Transports
Overview
The SDK exposes four transport constructors:
| Constructor | Protocol | Use Case |
|---|
Controller(channel) | SocketCAN | Standard CAN 2.0, most common |
Controller.from_socketcanfd(channel) | CAN-FD | High-bandwidth, Hexfellow motors |
Controller.from_dm_serial(port, baud) | Serial | Damiao serial bridge adapter |
Controller.from_dm_device(device_type, channel) | DM_Device SDK | Damiao USB2CANFD / USB2CANFD_DUAL / LINKX4C adapters |
SocketCAN (Standard CAN)
The default transport for most motor vendors.
Linux uses SocketCAN directly, and Windows/macOS use the PCAN backend with canX channel aliases.
Usage
from motorbridge import Controller
# Open standard CAN interface
with Controller("can0") as ctrl:
motor = ctrl.add_damiao_motor(0x01, 0x11, "4340P")
# ... control motor
Supported Vendors
- Damiao (all models)
- RobStride
- MyActuator
- HighTorque
Linux (SocketCAN):
# Configure CAN interface at 1M bitrate
sudo ip link set can0 type can bitrate 1000000
sudo ip link set can0 up
# Increase TX queue to prevent buffer overflow
sudo ifconfig can0 txqueuelen 1000
macOS (PCAN via PCBUSB):
# Verify PCBUSB runtime is available
python3 -c "import ctypes; ctypes.CDLL('libPCBUSB.dylib'); print('PCBUSB load OK')"
# Run a scan check on can0
motorbridge-cli scan --vendor damiao --transport auto --channel can0 --start-id 1 --end-id 16
Windows (PCAN):
# Verify PCAN runtime is available
python -c "import ctypes; ctypes.CDLL('PCANBasic.dll'); print('PCANBasic load OK')"
# can0@1000000 maps to PCAN_USBBUS1
motorbridge-cli scan --vendor damiao --transport auto --channel can0@1000000 --start-id 1 --end-id 16
Multiple CAN Interfaces
# Control motors on different CAN buses
with Controller("can0") as ctrl0:
motor0 = ctrl0.add_damiao_motor(0x01, 0x11, "4340P")
with Controller("can1") as ctrl1:
motor1 = ctrl1.add_robstride_motor(127, 0xFD, "rs-06")
CAN-FD (SocketCAN-FD)
Extended CAN with larger payload and higher bandwidth. Required for some vendors.
Usage
from motorbridge import Controller
# Open CAN-FD interface
with Controller.from_socketcanfd("can0") as ctrl:
motor = ctrl.add_hexfellow_motor(0x01, 0x00, "hexfellow")
# ... control motor
Supported Vendors
- Hexfellow (required)
- Damiao (optional, for higher bandwidth)
System Setup
# Configure CAN-FD interface
sudo ip link set can0 type can bitrate 1000000 dbitrate 5000000 fd on
sudo ip link set can0 up
CAN-FD examples above are Linux-first. On Windows/macOS, prefer standard CAN (Controller(channel)) unless your adapter stack explicitly supports FD.
DM Serial Bridge
Serial-to-CAN bridge for Damiao motors using the official Damiao serial adapter.
Usage
from motorbridge import Controller
# Open serial bridge
with Controller.from_dm_serial("/dev/ttyACM0", baud=921600) as ctrl:
motor = ctrl.add_damiao_motor(0x01, 0x11, "4340P")
# ... control motor
Parameters
| Parameter | Type | Default | Description |
|---|
serial_port | str | ”/dev/ttyACM0” | Serial device path |
baud | int | 921600 | Baud rate (use 921600 for Damiao) |
Supported Vendors
DM_Device SDK
DaMiao DM_Device_SDK controls CAN/CAN FD adapter hardware. In motorbridge, this
transport is wired to the Damiao motor protocol only, and the adapter must be in
USB mode.
Supported Adapter Types
| Adapter | SDK enum | Channels | dm_device_type | dm_channel |
|---|
| USB2CANFD | USB2CANFD | 1 | usb2canfd | 0 |
| USB2CANFD_DUAL | USB2CANFD_DUAL | 2 | usb2canfd-dual | 0 / 1 |
| LINKX4C | LINKX4C | 4 | linkx4c | 0 / 1 / 2 / 3 |
Python Usage
from motorbridge import Controller
# USB2CANFD_DUAL channel 0
with Controller.from_dm_device("usb2canfd-dual", "0") as ctrl:
motor = ctrl.add_damiao_motor(0x04, 0x14, "4310")
# LINKX4C channel 0
with Controller.from_dm_device("linkx4c", "0") as ctrl:
motor = ctrl.add_damiao_motor(0x04, 0x14, "4310")
CLI Usage
# Scan all channels on USB2CANFD_DUAL: 0 and 1
motorbridge-cli scan \
--vendor damiao \
--transport dm-device \
--dm-device-type usb2canfd-dual \
--model 4310 \
--start-id 1 \
--end-id 16
# Scan all channels on LINKX4C: 0, 1, 2, 3
motorbridge-cli scan \
--vendor damiao \
--transport dm-device \
--dm-device-type linkx4c \
--model 4310 \
--start-id 1 \
--end-id 8
# Control one physical channel
motorbridge-cli run \
--vendor damiao \
--transport dm-device \
--dm-device-type linkx4c \
--dm-channel 0 \
--model 4310 \
--motor-id 0x04 \
--feedback-id 0x14 \
--mode enable \
--loop 1
In scan mode, omit --dm-channel to scan every channel for the selected
adapter. Pass --dm-channel only when you want one physical channel.
Linux:
# Check available serial ports
ls -la /dev/ttyACM* /dev/ttyUSB*
# Add user to dialout group for permission
sudo usermod -a -G dialout $USER
# Log out and back in
macOS:
# Typical serial devices
ls -la /dev/cu.usbmodem* /dev/cu.usbserial*
Windows (PowerShell):
# List COM ports
[System.IO.Ports.SerialPort]::GetPortNames()
Common Serial Devices
| Device | Path | Notes |
|---|
| Damiao USB-CAN | /dev/ttyACM0 | Default |
| USB-Serial Adapter | /dev/ttyUSB0 | Check with dmesg |
Transport Selection Guide
Decision Tree
What motor vendor are you using?
│
├── Hexfellow ──→ from_socketcanfd (required)
│
├── Damiao with DM_Device USB2CANFD/DUAL/LINKX4C ──→ from_dm_device
│
├── Damiao with USB-CAN adapter ──→ from_dm_serial
│
├── Damiao with CAN card ──→ Controller (SocketCAN)
│
├── RobStride ──→ Controller (SocketCAN)
│
├── MyActuator ──→ Controller (SocketCAN)
│
└── HighTorque ──→ Controller (SocketCAN)
Mixed Vendor Setup
When using multiple vendors on the same CAN bus, create separate Controller instances:
from motorbridge import Controller
# Each vendor gets its own controller
with Controller("can0") as dm_ctrl:
dm_motor = dm_ctrl.add_damiao_motor(0x01, 0x11, "4340P")
dm_ctrl.enable_all()
with Controller("can0") as rs_ctrl:
rs_motor = rs_ctrl.add_robstride_motor(127, 0xFD, "rs-06")
rs_ctrl.enable_all()
Do not add motors from different vendors to the same Controller instance. Each controller is optimized for a specific vendor protocol.
Latency Comparison
| Transport | Typical Latency | Max Throughput |
|---|
| SocketCAN | ~1-2 ms | ~5000 msg/s |
| CAN-FD | ~0.5-1 ms | ~10000 msg/s |
| DM Serial | ~2-5 ms | ~2000 msg/s |
Recommendations
- Real-time control: Use SocketCAN or CAN-FD
- Development/Debug: DM Serial is convenient for quick testing
- High-speed loops: Use CAN-FD with
dt_ms >= 10
Troubleshooting
SocketCAN: “No buffer space available” (Error 105)
# Stop other CAN senders
# Increase TX queue
sudo ifconfig can0 txqueuelen 1000
# Increase control loop period
# dt_ms = 20 or higher
Serial: Permission Denied
sudo usermod -a -G dialout $USER
# Log out and back in
CAN-FD: “Invalid argument”
# Ensure CAN-FD is enabled on interface
sudo ip link set can0 type can bitrate 1000000 dbitrate 5000000 fd on
sudo ip link set can0 up
Next Steps