Software > Software

Calculations for acceleration and decceleration

(1/1)

clementfletcher:
Hello:

I am rather new around here however I was hoping that the members may be able to help me out with a pickle of a problem I've come across.

What I would Like to do:

I would like to be able to set an angle in software for a hobby servo to go to. Rather than have the servo go to that position immediately I would like it's path governed using an acceleration (degrees per sec sec) and a maximum speed (degrees per sec) parameter in software.

What I'm using

I'm using regular hobby servos (180 degrees) and an arduino as a microcontroller

What I've tried

Accelerating is not difficult. I have a loop in software with a constant repeat time (10milliseconds) I have a speed parameter which each iteration I increase by the acceleration factor until the maximum speed is reached. and this speed factor is incremented to the absolute position each iteration.

Decelerating is also not difficult doing the same but subtract the acceleration factor each iteration until the speed is zero.

The problem I am having is in deciding at what point to begin decelerating. I have tried calculating the distance required to stop (using kinematics d = vt + (1/2) a t^2 ) however I'm finding my servo always overshoots and sometimes settles however sometimes awful feedback loops and a shacking servo result.

I'm currently using Excel to try and model the problem with some success (the graphs generate the same results as my microcontroller code) but am not making much progress.

Would love to hear of others experiences with problems like this or advice of things to try.

It seems like a problem which should be easy to solve I hope it's just something small and silly alluding me. If you would like any further details please just ask.

Regards:
Clement

klaxxon:
If I understand your question correctly (smooth accelleration/decelleration curve when moving to a given angle), my solution was to use a sine wave for the speed value.

Pseudocode:

delta_angle = (destination_angle - starting_angle)

while (progress < (180 degrees))
{
progress = ((current_angle - starting_angle) / delta_angle) * (180 degrees)
setServoSpeed (sin (progress) * max_speed)
}

Explanation:

A sine wave (from 0 to 180 degrees) goes very smoothly from 0 to 1 and back to 0, so use that as a multiplier for the maximum desired speed. Continually poll the servo for it's position while moving, and keep adjusting the speed according to the sine wave.

If you're working on a microcontroller, storing a sine lookup-table in RAM or EEPROM is a good workaround for the lack of floating point capabilities. There are many other optimizations that can also be performed.

Your milage may vary, but when I tried this it worked exactly as expected (regarding the speed), however the servo itself appeared to stutter a little bit, probably because I wasn't updating with new speed values often enough.

Hope this helps, or at least gives you some more ideas on how to tackle the problem!
- Adam

Admin:
sounds like a PID problem . . .
http://www.societyofrobots.com/programming_PID.shtml

That tutorial needs to be rewritten, and what I said about the integral term isn't entirely correct as of this posting. Just haven't had the time to fix it . . .

It should however get you started.

You might also be interested in fuzzy logic control:
http://www.societyofrobots.com/programming_fuzzy_logic.shtml

ed1380:
IIRC if a servo is centered and you tell it to move alot it will move fast. if you tell it to move a little it'll move slowly.
you could use that to your advantage. sry i suck at programming

Navigation

[0] Message Index

Go to full version