Output limit reason reporting

There are many configurable values and internal firmware limits in the moteus brushless motor controller that result in the output current being less that would exist in an ideal system or less than what was commanded. To date, the only way to know if any of these factors was resulting in limiting behavior was to know all of the possible limiting factors, and look at factor specific diagnostic values one by one to see which was the culprit. Now, as of firmware release 2025-07-21, moteus will report exactly which feature is limiting the output at any given point in time, making that diagnostic process much simpler.

Read on for more details.

Limiting factors

There are quite a decent number of mechanisms that can limit the output during normal operation:

  1. Position bounds: If the current position is outside of servopos.position_min and servopos.position_max, then torque is limited in the direction that would push the motor further outside the bounds.
  2. Maximum torque: With each position mode command, the client can specify a maximum torque to use. If the combination of the onboard PID and commanded feedforward torque exceeds this, then limiting occurs.
  3. Temperature: The onboard FET temperature sensor, or if enabled the motor thermistor temperature sensor, can limit the output current. These thresholds are set in the current firmware with servo.fault_temperature/servo.temperature_margin and servo.motor_fault_temperature/servo.motor_temperature_margin.
  4. Maximum current: There is a system wide maximum output phase current that is configured in servo.max_current_A.
  5. Maximum output voltage: The output voltage cannot exceed the input voltage multiplied by the maximum effective modulation depth.
  6. Maximum power: The total power of the output is limited through a combination of a board power profile and servo.max_power_W. See this post for more.
  7. Maximum velocity: If the observed velocity exceeds the configured maximum velocity, torque is limited in the direction that would cause the velocity to increase. This is configured with servo.max_velocity.

There are some “limiting-like” features that do not report through this mechanism. If position bounds are configured, the control position is limited to stay within those bounds. This does not directly limit torque, so is not reported via this mechanism.

Similarly, if the commanded velocity exceeds either the velocity limit, velocity.max_velocity, or servo_stats.motor_max_velocity, then it is truncated to stay within. This also is not reported via this mechanism.

Reporting mechanism

The current limiting reason is reported via the fault code register 0x00f, and via servo_stats.fault via the diagnostic protocol. Previously these values were only defined if the primary mode was that of a fault.

Since this register is requested by default with both the C++ and python libraries, that means that most applications already have access to the new limit reporting data with no changes required.

However, in some cases, a client application may have been treating any non-zero fault code as a fault state, no matter what the actual mode was. If that was the case, then this reporting mechanism will be a breaking change. You will either have to not update the firmware on affected devices, or update your application to first look at the mode before inspecting the fault code.