Archives: Python

Optimizing moteus command rate

Probably one of the most frequently asked questions in the mjbots Discord is “how fast can I send new commands to moteus”, or “how fast can I read the status from moteus”. That may be because you want to perform torque based control in your application and require high bandwidth, or just because you have a high torque to inertia ratio system that reacts on very short time-scales. No matter the reason, the principles that control the maximum rate you can send updates are the same.

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:

moteus external connector pin selection

moteus r4.11 has two external connectors, the ABS connector (AUX2) and the ENC/AUX1 connector. The ABS connector was designed initially just to have 2 I2C pins. The ENC connector just has the random pins that were used for the onboard encoder SPI plus one more. Thus the range of external accessories that can be connected is somewhat haphazard and not necessarily all that useful.

When working on a more ground up revision of the controller, I wanted to improve that situation to expose more connectivity options on still a relatively limited connector set. The idea was to use 2 connectors, one which has 5 I/O pins and the other with 4 I/O pins. The onboard encoder SPI would still be accessible on the larger connector to use for at least one external SPI encoder, but how much other functionality could be crammed into the remaining pins? To start, lets see what possible options there are in the current firmware and supported by the STM32G4 microcontroller that moteus uses:

UART tunneling with moteus

With the release of more flexible I/O support, the moteus controller auxiliary port can be used to monitor encoders using an onboard UART. Now, with firmware release 2023-02-01, those UART pins can be used as an arbitrary logic level serial port controlled by the application! Let’s see how to use it below.

First, you will need to look at the pin configuration table to find pins that support UART functionality, and configure them as UART in the “aux?.pins” configuration tree. Next, “aux?.uart.mode” should be set to “kTunnel”, along with the desired baud rate. That’s it on the configuration front.

Debugging bare-metal STM32 from the seventh level of hell

Here’s a not-so-brief story about troubleshooting a problem that was at times vexing, impossible, incredibly challenging, frustrating, and all around just a terrible time with the bare-metal STM32G4 firmware for the moteus brushless motor controller.

Background

First, some things for context:

moteus has a variety of testing done on every firmware release. There are unit tests that run with pieces of the firmware compiled to run in a host environment. There is a hardware-in-the-loop dynamometer test fixture that is used to run a separate battery of tests. There is also an end-of-line test fixture that is used to run tests on every board and some other firmware level performance tests.

Improved mjbots labels

For most of mjbots’ existence, all of our products were labeled with a dependable, if lackluster, Brother P-Touch label maker. In line with other packaging improvements, I recently upgraded that labeling setup to bigger, higher resolution, and full color!

This is using an Epson TM-C3500, which I had expected to operate directly from my Linux based test fixtures. However, upon receiving it, discovered that alas only Windows drivers were available. Thankfully, it wasn’t too bad to print from python in a simple way as long as you manually select the media type from the Windows dialogs. Thus I made up a simple Flask app to receive label images over HTTP and print them. That runs on a Windows computer, and the test fixture applications just POST their label images to it.

pi3hat python raw CAN-FD

The pi3hat, among other things has 5 CAN-FD ports. You can use them to drive a lot of moteus servos, but they are perfectly fine CAN-FD ports generally. The C++ library has always been able to send and receive arbitrary frames (and recently at arbitrary bitrates), but the python interface was lacking, only exposing a portion of this functionality.

As of version 0.3.11, the python library (pip3 install moteus-pi3hat) now exposes everything you need to be able to send and receive arbitrary CAN frames from any of the ports, as well as configure all the timing options for waiting for responses from slave devices.

pi3hat configurable CAN

To date, the pi3hat CAN channels only supported CAN properties suitable for use with moteus controllers. Given that’s what most people are using them for, that’s fine. However, there was no real constraint behind that, just laziness.

Thus, I’ve released new firmware for the pi3hat that supports configuring the bitrate, FD-ness, and other properties of all 5 CAN channels.

Currently only the C++ library exposes the configuration functionality, but it will be easy enough to add to python when someone needs it.

New cross-platform moteus tools!

After receiving many requests via youtube, discord, and email, I’ve finally gone ahead, bitten the bullet, and updated all of the moteus tools to be pure python and work in a cross platform manner. Now, the only thing you need to do to install pre-compiled versions of tview and moteus tool on most* platforms is:

pip3 install moteus_gui
python3 -m moteus_gui.tview    # (or maybe just tview)
python3 -m moteus.moteus_tool  # (or maybe just moteus_tool)

I’ve personally tested these on Linux, Windows, and Raspberry Pi, and others have at least verified basic operation on Macs. Python 3.7 or greater is required.