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

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

§Supported Transports

  • fdcanusb: USB-to-CAN adapter (serial CDC)
  • 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::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.
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§

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.