Adding acceleration control to dynamixel MX series motors

Hi everybody,

Maybe I’m wrong but it looks like dynamixel MX ‘acceleration’ control is not currently implemented in pypot\dynamixel (I can’t see it in my currently installed library nor in the last release on github).
I mean the ability to set 0X49 (# decimal 73) register adress of MX series to 0 or 1 (this should have to be also linked to a non zero value for goal speed (= 0x20 register). I think that using acceleration control allows softer motions, better synchronizations by reducing inertia effects and probably reduce power supply consumption and gear wearing.

I tried to add this property to my pypot package, but I’m not sure to have a good understanding of the whole mechanism of controlling a MX28 with pypot. Could Matthieu or Pierre provide us a simple way to add this property to those wanting it ?

It was actually implemented in pypot in a separate branch: https://github.com/poppy-project/pypot/tree/goal-acceleration

Yet, we never merged it with master because the goal_acceleration behaviour of the MX motors seems really odd. When set a constant acceleration, the motor position was oscillating, changing direction, etc…

Maybe we did something wrong. Maybe there was something wrong within the firmware.

Let me know if you manage to have something working correctly! That would indeed be a really nice improvement of how we control poppy robots!

Thanks Pierre for your very quick reply.

Yes, I got (easily) perfect results with ‘acceleration’ on MX28 (and also MX64), but with a ‘non-pypot’ way of control (USB2Dynamixel SDK).

The only limitation is a purely triangular velocity profile (trapezoidal not possible without adding some tricky computations).

I don’t understand deeply the way dynamixel registers are controled in pypot. Maybe the issues you encountered with acceleration come from that speed have to be constant and non-zero for each ordered motion and a low values should be choosen (1 : very progressive acceleration-decceleration, to 20: near to no acceleration. 125 do not any visible acceleration. But it also depends on speed). Maybe also, the synchronization loop (which include speed control) was interfering with acceleration control, or ‘motion time’ was responsible ?

I tried in the past to control acceleration via speed register (with a loop changing speed with the time), but due to a lack of contant transmission time via USB port (and FTDI chip) the results were verybad so, I think that it is much better and reliable to ask the servomotor controller to do this job at a low level, and really it works finely.

Another solution would be to compute an accelerated-deccelerated trajectory via time/position control (at maximum speed): it works properly but it is much more difficult to implement, subject to issues since it is a high level control and gears are experimenting more wearing since they often have to go back and forth in order to follow position orders (they can actually have a more advanced position than the one schedulled: so they came back then forth) . you can listen to that when servo is moving : more noise occurs.

A third solution which would also allows a fine control of speed (and thus acceleration) would be to use a dedicated controller. I guess a single Arduino should work. But it would require time and trials before expecting a result.

So, the best is to implement acceleration control and look were the things struggle.

Hi @Bertrand ,

What exactly are you trying to do? It is still not clear to me :confused: .

Well, in any case, the only thing you need to do, to ‘control’ acceleration is to measure it (feedback). I have no idea how the MX series of Dynamixel work, but if you trust the velocity feedback that provide and hopefully it is not noisy, then the simplest solution is to just derive the velocity and you got the acceleration. It will be most likely a noisy result but for sure something to begin with.

In fact, you can generate a slow velocity profile (slow because the reference comes from pypot/DynamixelSDK side) send to the motor only the goal_position and goal_velocity as fast as possible and then measure (read Dynamixel register?) or calculate by your self the acceleration to see if the result is as expected.

Hi Esaii,

I am working on a ‘cyber scrub nurse’: a system trying to help a surgeon while operating on via minimally invasive approaches; It is a kind of two additional hands with vision capabilities.

Regarding acceleration, I agree with you on the theory side: speed and acceleration are just time derivatives of position. The hard thing is that motor is controlled from software via an USB port and a USP to serial TTLconverter : this induce not only time lag but also a non-regular exchange between the servomotor and the host computer. Much more you do not have a reliable basetime for deriving time measurements.

If you only perform slow motions, these time issues are not noticeable. But if you want more than a slow motion (and MX serie can do it), you will notice irregular motion, especially if you need to synchronize many motors to get a rectilinear motion from a combination of revolute motions. This increase again if the load of each motor is very different, due to mass inertia effects.

The acceleration register integrated in MX series works at a low level within a controller which looping time is presumed very constant, based on a quartz basetime. So, the measurements ‘locally’ performed on a servomotor are very consistant regarding time, because there is no time buffering as it is done via an USB port (USB port v2 can works at megahertz rate, but not continuously because data buffering occurs).

This is why I think that MX Dynamixel can only be accurately controlled in position while operated via PC host-USB port. Any time related control (I mean speed, acceleration) are only very approximative.

It is why Robotis engineers have been well advised when implementing acceleration control from the servo controller embedded on each motor. Not only acceleration allows for a soft-sweet-delightfull motions (allowing much load), but it helps motors synchronization by minimizing the effect of inertia (the slowest the acceleration, the higher the load you can move as stated by Newton first law).

Of course, these consideration are meaningless while considering only working with 1 motor at slow motion…

Ok ok. Let’s talk locally. And by locally I mean inside the Dynamixel motor. If the problem is that the on-board control of acceleration is not good for you… well … you can’t do much about it. Unless you are willing to make your own firmware. (In fact that’s the second reason I decided to make my own motors -the first one is the price of course-. I put an arduino inside the motor and I can reprogram each one of them according to my needs!). If that is not the problem, then supposing that you have goal_acceleration register and feedback_acceleration register I don’t see any problem then (apart of the pypot implementation).

The suggested derivative was of course only for comparing with the Dynamixel acceleration feedback. And with Odroid/Raspberry one on one communication with a motor, you would get “more or less” fixed timings. At least enough to have representative results (for sure not accurate).

Theory question cause I’m curious now :smile: . Cyber scrub nurse! Accuracy is important, right? (in that applications ‘overshoot’ is not allowed!). Why you prefer acceleration control instead of torque control? Actually, the only reason I can think of using acceleration is for the dynamics algorithms but then again, never alone. Always as part of control schemes that include outer loops (position, velocity or torque).

@ Esaii:

I am very intrested by your project. Do you have an already working system ? I considered this option monthes ago, but modeling a motor and coding a good control firmware appeared a too complex task for me. Are you working (or do you plane to work) on separate elements combined (motor + encoder + gear box + controller) or do you modify Dynamixel firmware ?

Regarding the Cyber nurse: yes reliability is a great concern and overshooting not specially appreciated at operating room… It is not operated in torque mode because it has to lift various payloads which would require to know their exact mass and geometry in order to exactly counterbalance the gravity effect.

@ Pierre:
I think implementing acceleration within pypot should not give issues… Maybe the problem you encountered was due to that you acceded acceleration register while a synchro loop was running ? If yes, stopping loop, adressing register and restarting loop should work ? (or the problem were elswhere).

The last time I tried this was really a long time ago (3 years according to git…) so I’m really not sure what I did at the time.

As you can see in this branch https://github.com/poppy-project/pypot/compare/goal-acceleration I just add it the goal_acceleration register.

To make sure you don’t have any “concurrence” issue with speed, the best way is to only use pypot lower level.

For instance, you could try something like this:


from pypot.dynamixel import DxlIO


serial_port = '/dev/ttyUSB0'
id = 42

io = DxlIO(serial_port)

acc = ...
io.set_goal_acceleration({id: acc})

Sorry I don’t have any MX motors around me so I can’t really test.

Thanks Pierre.

But in < dynamixel\io\io.py > I don’t have acceleration register control.
I presume I have to add this in io.py :

__add_control('acceleration', address=0x49,length=1,
              models=('MX28', 'MX64', 'MX106'))

Is it correct ? Do I have to add something else here or elsewhere ?
Could such a procedure works while synchro loop is running ( I am afraid that serial port could not be adressed twice by 2 differents process ) ?

I did not integrate it into the master branch yet but it’s available in this branch: https://github.com/poppy-project/pypot/compare/goal-acceleration

As you can see, it’s basically only the line you posted + some conversions.

This can be mixed with synchro loop but at the moment sync loops continuously sets the position and speed for all motors. I’m not sure to have understood you correctly but it seems to me that you were saying that setting the speed and the acceleration at the same time won’t work.
So at the moment I would advice you to first try with low-level (the code I put above) and if this works well we will have to add some mechanism to switch from sync loop for control in position to sync loop for control in acceleration.