Saturday, January 8, 2011

Acceleration

Nothing can move from any given speed to another speed instantly. I could tell the motors to jump from speed A to speed B instantly but the machine is going to resist. The result will be jerky motion, rough cutting and wear on the machine.
I've studied a number of G Code interpreters for the Arduino. The RepRap project has 2 or three, I can't figure it out. There's "Arduino G Code Interpretor", the "new RepRap firmware", and "FiveD on Arduino". The contraptor project recommends one of these or GRBL. They seem to be related in one way or another. The latest versions all seem to be well developed. None of them do any sophisticated "look ahead" which is understandable given the limited horsepower of the Arduino.


One or more of these interpreters support "linear interpolation" of speed. IOW, they will calculate the change in speed per unit of time to get from one speed to another along a straight line movement. I will be doing as much "heavy lifting" as I can in the host software, so I have the opportunity to precalculate speed changes and send this information "prebaked" in the G Code to the Arduino.


Once the path is built (a series of straight line movements), what I'd like to do is make a pass through the path setting the speed at each point to the "maximum" speed. This speed will likely be related to the change in angle between adjacent lines. A zero degree change will be full speed. Maybe by 70 degrees, the max speed will be zero. I could get more sophisticated down the road, but I think this is a good place to start.


My mill is small. In fact there probably isn’t a smaller one. Without any major chucks of metal on it, like my rotary table, it doesn’t have a whole lot of momentum. The steppers are 205oz so will probably get it up to speed quickly. But not instantly.


There is some “full speed” that I will run my machine at. I think this will be determined experimentally and will be based on how fast the steppers will be able to go (possibly under some average load) without losing a step. If we’re going from stop to full speed, there is some minimum distance that we’ll want this to happen over. I’m calling this the “full acceleration distance” or FAD. This will also be determined experimentally and will probably be based on my perception of “jerk”, deflection and vibration. I’ll be conservative since I’m more concerned about wear and tear than production speed.



The speed at the start of a line segment is SS, the speed at the end ES. Full speed is 1.0, SS and ES are from 0.0 to 1.0. For any given acceleration (where ES > SS) there is some minimum distance required to reach the end speed. This is “delta acceleration distance”, DAD:


DAD = (ES - SS)(FAD)


I’ve thought of 3 scenarios relating the change in speed to the length of the segment, L.
If DAD > L then we don’t have enough room to go from SS to ES, so we need to reduce ES.





The target end speed is the top of the dotted lines. The right dotted line is the distance it will really take to get to 0.75. The new, reduced end speed is the intersection of the left dotted line and the diagonal line. Since our start speed is not zero, we need to shift the whole thing up and down by 0.25:


Reduced ES = (L / DAD)(ES - SS) + SS


If we say FAD is 3 "units", then DAD is 1.5 since we've changed speed by 0.5 (0.75 - 0.25). Judging from the illustration L looks to be around 1.0. So to verify, we substitute these numbers:


0.58 = (1 / 1.5)(0.75 - 0.5) + 0.25


0.58 looks to be about right from the illustration.


In the second scenario, we have at least enough distance to go from SS to full speed and back down to ES. We need to address this scenario if


L >= (1 - SS)(FAD) + (1 - ES)(FAD)



What we want to do is split the segment into 3 parts and set the new points to full speed.


L1 = (1 - SS)(FAD)
L2 = (1 - ES)(FAD)


Now’s the tough one. We have more than enough room to get from SS to ES (but not enough to get to full speed) which means we can hit a speed higher than ES and come back down to ES. We know we have this scenario if


DAD < L and L < (1 - SS)(FAD) + (1- ES)(FAD)



What we need to do here is split the line in 2 and set the “mid speed” MS at the new point. If we were to accelerate from SS continuously until we move a distance of L, we would have reached an end speed we’ll call VES for virtual end speed (0.92):


VES = SS + (L / FAD)


Assuming our acceleration distance is equal to our deceleration distance, MS is half way between ES and VES:


MS = (VES + ES) / 2


The distance from MS to ES is:


L2 = (MS - ES)(FAD)


Now we can split the segment a distance of L2 from the end and set the speed to MS.


To verify, if we say L = 2, then VES = 0.25 + (2 / 3) = 0.92


MS = (0.92 + 0.75) / 2 = 0.835


L2 = (0.835 - 0.75)(3) = 0.25


I took measurements from the illustration and I come up with something closer to 0.45 for L2. The slope of the diagonal line is pretty close to 3 but not right on. This seems like a big discrepancy, but I can't seem to find the problem if there is one. I'm tired of working on this so I'm putting it out there. I'll come back to it later.


And the fourth of my three scenarios is DAD = L in which case we don’t have to do anything.


All of these scenarios are for ES > SS or an increase in speed. I figure I'll walk through the path forward and ignore decreases in speed. Then I'll walk backward with the same algorithm as going forward and it should correct the cases where we need to decelerate faster than our constant.

No comments:

Post a Comment