Best way to implement servo speed control

Hi
Im currently working on the basic code for my Panda II based bot.
Now i have made a simple class for controling my servos, but i really want some way of controlling the speed of the servo…

But not sure how to handle it in a good way, any help appriciated.

This is my current code:


class Servo
{
    private readonly ServoModel _servo;
    private readonly I2CPwmDriver _driver;

    public Servo(ServoModel servo, I2CPwmDriver driver, int initPosition = 50)
    {
        _servo = servo;
        _driver = driver;
        Move(initPosition);
    }

    public void Move(int percentage)
    {
        _driver.SetPwm(_servo.ServoAddr, 0, CalcPulse(percentage));
    }

    private ushort CalcPulse(int percentage)
    {
        //Making sure percentage is inside specificed bounderies
        if (percentage > 100)
        {
            percentage = 100;
        }
        if (percentage < 0)
        {
            percentage = 0;
        }

        //Get pulse from percentage
        var pulse = (ushort)MathHelper.CalculateRelativeOutput(percentage, 100, 0, _servo.PulseMax, _servo.PulseMin);

        //Making sure pulse is inside specificed bounderies
        if (pulse > _servo.PulseMax)
        {
            pulse = _servo.PulseMax;
        }
        if (pulse < _servo.PulseMin)
        {
            pulse = _servo.PulseMin;
        }
        return pulse;
    }
}

Servos are “imprecise” from a speed perspective. The way to adjust how fast it moves from point A to point B is to do maths - figure out how to adjust the PWM percentage from what it currently is at A, to what it needs to be to be at B, and how long you want between that change (which is essentially the “speed”). Then you can work out a set of intermediate steps and timing points to make those changes and execute that. The maximum “speed” you can achieve is when you let the servo change its position through simply setting the PWM adjustment from A to B.

@ Bekker - You will most likely have to implement a PID algorithm.

There are generally 2 different ways you can command a servo to move, based on your application.

1.) Velocity Control - These are for applications where you want the servo to achieve a certain rotational velocity and hold it at that velocity, until you request a different velocity or command a stop. In this mode, the Integral term is the most important, and the Proportional and Derivative terms can generally be set to 0 or to small values.

2.) Position Control - This is where you want the servo to rotate until you achieve a chosen encoder count. The Proportional term is the most important in this mode, and the Integral and Derivative terms can generally be set to 0 or small values.

When reading tutorials on PIDs, don’t be intimidated by the theoretical aspects of it. Some documents talk about stability, optimal tuning, settling time, overshoot, different PID forms, etc. In real life, the implementation of a PID in a program is generally quite easy and can be as simple as this:

err = desired - measured
proportional = P * err
integral = integral + I * err
derivative = D * (err - prevErr)
output = proportional + integral + derivative

PIDs require trial and error, however, when finding good values for the P, I, and D gains, so you have to be patient.

1 Like

@ Iggmoe - servos typically do not have positional feedback which makes a pid loop difficult?

@ Mike - Feedback is what differentiates a servo from a plain vanilla motor by definition. Motor + feedback = “servo”. The feedback would typically involve an encoder, or less commonly hall sensors, resolvers, etc. Since @ Bekker mentioned a servo in the context of a mobile robot application, some form of feedback via the aforementioned sensors should be present, and an encoder is most likely.

Well im using std servos, so really there is no feedback by default.
So i would have to implement that somehow? or should i consider changing all my servos for some with feedback?

@ Bekker - Brett explained how to achieve speed control of standard servos. does his solution not meet your needs?

Never used servos, but if I understand that what brett wrote correctly:
The PWM duty cycle tells the motor at what angle it needs to be at.
Setting a new PWM moves the motor as fast as possible to new position.

To move slower you need to change PWM signal slowly.
But I assume to avoid a rough movement you need to make as many intermediate steps as possible.

In fact a stepper motor (as I used them so far) could achieve this much easier.