recapturing position and velocity with moteus

Recently I covered a new feature for the moteus brushless controller that improved robustness for velocity control when external torques exceed the maximum allowable control torque. In this post, I’ll cover a feature that can be used for a similar situation in position control, “recapturing position and velocity”.

In some applications, while in position mode, it can make sense to limit the maximum torque during specific periods so that external torques are able to overpower the controller. The most obvious case would be if the maximum torque is set to 0, or the kp and kd scale are set to 0 temporarily. A problem then arises when resuming control, as the “control position” will be wherever it last was, despite the fact that the actual motor have have been dragged by the external torque some distance away. When the torque limit is released, a large transient can develop as the controller tries to instantaneously get back to the old control position.

BIG price improvement for moteus-r4

I’m excited to announce a big price drop for the moteus-r4.11 controller for both single units and in volume!

Quantity Old New
1-10 $104 $79
10-99 $99 $75
100-499 $94 $71

We’ve been scaling up production, which enables these reductions of about 25% across the board. moteus-r4 is now by far the most cost effective motor driver with integrated encoder in its class. Here’s a quick comparison with similar products:

ODRIVE S1 Tinymover R5.2 moteus-r4.11
Voltage 12-50.5V 12-38V 10-44V
Continuous phase current 40A Not specified 22A
Peak current 80A 40A 100A
Dimensions 66mm x 50mm 40mm x 36mm 53mm x 46mm
Open source Proprietary FW and HW GPL FW, Proprietary HW Apache 2.0 FW and HW
Price $149 $108 $79

I personally am looking forward to all the new projects that these lower prices enable! Check it out below or join the mjbots Discord to chat and get some ideas for how you can use a moteus-r4.

max_velocity_slip with moteus

The moteus brushless motor controller supports several concepts of operation from within its primary “position” mode, including a velocity mode. As documented in the reference, you can run in that scenario using commands equivalent to the diagnostic mode command:

d pos nan V nan

Where V is the desired velocity. However, as with most control operations, there are a number of edge cases that can be useful to handle. When operating purely in velocity mode, the normal PID constants can be interpreted slightly differently:

Default bandwidths for moteus

moteus has long had both automatically tuned current control bandwidth and a built-in low-pass filter for encoder readings. During calibration, these are usually set with moteus_tool’s --cal-bw-hz option, which specifies the current loop (interchangeably called the torque loop) bandwidth. TLDR is that these heuristics have changed as of pypi 0.3.64, hopefully with only improved behavior. Read on if you want to understand more or if you need to resolve problems with something that changed for the worse.

New Project: Juggling Robot

I’ve been looking for a new motor control project to tackle that is both interesting, and a bit more unique than another Ascento clone. Looking around, I was surprised at the current paucity of robots capable of more advanced juggling feats. There are quite a few that can manage 3 balls, and nearly none I’ve found that can manage more, with the exception of Nathan Peterson’s inclined ball roller. I figure that I have access to lots of factory second moteus controllers, which are capable of quite demanding control applications, so I should be able to put something together.

moteus_tool --restore-config

For the moteus brushless controller, the moteus_tool utility has long had a --dump-config command line action which will cause the entire contents of the configuration to be written to standard output.

--dump-config format

This configuration looks like this:

servo.pid_position.kp 4
servo.pid_position.kd 0.1

moteus_tool has also had a --write-config option, which is something of a misnomer, as it actually just sends any commands one at a time from a file to the controller. Notably, it requires that the file to contain actual valid diagnostic mode commands.

New nice to have accessories at mjbots.com

This is a quick post to highlight two new nice to haves at mjbots.com that have been long requested.

First, is a pre-built JST PH3 CAN-FD cable, initially available in 30cm lengths. It can be used to daisy chain between controllers, or connect up a pi3hat. Use it as is, or cut it and strip the wires to easily build a JST PH3 to pigtail cable.

Second, is a pre-built CAN-FD termination resistor that can be directly plugged into a JST PH3 receptacle on the moteus controller. This uses split termination to achieve 5Mbps bandwidth over longer daisy chains than can be achieved with a simple one-resistor terminator.

moteus with velocity=NaN

When commanding a moteus controller, many of the registers defined in the reference documentation give explicit semantics when the value is passed as either a floating point NaN value or the “maximally negative integer” for integer encodings. Those that do not specify a meaning for NaN are “undefined” and anything can happen. For the most part, this isn’t a problem, but in one specific case users were repeatedly caught off guard.

Three common registers often set in position mode, (also accessible by the unlabeled first three arguments to “d pos”), are 0x020 “target position”, 0x021 “target velocity”, and 0x025 “maximum torque”. Target position has a defined meaning when set to NaN: the controller assumes that the target position is the current target position, or the sampled position if the controller is not yet in position mode. Maximum torque also has a defined meaning when set to NaN: it then uses the maximum torque as defined by the maximum phase current limit. However, target velocity had no such definition, and in practice when used, resulted in the controller becoming mostly non-functional.

CUI AMT21 series RS485 encoder support for moteus

As of release 2023-09-26, moteus controllers can now use CUI AMT21 series encoders for any encoder source. CUI’s AMT21 series encoders are rugged, with resolution up to 14 bits, and since they use RS485 for communication can be located a significant distance from the motor driver if necessary. Setting one up is easy with the moteus-n1, which is what I’ll cover here.

Hardware

The moteus N1 has JST GH-6 connector labeled “RS422” with all the pins necessary to power and communicate with an AMT21. Since the AMT21 is RS485, not RS422, it is required to tie the A and Y pins together and the B and Z pins together. An easy option is to do so in the harness, either by crimping multiple wires into the Molex terminal for the AMT21, or by splicing wires. The desired schematic looks like:

Python trajectory waiting

In simple motion control applications with moteus, a common request for the python library is “run a position command until it is complete”. moteus does track when the target position reaches the desired one and reports it in the “trajectory complete flag” (register 0x00b), however until now the application needed to poll that flag on a regular basis to see when the motion is done.

As of pypi moteus 0.3.59, there is now a new method on Controller which can be used to accomplish this, along with an example script. Basic usage is about as simple as one would expect: