Sunday, March 14, 2010
Hydra Joins the Acceleration Party... with multiple heads
- If you have a constant acceleration with a non-zero initial velocity, the time interval for stepping cannot be directly determined. A quadratic equation needed to be used to solve for the time interval. This is due to the fact that the motor speed is dependent on the stepping interval (delay between steps), and the distance the machine travels is also dependent on this velocity as well as the constant specified acceleration.
- (Solved) For some reason, every time I derive the kinematic equation to relate distance, velocity, and acceleration together I get a different result than that which is in the physics textbooks I have used in school. If V = delta x / delta t, and a = (V-Vo)/delta t, if you combine these you get a*deltat + Vo = V = deltax/deltat. Multiplying both sides by deltat, you get a*(deltat^2) + Vo*deltat - deltax = 0. The equation in my textbooks is1/2*a*(deltat^2) + Vo*deltat - deltax = 0. I was forgetting that the V term is actually Vavg which would equal (V-Vo)/2 which answers the factor of 2 difference. Thanks for pointing this out guys!
- Solving quadratic equations while moving is not a good idea. It was too slow and it was actually limiting my maximum speed (the delay from solving the equation was greater than the interval I was using for stepping). The whole idea of doing this is to allow for faster and smoother stepping so a change was needed. I decided the best way was to compute the acceleration scalers (% of desired speed) for each step and to store those in an array. See the next point.
- Storing large arrays (200+ items) of floating point numbers eats up SRAM real fast. A 200 item float array requires 200*4 Bytes = 800 Bytes! That is almost all of the available memory on the ATmega168! To fix this I scaled the acceleration scalers up to integer values. The scalers only range from 0.0 to 1.0 so this was not hard to do and it cut the memory usage in half (integers only require 2 Bytes instead of 4 Bytes for floating point numbers).
- I originally intended to have separate acceleration and deceleration calculations, but it proved to be must faster to just calculate the acceleration values and then duplicate those in reverse for deceleration. I also has a problem when solving the quadratic equation for negative acceleration. The radical is negative if Vo^2 < -2*a*deltax which can happen for deceleration. See the 2 figures below.
- So again, it was must easier to just use the acceleration calculations where acceleration is positive and the value inside the square root can never be negative. To help with this problem, I also added a startup speed variable so the motors can start from a specified velocity. For example, if they have no problem jumping to 0 to 30 inch/min, start them at 30 and then ramp up to 80. While this change, as well as only calculating the positive acceleration values got around this problem, I am still intrigued why this was happening.
v = dx/dt
a = dv/dt
-> multiply both sides by dt:
a*dt = dv
v = vo + a*t = dx/dt
-> multiply both sides by dt:
vo + a*t dt = dx
x = xo + vo*t + 1/2 a*t^2
Perhaps using this formula will also solve your problem of imaginary roots?
The error is quite subtle, but the error comes in the last step: When you have
a*delta t + vo = delta x / delta t,
you can't multiply both sides by delta t. It's because if you plot the a*delta t term, it's growing linearly in time (a triangle), and the velocity growth in time period delta t is the area underneath that triangle, which is 1/2 base times height. If you just multiply by delta t, then you're assuming it's a square, which gives you base*height but is off by the factor of one half :)
As an example, if you want to find the distance traveled by an apple falling for three seconds from rest, if you simply say delta x = 9.8*(3^2), you'll get twice the experimentally measured distance. Because you have to account for the fact that the apple goes more slowly at the start!
Anyway, good job on the software, I'm very excited about anything that supports multiple toolheads!
I use the same table for acceleration and deceleration as it is just a mirror image.
And nophead, thanks for the link! I'll definitely give it a read
Not true: a*deltat + Vo = V = deltax/deltat
True: a*deltat + V_o = V_final
True: V_average = deltax/deltat
Links to this post: