Sometimes you find bugs, and sometimes the bugs find you! While getting ready to release some updated qdd100 beta servos, I was investigating speed control in the moteus firmware and discovered an unwelcome surprise!
To improve dynamic response under high accelerations, moteus uses a voltage feedforward term as part of its control loop. When trying to command a specific current, it normally applies a PI controller to determine the resulting D and Q phase voltages to apply. The feedforward component of this looks at the phase resistance and the current rotor velocity, and determines a zeroth order estimate of what voltage would be required to achieve that current under a no-load condition, only using the PI controller to determine the difference.
This technique has been in use since my earliest direct drive leg jumping experiments. However, at some point before I added support for gearing reduction in the controller, there was a lot of confusion in the code base around the sign of the torques vs. the sign of the encoder. When that was sorted out, I missed the fact that the resolution ended up leaving the velocity component of the feedforward with a *negative* value. This meant that instead of helping the PI controller, it made the PI controller have to work twice as hard!
The easy, and not-so-easy fix
Fixing this for new controllers involved changing just a single character change from ‘-‘ to ‘+’. However, there is a configuration value which applies an overall scaling to this feedforward term, and has been 1.0 for all released moteus controllers. With the correct sign, a 1.0 scaling factor can result in unstable performance at high velocities.
Knowing this probably won’t be the only complicated upgrade procedure for the moteus controller, I decided to invest in a little infrastructure to make it easier in the future. This is built on two components:
- The “firmware version” was always stored in the firmware image and reportable over CAN. Until now, it has always been 0x00000100. I’ve now set this up so that the version is stored as a top level symbol in the firmware .elf file that automated tools can inspect.
- moteus_tool now checks the existing firmware version, and the new firmware version. When crossing given firmware versions, it can apply programmatic rules to update the configuration to maintain as close as possible semantic values. To make that robust, it refuses to flash firmware versions newer than it is aware of.
Thus, the new release, 2021-01-14 which has two improvements / bug fixes:
- The aforementioned feedforward sign error.
- Temperature values are now minimally filtered before being used for derating or faults.
If you want to upgrade, be sure to use a moteus_tool version 0.3.7 or newer from pypi. Or, if not, make sure that
servo.feedforward_scale is set to no more than 0.5 when you’re done!