moteus r4.5

Meet the newest revision of the moteus controller!

Yes, it does look mostly the same as the r4.3 that has been getting a lot of use lately. This revision exists mostly to improve manufacturability, but I snuck in a minor design improvement while at it. Now, the maximum voltage input is rated up to 44V from the 34V of the r4.3! (Note though, that the pi3hat and power_dist still are limited to 34V). Otherwise the new controller is fully electrically, mechanically, and software compatible with the r4.3.

It is now the default in the mjbots store, only $5 more than the old version at $84.

And, by popular demand, it still has a devkit!

Another quad A1 speed record – 2.5 m/s

In two previous posts (part 1, part 2) I discussed some changes I made to the gait sequencing on the quad A1. Things are working relatively well now, sufficient that I was able to take this compilation video in one sitting without any gait or mechanical failures! I actually took a lot of the outdoor shots from this video in the same session, so things are definitely getting more robust.

Recalibrating the Pocket NC’s X/Y home position

This summer I had to send my Pocket NC in for some service, when it came back, I immediately noticed that the X axis homing was very far off, something like 0.01 inches, as I was boring a hole in one side of a part, spinning it around the B axis, then boring a countersink in the other side. The two were very clearly not concentric. I suspect the homing mechanism shifted in transport or something, because the error was very consistent.

Pocket NC’s support was great as usual and I quickly received a screencast showing the location of the homing setting:

Step 1: Conf
Step 2: Server
Step 3: Launch in New Tab
Step 4: Configure
Step 5: Pick Axis
Step 6: Change value, select Save, then Sytem
Step 7: Restart LinuxCNC and Rockhopper

To calibrate the X axis, I just used the hole that was bored all the way through, and manually used the MDI to spin the B axes around and jog the end mill through the center of the hole. Then I used my calipers to measure the offset between the widest part of the mill and each side of the hole. Two iterations of that had the X error back to under 0.001″.

Fast forward a few months and I am running a part where the Y axis zero position matters. Sure enough, it is off too. Not as much, maybe only 0.004″ or so, but enough to make the part not work out. I tried a different technique this time, engraving an X axis line with a chamfer mill in two parts. One part with the B axis at 0, and the other half with it at 180. Any Y offset will manifest as a “jog” in the line.

Several iterations of testing
Checking it out under the microscope

I’m not sure if this was any more or less accurate than the boring method, but it was faster and seems to have also gotten me back down to under 0.001 inch of error in the Y axis.

Walking in semi-rugged terrain

While testing the improved gait sequencing for the quad A1 I got some footage of it traversing a few different types of outdoor semi-rugged terrain.

Tree roots

The first clip shows it walking over some tree roots. In this particular instance, it just uses a high stepping gait, which allows the feet to get on top of the root. The gait sequencing doesn’t handle walking over the taller part of the root very well yet… the robot can get “high centered” on two legs, with the other two flailing in the air.


In the second clip the robot runs across some loose gravel and leaves. Here each foot fall skids around a fair amount and kicks up loose debris, but otherwise wasn’t too challenging.

Raised pavers

For the third clip, the quad A1 walks through some grass and over some pavers, which are around 1-3″ raised above the baseline grass level. Here raised steps allow the robot to move at nearly the same speed over the pavers as it can move over the grassy terrain.

Loose bricks

In the final clip, it walks over some loose bricks. With each footfall, the gait sequencing is looking for when contact is made with the ground. That allows the robot to stop pushing once contact is made. The current formulation does attempt to get the legs back to their “average” Z position at the end of each cycle, which is sufficient for this type of terrain, although a longer-term outlook would allow it to tackle even tougher terrain.

New compilation commands for moteus

To stay on top of bazel development, and to prepare for some future improvements, I’ve gone ahead and upgraded the moteus firmware build system, rules_mbed to use the new bazel “platforms” toolchain resolution mechanism.

Previously, rules_mbed used the “crosstool_top” bazel mechanism for toolchain configuration. This allowed a single package to contribute a set of C++ toolchains which would be selected based on CPU and compiler. One of the downsides from the rules_mbed perspective, is that it made it difficult to make a build that included both mbed targets and host targets (or anything else non-mbed). rules_mbed worked around this by including a functioning clang host toolchain within it.

With the new toolchain resolution support, at the command line you specify to bazel what “platform” you want to be the final target. The updated rules_mbed specifies a “platform” for each of the STM32 processors that are supported. So for instance you could use:

bazel build --platforms=@rules_mbed//:stm32g4 //:target

It then uses that platform to find a toolchain with a compatible operating system and CPU, which for rules_mbed is the arm-gcc compiler for the correct chip.

Because of this, the command lines necessary to compile the moteus firmware and host side tools have changed. Rather than expose the raw bazel options, it now just uses a bazel config to abstract away whatever mechanisms are required. So, the two necessary new command lines are:

tools/bazel test --config=target //:target  # build firmware
tools/bazel test --config=host //:host # build host tools

Soon, we’ll use this capability to add some useful new features to the moteus tools, such as support for non-linux operating systems.

New leg cable management

Now that the quad A1 has been running faster, it has started “running” through its ad-hoc cable management too. After replacing a harness for the nth time, I decided to actually design something rather than just keep re-building over and over again.

My current best effort uses semi-flexible nylon split conduit, captured in 3d printed forms at each joint. Inside that conduit is basically the same harness I had before, with the cables selected to be more robust to repetitive motion. The nylon conduit is only semi-flexible, so it enforces a relatively large minimum bending radius on the wires within, while still sticking to the black quad A1 color motif.

To verify this would be at least a minimal step up, I ran some endurance testing with around 100,000 cycles of the leg moving. With no degradation of the cables in that window, I’m calling this good enough for this iteration of improvement.

Stable gait sequencing

In the last post, I described the newer gait engine which takes a desired command and produces a set of gait parameters. At that point, the gait engine needs to implement those gait parameters in a way that is stable with respect to disturbances and keeps the two legs properly out of phase with one another.

The gait variables that the gait selection procedure emits are as follows, each “leg” is actually a pair of legs.

  • swing time: This is the amount of time between when a leg lifts off the ground, and when it lands again.
  • one leg time: This is the amount of time spent with only a single leg on the ground.
  • two leg time: The amount of time with both legs on the ground.
  • flight time: The amount of time with no legs on the ground.

I’ve chosen to implement this for now with two controllable variables, when to pick up the next leg to begin its swing phase and how far out to place the foot when landing. When in flight, the swing time is fixed to be exactly what the gait engine selected. When on the ground, the leg position and velocity are fixed in the world frame to match the current command. This results in the other three parameters, one leg, two leg, and flight time, being approximated as best as possible.

When to lift

When there is no flight time, then the heuristic for when to lift the leg is identical to that described in “Balancing gait in 2D“. The trailing leg is lifted when the opposing leg is half of a swing time away from crossing the balance point.

When there is a flight time present, we have to add a corrective term to that heuristic, otherwise the two legs can lose their phase synchronization. If the correct out of phase relationship is being held, then the leg will be lifted when the alternate leg is in flight and has the “flight time” remaining in its swing cycle. The correction for that leg is calculated as a difference in time around that point such that the correction is positive before that point and negative after scaling in a linear manner. This has the desired property that the two legs are kept out of phase, without enforcing a strict leg cycle time.

Where to place

Once again, when there is no flight time, the placement location is the same as before. When there is a flight time, then the placement location is even simpler. Now it is just a position forward of the balance point by one half of the “one leg time”. This results in the machine spending roughly half of its time on each side of the balance point.

Further work

I’ve got one further enhancement to this technique to describe, at which point I think I’ll have basically exhausted its promise. Further advances will likely have to come from using an optimization based controller rather than a heuristic driven approach.

Higher speed gait formulation

As hinted in my earlier video I’ve been working towards some higher speed gaits with the quad A1. To accomplish that, I had to restructure the gait sequencing logic to permit changing cycle times and allow flight phases.

For now, I’ve tentatively broken down the trot gait into 5 regimes, based on how fast the machine is moving:

  1. At the slowest speeds, the flight legs swing through a step in the configured maximum flight time. The interval between flight times is fixed at a configured maximum. Here the speed is determined by how far the flight legs move.
  2. Once the flight legs are moving through their maximum allowed distance, then the amount of time spent with both legs on the ground is reduced in order to increase speed.
  3. At the point when both legs are not on the ground at the same time, then there begins to be a flight phase. Increasing the length of the flight phase increases the speed.
  4. When the flight phase reaches a configured maximum, then the swing time is decreased until it reaches a configured minimum.
  5. When the swing time is at a configured minimum, the flight time is at a configured maximum, and the legs are moving through their maximum range, then the machine is moving at its maximum speed.

Depending upon the current commanded rotation rate and translation velocity, the distance available for the legs to travel through may change. This uses the same mechanism from the step selection technique to determine the maximum distance at each update cycle, then selects which of the above regimes is active based on the commanded speed.

For a given maximum distance the legs can move through, that results in key gait parameters changing with speed as in the plot below:

Next up I’ll cover the heuristics used to implement any given set of gait parameters in a stable manner.