RobotActuators

Actuators

We have developed Python and Rust packages to make it easy to control our robot’s actuators.

Installation

The package can easily be installed from PyPI using the command:

sudo apt install pkg-config libudev-dev  # If not installed
pip install actuator

Alternatively, to install the bleeding edge version from Github, use the command:

pip install 'actuator @ git+https://github.com/kscalelabs/actuator.git@master'

Actuators are the most important component of a robot. In this guide, we will walk you through the actuators that we use in our robot and conventions we use to connect to them.

Specs

Our general-purpose robot uses the Robstride series of actuators.

ActuatorTorqueVoltageEncoders
Robstride 0014 Nm48 VDual-encoder
Robstride 0117 Nm36 VSingle-encoder
Robstride 0217 Nm48 VDual-encoder
Robstride 0360 Nm48 VDual-encoder
Robstride 04120 Nm48 VDual-encoder

We use the following actuator types for each degree of freedom:

Actuator types

ID Layout

We use the following numbering scheme for the actuators in our robot:

Actuator ID Layout

Actuator Package

Here is a high-level overview of the package architecture.

Actuator Package Architecture

Prerequisites

  • Operating System: This package has been tested on Linux, but may work with other operating systems.
  • Python: Python 3.11 or later.
  • Rust: This package has been tested with Rust 1.80.1, but will likely work with other versions.

You should install the following libraries:

sudo apt install pkg-config libudev-dev

Robstride Actuator Interface

This package lets you interact with the Robstride series of actuators using their custom CAN controller.

pip install actuator  # Install the entire Python package
cargo install robstride  # Install the Rust package

The actuator package is designed to work with the Robstride-developed USB to CAN controller, which is built on the CH341 USB controller. This requires some additional setup to get started.

You can install the pure-Rust implementation of this package from here.

Pre-requisites

Make sure you have satisfied the following requirements:

  • Operating System: We have tested this package on Linux. Note that it will not work on Mac with the default USB to CAN drivers, since Mac does not support the required TTY baudrate of 921600. It may work with Windows as well, but we have not yet tested this.
  • Python Version: This package works with Python 3.11 and above.
  • Rust: You should ensure that Rust is installed on your system.

SocketCAN

If controlling Robstride motors through SocketCAN, run the following to set-up the interface (with interfaces enumerating as can[x])

ip link set can0 down
ip link set can0 type can bitrate 1000000
ip link set can0 txqueuelen 1000
ip link set can0 up

CH341 Driver

Note that there are some additional steps needed before the Robstride USB controller will work on Linux:

  1. Install this driver for the CH341 USB controller.
  2. This should create a /dev/ttyUSB0 or /dev/ttyCH341USB0 device - you should check which one by doing ls /dev/tty*. You might need to the change the permissions:

Note that if you successfully installed the CH341 driver but the USB device wasn’t created, another service may be interfering with the CH341 driver. Try running dmesg | grep ch341 see if other services are claiming the interface. In some cases, brltty may be interrupting the CH341 setup in which case you should unload it or remove it entirely.

sudo chmod 666 /dev/ttyCH341USB0
  1. Run the following command to configure the baud rate of the controller:
sudo stty -F /dev/ttyUSB0 921600
  1. Alternatively, you can add the following line to your /etc/udev/rules.d/51-ch340.rules file to automatically configure the baud rate:
KERNEL=="ttyCH341USB[0-9]", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="ttyUSB%n", RUN+="/bin/stty -F /dev/ttyCH341USB0 921600"
KERNEL=="ttyUSB[0-9]", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", RUN+="/bin/stty -F /dev/ttyUSB0 921600"
  1. After adding the above rule, you should run sudo udevadm control --reload-rules to reload the rules.

Test Program

Here is a simple test program you can use to try using the Robstride motor controllers:

import argparse
import math
import time
 
from actuator import RobstrideMotorsSupervisor
 
# Parse command line arguments.
parser = argparse.ArgumentParser()
parser.add_argument("--port-name", type=str, default="/dev/ttyUSB0")
parser.add_argument("--motor-id", type=int, default=1)
parser.add_argument("--motor-type", type=str, default="01")
parser.add_argument("--sleep", type=float, default=0.0)
parser.add_argument("--period", type=float, default=10.0)
parser.add_argument("--amplitude", type=float, default=1.0)
parser.add_argument("--verbose", action="store_true")
args = parser.parse_args()
 
amplitude = args.amplitude
period = args.period
 
# This creates a motor supervisor, which sends commands to all the actuators on
# the same CAN bus at a regular interval.
supervisor = RobstrideMotorsSupervisor(args.port_name, {args.motor_id: args.motor_type})
 
# This is used to set the KP and KD parameters for the MIT Cheetah-style
# PD controller.
supervisor.set_kp(args.motor_id, 10.0)
supervisor.set_kd(args.motor_id, 1.0)
 
start_time = time.time()
 
try:
    while True:
        elapsed_time = time.time() - start_time
        target_position = amplitude * math.sin(elapsed_time * 2 * math.pi / period)
        target_velocity = amplitude * 2 * math.pi / period * math.cos(elapsed_time * 2 * math.pi / period)
        supervisor.set_position(args.motor_id, target_position)
        supervisor.set_velocity(args.motor_id, target_velocity)
        time.sleep(args.sleep)
        if args.verbose:
            feedback = supervisor.get_latest_feedback()
            print(feedback)
 
except KeyboardInterrupt:
    supervisor.stop()
    time.sleep(0.1)
    raise

Assorted Notes

Robstride actuators move in a positive direction when going clockwise looking at the flat face of the motor. That is, +90 deg is 90 deg clockwise and -90 deg is 90 deg counterclockwise

Robstride Clockwise Direction