Legacy Forum: Preserving Nearly 20 Years of Community History - A Time Capsule of Discussions, Memories, and Shared Experiences.

Help with PWM servo slow moving function

Based on DMP's Vortex processor / SoC this board is a full computer capable of running a standard Windows and Linux installation on the backpack of your robot.
3 postsPage 1 of 1
3 postsPage 1 of 1

Help with PWM servo slow moving function

Post by Ernif » Thu Dec 09, 2010 4:57 pm

Post by Ernif
Thu Dec 09, 2010 4:57 pm

I've been trying to write a function that moves slowly a HITEC servo for some cam tracking business. Unfortunately, the best functions that I've been able to write is moving jerkily. My function consists of sending PWM pulses then to put a little sleep. Since servos are sometime fragiles, it's hard to do lots of test.

Here is my function:

Code: Select all
if (destination_position != current_position && rcservo_IsPWMCompleted(0))
      {
         int steps = (destination_position - current_position)/speed;
         rcservo_SendPWMPulses(0, 20000L, current_position, 10);
         usleep((1/speed)*1000);
         current_position += steps;
      }


The speed value I set is from 0 to 1000. If I use the 20000L value I feel like the servo is moving like Robocop attending to a pistol duel contest: it's way too fast. Changing it though has made some pretty weird results.

Anyone know a way to make it move slow and unjerky (smooth movement)?
I've been trying to write a function that moves slowly a HITEC servo for some cam tracking business. Unfortunately, the best functions that I've been able to write is moving jerkily. My function consists of sending PWM pulses then to put a little sleep. Since servos are sometime fragiles, it's hard to do lots of test.

Here is my function:

Code: Select all
if (destination_position != current_position && rcservo_IsPWMCompleted(0))
      {
         int steps = (destination_position - current_position)/speed;
         rcservo_SendPWMPulses(0, 20000L, current_position, 10);
         usleep((1/speed)*1000);
         current_position += steps;
      }


The speed value I set is from 0 to 1000. If I use the 20000L value I feel like the servo is moving like Robocop attending to a pistol duel contest: it's way too fast. Changing it though has made some pretty weird results.

Anyone know a way to make it move slow and unjerky (smooth movement)?
Ernif
Robot Builder
Robot Builder
Posts: 7
Joined: Tue Oct 26, 2010 5:19 am

Post by PaulL » Sat Dec 11, 2010 3:29 pm

Post by PaulL
Sat Dec 11, 2010 3:29 pm

To get dynamic movement (not point-to-point as is done in the frame capture of the demo, but programatically controlled), you need to update the servo position gradually (and frequently to get smoothness) over time. There are a number of posts in my "Roboard Experience" thread regarding servo movement. My efforts are in VB.Net, but the methods are the same.

When you tell a typical servo to move to a position, it knows nothing of speed, and just moves immediately to the position, as you have witnessed. So, you need to give it MANY positions to transition smoothly from one position to another.

My method:

I use PWM in "continuous" mode on the servos, and set the position using a Windows Multimedia Timer event (4mS interval seems to work fine), but I use RDTSC to calculate actual time elapsed and set the position accordingly. Distance = Speed / Time, so there's that. :)

You need:

* Start Position
* End Position
* Duration

From there, you just interpolate the position of the move based on time elapsed since start of move:

Position = (Fraction of Move * (EndPosition - StartPosition)) + StartPosition

That's the basic method in a nutshell.

You could even redo my accel / decel code from the "Roboard Experience" thread in C++, it will work the same way.

Paul
To get dynamic movement (not point-to-point as is done in the frame capture of the demo, but programatically controlled), you need to update the servo position gradually (and frequently to get smoothness) over time. There are a number of posts in my "Roboard Experience" thread regarding servo movement. My efforts are in VB.Net, but the methods are the same.

When you tell a typical servo to move to a position, it knows nothing of speed, and just moves immediately to the position, as you have witnessed. So, you need to give it MANY positions to transition smoothly from one position to another.

My method:

I use PWM in "continuous" mode on the servos, and set the position using a Windows Multimedia Timer event (4mS interval seems to work fine), but I use RDTSC to calculate actual time elapsed and set the position accordingly. Distance = Speed / Time, so there's that. :)

You need:

* Start Position
* End Position
* Duration

From there, you just interpolate the position of the move based on time elapsed since start of move:

Position = (Fraction of Move * (EndPosition - StartPosition)) + StartPosition

That's the basic method in a nutshell.

You could even redo my accel / decel code from the "Roboard Experience" thread in C++, it will work the same way.

Paul
PaulL
Savvy Roboteer
Savvy Roboteer
Posts: 423
Joined: Sat Sep 15, 2007 12:52 am

Post by Ernif » Tue Dec 14, 2010 5:22 pm

Post by Ernif
Tue Dec 14, 2010 5:22 pm

Thanks a lot for the reply, it sure helped me a lot. I'm currently working on a servo class. I'll post the result/code when it's done.
Thanks a lot for the reply, it sure helped me a lot. I'm currently working on a servo class. I'll post the result/code when it's done.
Ernif
Robot Builder
Robot Builder
Posts: 7
Joined: Tue Oct 26, 2010 5:19 am


3 postsPage 1 of 1
3 postsPage 1 of 1