Saturday, May 19, 2012

How many times... re: motion-ramping

I guess there are just some things I have to admit are my white whale...

I can't count the number of times I've coded the same thing to come to the same conclusion. It seems simple at first... You have a motor which moves from one position to another... you have a top speed, and you want it to ramp from stop to the top speed, continue at that speed for a while, then ramp back down to stop at the end position.

I've solved this problem, already, with a convoluted solution: treat the ramping motion like a quarter of a sine-wave, and instead of setting the *speed*, give a simpler motion algorithm (without ramping) multiple intermediate endpoints along that sine-wave, telling it how long to take between each step (a constant time-value). If you're on a circle it makes more sense... the overall speed around the circle is constant; it takes the same amount of time to traverse from one angle on the circle to another... A circle, of course, has a maximum speed of 1 and a minimum of 0 along a single axis while rotating over 90 degrees. Then taking that back to a single-axis you're simply telling it to take a certain amount of time to traverse between different angles on the sine-wave.

But every time I set the project down for a year or two, I look at it and think "damn that's convoluted, why don't I just vary the velocity constantly?" And I recode it with a seemingly simple algorithm. Tonight's was: for the first third of the distance vary the speed linearly from 0 to max, continue at max for the second third, then vary the speed linearly down from max to 0.

Seems simple, really, it probably is, too, because that's how it's taught to implement "simple ramping." But there're several inherent problems I always run into. First: Distance, Time, (and the calculations!) are discrete, here... so it doesn't quite work like in physics. The math doesn't *quite* work out. It works great for ramping UP, but ramping DOWN is a pain, the math is off by a tiny fraction here or there, that error adds up, and suddenly I'm at velocity zero long before the endpoint.

It really seems my problem is I keep trying to approach this from the ideal physics/math standpoint; I keep thinking about *speed* as the main concern, when really time (and position) is what matters (and *works*). If I can fully wrap my head around why the sine-wave approach works, I could probably use the same logic to implement linear-ramping. Maybe instead of using points on a sine-wave, I could use points on a parabola... tell it exactly how long to take between each of those points. Because, without ramping, I can easily get from one point to the next in a specific amount of time. Either way, sinusoidal ramping is smoother than linear, so it doesn't *really* make sense to go back, except to simplify the code that's already written and works (but always has to be modified slightly each time I'm reusing it).

It's just friggin' annoying that I keep recoding this over and over to come to the same conclusions. This last time I didn't even realize I was coding the same thing until the very end... I came to the same faulty conclusion from a completely different direction... thought I had that ah-hah moment, only to realize it was exactly the same as before.

Sine waves, stick to 'em!

No comments:

Post a Comment