What is the actual role of internal motor PID?

Nooby question here. I know PID (proportional-integral-derivative) control is a math based algo that help you, have a tight control over motors. http://en.wikipedia.org/wiki/PID_controller

But am a little confused about in which situation a robot can be controlled through PID? Or in other words what these PID gain do on motors, does not the motors do that automatically? And do we need the PID gains in a situation when robot needs a lot more torque to regain its balance?
Any guide will be highly appreciated.

I think you must have misunderstood something.
What an electric motor can do is just to turn.
When you power-on a motor, it just turns, in one direction (at a velocity depending on the voltage).
But usually, what we want is not just turn forever but turn until a specific position is reached. So what we need is not just a motor but a servomotor.
To do that we have to add a sensor (angular position sensor) to the motor and some way to control the motor according to a the sensor and the given position we want to reach. That is where PID control is used. It allows to continuously apply the right voltage to the motor in order to reach a given position.

The way a PID controlled motor works is in fact very simple, you can find explanation here for exemple:

2 Likes

To complete, the PID parameters can be understood as “physical value” such as stiffness and damping.
For exemple, spring-mass systems are often simulated with a PD control, the Proportionnal parameter is for the stiffness and the Derivative parameter for the damping.

http://homepages.wmich.edu/~kamman/ME471PIDPositionControlofSMDRL.pdf

Therefore on the Robotis Dynamixel servomotor, these parameters are very useful to change the behavior of the robot. You can for exemple tune the reactivity, the rigidity, create shock absorption and so on…

On Poppy, I change them on the torso:

class StandPosition(InitRobot):

    def run(self):
        self.robot.compliant = False

        self.robot.power_up()

        # Change PID of Dynamixel MX motors
        for m in filter(lambda m: hasattr(m, 'pid'), self.robot.motors):
            m.pid = (4, 2, 0)

        for m in self.robot.torso:
            m.pid = (6, 2, 0)

This create an interesting spring-like reaction of the upper body.

1 Like

Thanks @Steve @Matthieu it clears a lot of danglings from my head.

One q…

So can you explain a bit how we can receive spring like effect or a rigidity effect in code … I mean is this by changing values from 4 → 6 ?
Or any example code

  1. for making torso rigid
  2. for making torso spring like.
    Sorry I got a little understanding issue how to make …

Regards
NicoX

You have the spring-mass behavior explanation here:

Changing the motor PID is not exactly like a spring but it has a similar reaction. Because Robotis does not give all the data and firmware of their motor, it is not possible to know how the motor will actually react so you need to do it by trial-error with the real robot. Here I tried several value and eventually switched from (4, 0, 0) to (6, 2, 0).

Well thanks @Matthieu for your detailed ans. One quick question, can we introduce PID control through either any hardware or software to non PID compliant servos like AX 12 or AX 18?
Any idea ?

Regards
NicoX

Yes you can but you need to change the motor firmware.

Is there any detail posted somewhere to do that ?

We never tried to do that so I do not have more information. I only know that some people did it.

Thanks a lot for this info, but do you have any pointer on that may be on web?
I am also searching … :slight_smile:

@Steve do you have more info ?

I know that there are some open-source firmwares for AX12, for exemple:

There is also an open-source firmware project from the Rhoban team for MX64.
The aim here is to experiment the torque control based on current sensing:

2 Likes

Thanks a lot guys you have guided me pretty well.
Awesome I will try searching what they have done … will revert :slight_smile:

Regards
NicoX

I have a question which (may be) could take place here ?
Pypot provide synchronized loops at the highest speed for reading both position, speed and torque_limit of servomotors. So, I presume that torque_limit (for MX28 control) can be used for improving the dynamical behaviour of the robot at a high rate, but I am unable to figure out how and why ?
What I mean is that torque control (goalTorque, which is a goal value, not just a limit) for a MX64 could be used, for instance for balancing gravity effect on a arm in order to make it have softer movements. But MX28, unfortunately don’t have this registry control. So, do you use torque_limit in place of goalTorque ? I would be very happy toget light on this point.

On the MX64 there is indeed a goal_torque register. We did not really play with it but @Steve says it works.

On MX28, you do not have such possibility. I tried to create some torque based controller using the “current_load”, the “torque_limit” or “goal_acceleration” but I never obtained satisfying behaviors (also I’m not a automation specialist…).

Also the “torque_limit” behavior is limited. There is no continuous range from 0% to 100% torque, especially there is a strong discontinuity between torque_limit = 0 and compliant = True.

The current @Steve’s team (Rhoban) is working on a new opensource and hopefully better firmware.

Thanks Matthieu for your in deep feedback. In my modest experience, MX28 register ‘current_load’ as a mean for sensing torque, exhibit important offset and hysteresis, thus providing inaccurate results. But this could probably be slightly improved using some code.
Regarding the torque control of the MX64, I have been very disapointed by it: torque cannot be set accurately since its dynamical range is encoded only on 8 bits with a significant remaining torque even while set @ minimum. And current sensing appeared not to accurately mirroring the torque the motor produce (probably due to the highest friction level for MX64).
Coming back to torque_limit implemented in Pypot (an amazing thing !) : what is the usage done with it ? Since it is implemented as a high rate loop, I presume it is usefull for controlling Poppy ?

You seem to have explored more deeply the question :smile:

There are multiple control loops in pypot, only position speed load are synchronized at 50Hz. Others registers are synchronized at a lower frequency.
The “torque_limit” is synchronized at 10 Hz, we used it in some experimental behaviors but most of the time we used it to protect Poppy against user abuses e.g. we reduce the torque_limit to avoid the motor overheating. Sometimes it permits saving a $250 motor :slight_smile:

Bertrand, 8 bits shouldn’t be that bad. If for example the maximum current that the motor can “use” is 8 A, with a sensor of 8 bits (I guess that’s what you mean by “dynamical range” ) you have a resolution roughly of 30 mA resolution. Not that bad!

Your position sensor has a resolution of 0.088 degrees and is considered -as it should- “highly accurate”.

Based on the configuration of the arm you can calculate the ‘static’ torques and add this value to the output of the controller. That way your controller will have “less work to do”. You can search for more details, about “feedforward path” or “feedfoward control”.

Matthieu & poppy_esaii:
Thanks for your reply: I now better figure out your servomotors read/write loop strategy. I understand that you sense motor load at approx 50 Hz and use this value (maybe after some average or any kind of filtering ?) to set PID values of MX28 motors at approx 10 Hz thus getting a faster response of each motors. However, since you get for each motor 2 values for control : sensed motor load and its static load computed from Poppy’s model, how do you mix them ?

poppy_esaii:> Bertrand, 8 bits shouldn’t be that bad. If for example the maximum

current that the motor can “use” is 8 A, with a sensor of 8 bits (I
guess that’s what you mean by “dynamical range” ) you have a resolution
roughly of 30 mA resolution. Not that bad!

I agree. But this 8 bits looks low compared to the 10 bits (~5mA) of current sensing. Maybe I’m wrong but I guess that it would theoretically be not enough to balance a loaded motor from 45° to 45.1° (an angular displacement that’s more than the motor encoder resolution).

Just some more words to tell how much I am impressed by your work and the results you got. It will probably soon be considered as a significant milestone in the story of androïds. What impressed me the more, is that you did it with relatively low-cost components. That’s the real art !