opensourceleg icon indicating copy to clipboard operation
opensourceleg copied to clipboard

feat: Add TMotor servo mode actuator with native CAN protocol support

Open DasuanerA opened this issue 3 months ago • 6 comments

Implements complete TMotor servo mode control for AK series actuators (AK80-9, AK10-9) using native CAN communication protocol.

Architecture

Core Classes:

  • TMotorServoActuator: Main actuator class extending ActuatorBase

    • Manages motor state, control modes, and command interface
    • Implements thermal protection via ThermalModel
    • Tracks communication timeouts and error states
  • CANManagerServo: Singleton CAN communication manager

    • Configures CAN0 interface: 1MHz bitrate, txqueuelen 1000
    • Handles message sending/receiving via python-can library
    • Power on/off commands: 0xFC (on), 0xFD (off)
  • MotorListener: CAN message listener (can.Listener)

    • Asynchronous message reception via can.Notifier
    • Filters messages by motor ID (arbitration_id & 0x00000FF)
    • Triggers async state updates in actuator

Data Structures:

  • ServoMotorState: Motor state container

    • position (degrees), velocity (ERPM), current (amps)
    • temperature (celsius), error code, acceleration (rad/s)
  • ServoControlMode: Enum for control modes

    • POSITION (4), VELOCITY (3), CURRENT (1), IDLE (7)

CAN Protocol Implementation

Message IDs (Extended CAN):

  • SET_DUTY: 0x00 (not used)
  • SET_CURRENT: 0x01 (current control)
  • SET_CURRENT_BRAKE: 0x02 (not used)
  • SET_RPM: 0x03 (velocity control)
  • SET_POS: 0x04 (position control)
  • SET_ORIGIN_HERE: 0x05 (homing)
  • SET_POS_SPD: 0x06 (not used)
  • Control mode switch: 0x07

Message Format:

  • TX (4 bytes, big-endian): int32 command value

    • Position: degrees * 10 (0.1 resolution, configurable to *1000000)
    • Velocity: ERPM value directly
    • Current: milliamps (current * 1000)
  • RX (8 bytes, big-endian parsing):

    • Bytes[0-1]: Position (int16, *0.1 degrees)
    • Bytes[2-3]: Velocity (int16, *10 ERPM)
    • Bytes[4-5]: Current (int16, *0.01 amps)
    • Byte[6]: Temperature (uint8, celsius)
    • Byte[7]: Error code (uint8)

Control Features

Implemented Methods:

  • set_motor_torque(Nm): Converts via Kt to current command
  • set_output_torque(Nm): Applies gear ratio compensation
  • set_motor_current(A): Direct current command
  • set_motor_position(rad): Converts to degrees, sends position command
  • set_motor_velocity(rad/s): Converts to ERPM via pole pairs
  • set_output_velocity(rad/s): Applies gear ratio
  • home(): Sets origin via CAN_PACKET_SET_ORIGIN_HERE

State Properties:

  • motor_position/output_position (radians)
  • motor_velocity/output_velocity (rad/s)
  • motor_current (amps)
  • motor_torque/output_torque (Nm)
  • case_temperature/winding_temperature (C)
  • error_info: Optional[tuple[error_code, error_message]]

Safety Features

  • Thermal protection: 80C case, 110C winding limits (configurable)
  • Communication timeout: 100ms threshold warning
  • Auto-stop on critical errors (overcurrent, overtemp)
  • Acceleration calculation for sudden change detection
  • Control mode verification via test command
  • Detailed status reporting via get_detailed_status()

Utility Functions

  • degrees_to_radians() / radians_to_degrees()
  • erpm_to_rad_per_sec() / rad_per_sec_to_erpm()
    • Accounts for motor pole pairs in conversion
  • _pack_int32(): Big-endian int32 packing for CAN TX

Control Mode Management

Each mode has entry/exit callbacks:

  • POSITION: Switch to mode 4, no exit action
  • VELOCITY: Switch to mode 3, zero velocity on exit
  • CURRENT: Switch to mode 1, zero current on exit
  • IDLE: Switch to mode 7, no exit action
  • All modes wait 100ms after switching for stabilization

Example Code (main)

Demonstrates current control mode with 15Nm torque command:

  1. Initialize motor (AK80-9, ID:1, offline mode for testing)
  2. Home motor and activate current control mode
  3. Command 15Nm output torque
  4. Run 10Hz monitoring loop for 5 seconds displaying:
    • Commanded vs actual torque (motor and output)
    • Motor and output angles (rad and degrees)
    • Motor and output velocities (rad/s)
    • Current, voltage, temperature
    • Error status
  5. Safe shutdown with zero torque
  6. Display final state summary

Note: Position resolution currently set to 0.1 for simplicity. To enable high-precision mode (0.000001), modify line 323.

DasuanerA avatar Aug 11 '25 06:08 DasuanerA

Hey @DasuanerA, can you please address the comments soon so that we can merge this PR and start planning our tests?

senthurayyappan avatar Aug 20 '25 20:08 senthurayyappan

Welcome to Codecov :tada:

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

:information_source: You can also turn on project coverage checks and project coverage reporting on Pull Request comment

Thanks for integrating Codecov - We've got you covered :open_umbrella:

codecov-commenter avatar Oct 02 '25 01:10 codecov-commenter

Hey @DasuanerA was any of this tested on hardware?

tkevinbest avatar Nov 05 '25 15:11 tkevinbest

Hey @DasuanerA was any of this tested on hardware?

Yes. Here is the plot of my testing. I'm now testing the motor on the MBlue Knee.

tmotor_torque_test_results

DasuanerA avatar Nov 05 '25 16:11 DasuanerA

Can you please resolve the remaining conflicts? And do you have some more information on what kinds of tests you ran?

tkevinbest avatar Nov 05 '25 18:11 tkevinbest

Can you please resolve the remaining conflicts? And do you have some more information on what kinds of tests you ran?

The test I’m running is static test to check whether the commanded current under the current loop can accurately track the desired trajectory, and the sensors can correctly read all the data.

DasuanerA avatar Nov 05 '25 20:11 DasuanerA