Skip to main content

Crate moteus_protocol

Crate moteus_protocol 

Source
Expand description

§moteus-protocol

Low-level CAN-FD protocol types for moteus brushless motor controllers.

This crate encodes and decodes the CAN-FD frames used to communicate with moteus controllers. It performs no I/O of its own: you bring the CAN-FD transport, and this crate builds the frames you send and parses the frames you receive.

It is no_std compatible and requires no allocator, so it is usable on embedded systems as well as in standard environments.

Most applications should use the higher-level moteus crate instead, which builds on this one to add blocking and async controllers, transport implementations (fdcanusb, SocketCAN), and device discovery. Reach for moteus-protocol directly when you are on an embedded target or have your own CAN-FD transport.

§Encoding a Command

Commands use a builder pattern, and serialize into a CanFdFrame:

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

// Address servo ID 1 from source ID 0, requesting a reply.
let mut frame = CanFdFrame::new();
frame.arbitration_id = calculate_arbitration_id(0, 1, 0, true);

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

// frame.data and frame.size now contain the encoded command, ready
// to hand to any CAN-FD transport.

§Requesting Telemetry

A query describes which registers the controller should report, and at what resolution. It can be appended to the same frame as a command, or sent on its own:

use moteus_protocol::{CanFdFrame, Resolution};
use moteus_protocol::query::QueryFormat;

let mut frame = CanFdFrame::new();

let mut query = QueryFormat::default();
query.position = Resolution::Float;  // full precision
query.velocity = Resolution::Float;

let expected_reply_size = query.serialize(&mut frame);

§Parsing a Reply

use moteus_protocol::{CanFdFrame, Mode};
use moteus_protocol::query::QueryResult;

// A reply frame as received from the transport.  This one reports the
// mode register as an int8 and the position register as a float.
let mut reply = CanFdFrame::new();
reply.data[..9].copy_from_slice(&[
    0x21, 0x00, 0x0A, // reply int8, register 0x000: Mode = 10 (position)
    0x2D, 0x01, // reply f32, register 0x001: Position
    0x00, 0x00, 0x00, 0x3F, // 0.5f32, little endian
]);
reply.size = 9;

let result = QueryResult::parse(&reply);
assert_eq!(result.mode, Mode::Position);
assert_eq!(result.position, 0.5);

§Key Types

  • CanFdFrame: a raw CAN-FD frame (arbitration ID, payload, flags), independent of any particular transport.
  • command: builder-style command types such as PositionCommand, CurrentCommand, VFOCCommand, StayWithinCommand, StopCommand, and BrakeCommand, with matching *Format resolution descriptions.
  • query::QueryFormat / query::QueryResult: telemetry requests and replies.
  • Register, Mode, Resolution: the moteus register map, operating modes, and wire resolutions.
  • WriteCanData, WriteCombiner, parse_frame: multiplex primitives for reading and writing arbitrary registers.
  • calculate_arbitration_id / parse_arbitration_id: CAN ID routing helpers.

§Building with Bazel

When building from the moteus repository:

tools/bazel build //lib/rust/moteus-protocol

Re-exports§

pub use scaling::Scaling;

Modules§

command
Command types for moteus motor control.
query
Query types for reading telemetry from moteus controllers.
scaling
Scaling constants and functions for moteus register values.

Structs§

CanFdFrame
A CAN-FD frame.
FrameParser
Iterator over subframes in a multiplex protocol frame.
WriteCanData
Writer for appending data to a CAN-FD frame.
WriteCombiner
Combines consecutive register writes of the same resolution for efficiency.

Enums§

HomeState
The homing/rezero state of the controller.
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.
Subframe
A single parsed subframe from a multiplex protocol frame.
SubframeType
The type of a parsed subframe.
Toggle
Toggle state for CAN-FD frame options.
Value
A decoded register value from the multiplex protocol.

Constants§

CLIENT_POLL_SERVER
Tunneled stream: client poll server
CLIENT_TO_SERVER
Tunneled stream: client to server
CURRENT_REGISTER_MAP_VERSION
The current register map version expected from moteus controllers. If the version differs, semantics of one or more registers may have changed.
NOP
No operation
READ_ERROR
Read error
READ_FLOAT
Read Float values
READ_INT8
Read Int8 values
READ_INT16
Read Int16 values
READ_INT32
Read Int32 values
REPLY_FLOAT
Reply Float values
REPLY_INT8
Reply Int8 values
REPLY_INT16
Reply Int16 values
REPLY_INT32
Reply Int32 values
SERVER_TO_CLIENT
Tunneled stream: server to client
WRITE_ERROR
Write error
WRITE_FLOAT
Write Float values
WRITE_INT8
Write Int8 values
WRITE_INT16
Write Int16 values
WRITE_INT32
Write Int32 values

Functions§

calculate_arbitration_id
Computes a moteus CAN arbitration ID from routing fields.
parse_arbitration_id
Extracts routing fields from a moteus CAN arbitration ID.
parse_frame
Creates a parser that iterates over all subframes in a multiplex protocol frame.