Skip to main content

Crate moteus

Crate moteus 

Source
Expand description

§moteus

Rust client library for moteus brushless motor controllers.

This crate provides a high-level API for communicating with moteus controllers over CAN-FD. It supports multiple transport backends and automatic device discovery.

§Crate Structure

This library is split into two crates:

  • moteus-protocol: Low-level protocol encoding/decoding. no_std compatible for embedded use.
  • moteus: High-level API with transport implementations for fdcanusb and SocketCAN.

The simplest way to use moteus is with automatic transport discovery:

use moteus::{BlockingController, command::PositionCommand};

fn main() -> Result<(), moteus::Error> {
    // Auto-discovers transport
    let mut ctrl = BlockingController::new(1)?;

    // Clear any faults
    ctrl.set_stop()?;

    // Command position mode
    loop {
        let result = ctrl.set_position(PositionCommand::new().position(f32::NAN))?;
        println!("Position: {}", result.position);
        std::thread::sleep(std::time::Duration::from_millis(20));
    }
}

§Builder Pattern API

Commands are built using the builder pattern for clear, self-documenting code:

use moteus::command::PositionCommand;

// Simple position command
let cmd = PositionCommand::new().position(0.5);

// Position with velocity
let cmd = PositionCommand::new()
    .position(0.5)
    .velocity(1.0);

// Full control over all parameters
let cmd = PositionCommand::new()
    .position(0.5)
    .velocity(1.0)
    .feedforward_torque(0.1)
    .kp_scale(0.8)
    .kd_scale(1.0)
    .maximum_torque(2.0);

§Explicit Transport

For more control, you can specify a transport explicitly:

use moteus::{BlockingController, Fdcanusb};

fn main() -> Result<(), moteus::Error> {
    // A single-bus convenience transport, ready to hand to a controller.
    let transport = Fdcanusb::open("/dev/fdcanusb")?;
    let mut ctrl = BlockingController::with_transport(1, transport);

    ctrl.set_stop()?;
    Ok(())
}

You can also build a Router over one or more explicit devices:

use moteus::{BlockingController, Router};
use moteus::transport::socketcan::SocketCanDevice;

fn main() -> Result<(), moteus::Error> {
    let transport = Router::from_device(SocketCanDevice::new("can0")?);
    let mut ctrl = BlockingController::with_transport(1, transport);

    ctrl.set_stop()?;
    Ok(())
}

§Transport Options

Configure transport auto-detection with options:

use moteus::{BlockingController, TransportOptions};
use std::time::Duration;

fn main() -> Result<(), moteus::Error> {
    let opts = TransportOptions::new()
        .socketcan_interfaces(vec!["can0"])
        .timeout(Duration::from_millis(200));

    let mut ctrl = BlockingController::with_options(1, &opts)?;
    Ok(())
}

§Low-Level Protocol Access

For embedded or custom transport use cases, the moteus-protocol crate can be used directly to construct and parse CAN-FD frames:

use moteus_protocol::{CanFdFrame, command::{PositionCommand, PositionFormat}};

// Create a position command frame using builder pattern
let mut frame = CanFdFrame::new();
frame.arbitration_id = 0x8001;  // dest=1, source=0

let cmd = PositionCommand::new()
    .position(0.5)
    .velocity(1.0);
cmd.serialize(&mut frame, &PositionFormat::default());

// frame.data and frame.size now contain the encoded command

§Controller Configuration

Use the builder pattern to configure controller settings:

use moteus::{Controller, BlockingController, Resolution};
use moteus::query::QueryFormat;

fn main() -> Result<(), moteus::Error> {
    // Configure a controller with custom settings
    let ctrl = Controller::new(1)
        .source_id(0x10)
        .query_format(QueryFormat::comprehensive());

    // Use with auto-discovered transport
    let ctrl = BlockingController::with_controller(ctrl)?;
    Ok(())
}

§Query Format Overrides

You can override the query format on a per-call basis:

use moteus::command_ext::CommandExt;
use moteus::command::PositionCommand;
use moteus::query::QueryFormat;

// Override query format for this specific call
let cmd = PositionCommand::new()
    .position(0.5)
    .with_query(QueryFormat::comprehensive());

§Resolution Configuration

Control the resolution of commands and queries to optimize bandwidth:

use moteus::{Controller, Resolution};
use moteus_protocol::query::QueryFormat;

let mut ctrl = Controller::new(1);

// Customize query resolution
ctrl.query_format.position = Resolution::Float;
ctrl.query_format.velocity = Resolution::Float;
ctrl.query_format.torque = Resolution::Int16;

§Features

  • serialport: fdcanusb transport support (default)
  • tokio: Async I/O transports and AsyncController (optional)
  • clap: CLI argument parsing support (optional)

§Supported Transports

  • fdcanusb: USB-to-CAN adapter (serial CDC); Linux, Windows, and macOS
  • UART: a moteus connected directly to a TTL serial port (see docs/integration/uart.md); auto-detected when the device path is not a known fdcanusb, with per-frame retries and CRC-8 checksums
  • SocketCAN: Linux kernel CAN interface

§Building with Bazel

tools/bazel build //lib/rust/moteus
tools/bazel test //lib/rust:host

§Versions prior to 0.5.0

Versions of this crate prior to 0.5.0 were developed independently by Omelia Iliffe. The source for those versions can be found at: https://github.com/omelia-iliffe/moteus-rs

Re-exports§

pub use controller::Controller;
pub use device_address::DeviceAddress;
pub use error::Error;
pub use transport::factory::TransportOptions;
pub use transport::Router;
pub use transport::Transport;
pub use transport::convenience::AsyncFdcanusb;
pub use transport::convenience::AsyncSocketCan;
pub use transport::convenience::Fdcanusb;
pub use transport::convenience::SocketCan;

Modules§

command
Command types for moteus motor control.
command_ext
Extension traits for command types to support query format overrides.
command_types
Moteus Command type — a routed protocol message.
controller
Controller API for moteus devices.
device_address
Device addressing for moteus controllers.
diagnostic
Diagnostic stream protocol for moteus controllers.
error
Error types for the moteus client library.
examples
Reusable bodies of the example programs (gated behind the examples feature). See examples for how out-of-tree transports reuse them. Runnable bodies of the example programs, exposed as a library so that downstream binaries can reuse them with a different set of transports.
move_to
Multi-servo coordinated position moves.
query
Query types for reading telemetry from moteus controllers.
transport
Router layer for communicating with moteus controllers.

Structs§

AsyncController
An async controller for a single moteus device.
BlockingController
A blocking controller for a single moteus device.
CanFdFrame
A CAN-FD frame.

Enums§

Mode
The operating mode of a moteus controller.
Register
Registers exposed for reading or writing from a moteus controller.
Resolution
The resolution (data type) used when encoding or decoding a register value.