Skip to main content

A package to manage AK series T Motors over CAN

Project description

TMotorCANControl

A Python API for controlling the AK-series Tmotor Actuators from CubeMars over the CAN bus. The project is geared towards the control of the AK80-9 actuator using a raspberry pi CAN hat or serial bus, but could eaisly be adapted for use with a different CAN/serial interface. The API files are in the src/TMotorCANControl folder in this repository. The main interface is in the file TMotorManager_mit_can.py for MIT mode, TMotorManager_servo_can.py for Servo mode (over CAN), and TMotorManager_servo_serial for Servo mode (over serial). The CAN_Manager_mit and CAN_Manager_serial file contains a low-level CAN interface for interacting with the motor, which is used by the TMotorManager classes to control the motor in a more user-friendly way. Sample scripts can be found in the demos folder. For help setting up the motor using a Raspberry Pi 4 and with the PiCAN hat, see these instructions on the Open Source Leg website. That page will walk you through all the setup.

API Usage

For some code examples, see the demos folder in this repository. For the full API documentation, see our page on ReadTheDocs. These examples make use of the soft_real_timeloop class from the NeuroLocoMiddleware library for the control loops, but the library could be used without this dependancy.

The TMotorManager_mit_can, TMotorManager_servo_can, and TMotorManager_servo_serial classes are in the TMotorManager module in the TMotorCANControl package. The intended use case would be to declare a TMotorManager_mit_can, TMotorManager_servo_can, or TMotorManager_servo_serial object in a block, and then write your controller within that block, in order to ensure the motor is powered on when in use and powered off if an error is thrown or the program ends.

To control a motor that has been set up for MIT control over the CAN bus, specify the motor type and CAN ID, as shown below for an AK80-9 with CAN ID 3.

from TMotorCANControl.TMotorManager_mit_can import TMotorManager_mit_can
with TMotorManager_mit_can(motor_type='AK80-9', motor_ID=3) as dev:
    dev.update()

To control a motor that has been set up for Servo control over the CAN bus, specify the motor type and CAN ID, as shown below for an AK80-9 with CAN ID 3.

from TMotorCANControl.TMotorManager_servo_can import TMotorManager_servo_can
with TMotorManager_servo_can(motor_type='AK80-9', motor_ID=3) as dev:
    dev.update()

To control a motor that has been set up for MIT control over the CAN bus, specify the motor type and CAN ID, as shown below for an AK80-9 on usb serial port 'dev/tty/USB0', with baud rate 921600 (the default).

from TMotorCANControl.TMotorManager_servo_serial import TMotorManager_servo_serial
with TMotorManager_servo_serial(port='/dev/ttyUSB0', baud=921600, motor_params=Servo_Params_Serial['AK80-9']) as dev:
    dev.update()

The motor can be controlled in a variety of modes, depending on which communication setup you are using, as shown below.

Control Mode MIT CAN Servo CAN Servo Serial
Current yes yes yes
Velocity yes yes yes
Position yes yes yes
Duty Cycle no yes yes
Impedance with feedforward Current yes no no
Position with velocity/acceleration limits no yes yes

Once entered, the motor can be controlled in any of these modes by setting the TMotorManager's internal command, and then calling the update() method to send the command. The values of the internal command can be set with the following methods, if available for the communication protocol you are using.

  • set_output_angle_radians(pos): Sets the position command to "pos" radians.
  • set_motor_current_qaxis_amps(current): Sets the current command to "current" amps.
  • set_duty_cycle_percent(duty): (only in servo mode, CAN or serial) Set the duty cycle to the specified percentage ratio, between 0 and 1.
  • set_output_torque_newton_meters(torque): Sets the current command based on the torque supplied.
  • set_output_velocity_radians_per_second(vel): Sets velocity command to "vel" rad/s.
  • set_motor_torque_newton_meters(torque): Sets torque command based on the torque specified, adjusted for the gear ratio to control motor-side torque.
  • set_motor_angle_radians(pos): Sets position command based on the position specified, adjusted for the gear ratio to control motor-side position.
  • set_motor_velocity_radians_per_second(vel): Sets velocity command based on the velocity specified, adjusted for the gear ratio to control motor-side velocity.

Furthermore, the motor state can be accessed with the following methods. The state is updated every time the update() method is called, which are pretty self explanitory.

  • get_current_qaxis_amps()
  • get_output_angle_radians()
  • get_output_velocity_radians_per_second()
  • get_output_acceleration_radians_per_second_squared()
  • get_output_torque_newton_meters()
  • get_motor_angle_radians()
  • get_motor_velocity_radians_per_second()
  • get_motor_acceleration_radians_per_second_squared()
  • get_motor_torque_newton_meters()
  • get_motor_error_code()

The following are available only for servo mode over the serial bus:

  • get_current_daxis_amps()
  • get_current_bus_amps()
  • get_voltage_qaxis_volts()
  • get_voltage_daxis_volts()
  • get_voltage_bus_volts()

The getters and setters above are also combined into properties for ease of use.

  • current_qaxis: q-axis current in Amps
  • position: output angle in rad (after gearbox)
  • velocity: output velocity in rad/s (after gearbox)
  • acceleration: output acceleration in rad/s/s (after gearbox)
  • torque: output torque in Nm (after gearbox)
  • position_motorside: motor-side angle in rad (before gearbox)
  • velocity_motorside: motor-side velocity in rad/s (before gearbox)
  • acceleration_motorside: motor-side acceleration in rad/s/s (before gearbox)
  • torque_motorside: motor-side torque in Nm (before gearbox)

And for servo mode over the serial bus only:

  • current_daxis: d-axis current in Amps
  • current_bus: input current in Amps
  • voltage_qaxis: q-axis voltage in Volts
  • voltage_daxis: d-axis voltage in Volts
  • voltage_bus: input voltage in Volts

Another notable function is the zero_position() function, which sends a command to the motor to zero it's current angle. This function will shut off control of the motor for about a half second while the motor zeros (sort of like zeroing a scale, it seems to record a few points to get a good measurement). As such, after calling the method you should delay for at least 500 ms if timely communication is important.

The following example would instantiate a TMotorManager for an AK80-9 motor with a CAN ID of 3, logging into a CSV file named "log.csv", with the full set of log variables specified above. Then it will zero the motor position and wait long enough for the motor to be done zeroing. Finally, it will enter impedance control mode with gains of 10Nm/rad and 0.5Nm/(rad/s). It then will set the motor position to 3.14 radians until the program is exited.

with TMotorManager_mit_can(motor_type='AK80-9', motor_ID=3) as dev:
    dev.set_zero_position()
    time.sleep(1.5)
    dev.set_impedance_gains_real_unit(K=10,B=0.5)
    loop = SoftRealtimeLoop(dt = 0.01, report=True, fade=0)

    for t in loop:
        dev.update()
        dev.position = 3.14

For more examples, see the demos folder. Have fun controlling some CubeMars Motors!

Other Resources

  1. Setup Instructions on the OSL Website

  2. API Documentation

  3. AK-series motor manual The documentation for the AK-series TMotors, which includes the CAN protocol and how to use R-Link

  4. PiCAN 2 CAN Bus Hat The documentation for the CopperHill Raspberry Pi CAN hat.

  5. RLink Youtube videos Yoyo's youtube channel has some tutorials on how to use the RLink software.

  6. Mini-Cheetah-TMotor-Python-Can This is another, more low-level library for controlling these motors in MIT mode.

This work is performed by Mitry Anderson and Vamsi Peddinti.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

TMotorCANControl-1.2.4.tar.gz (38.1 kB view details)

Uploaded Source

Built Distribution

TMotorCANControl-1.2.4-py3-none-any.whl (36.3 kB view details)

Uploaded Python 3

File details

Details for the file TMotorCANControl-1.2.4.tar.gz.

File metadata

  • Download URL: TMotorCANControl-1.2.4.tar.gz
  • Upload date:
  • Size: 38.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/34.0 requests/2.26.0 requests-toolbelt/0.9.1 urllib3/1.26.7 tqdm/4.63.0 importlib-metadata/4.11.3 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.8.8

File hashes

Hashes for TMotorCANControl-1.2.4.tar.gz
Algorithm Hash digest
SHA256 104fff7f7e9ccce4d74795fa4689dfec0ab22c658cf2f6d0bc92fc359bacea1a
MD5 bb5d514c4f055ca10cf9b920b65d3dc6
BLAKE2b-256 bd1085787a5b2c4d5bbd2e4c575dd6391bf741b3345ab64a136c0a517522ae07

See more details on using hashes here.

File details

Details for the file TMotorCANControl-1.2.4-py3-none-any.whl.

File metadata

  • Download URL: TMotorCANControl-1.2.4-py3-none-any.whl
  • Upload date:
  • Size: 36.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/34.0 requests/2.26.0 requests-toolbelt/0.9.1 urllib3/1.26.7 tqdm/4.63.0 importlib-metadata/4.11.3 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.8.8

File hashes

Hashes for TMotorCANControl-1.2.4-py3-none-any.whl
Algorithm Hash digest
SHA256 f1fdb48d4b786498bf4729f0ac3083d6f1c987b9d96c7d25e162ed1dcd2bba92
MD5 8ae8a263b05a29ba328852a8c60e2c05
BLAKE2b-256 53ecd87e085f2c5b9b29cf1d3c001811c6d8907d84cf0e9433c668e13521641e

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page