ODrive Robotics Documentation

repository·master·Indexed 24 days ago

https://github.com/odriverobotics/odrive

High-performance, low-cost brushless motor control for robotics. This documentation covers firmware for ODrive v3.x hardware, the ODriveArduino library, the fibre-cpp communication framework, fibre-js for web applications, and the ODrive GUI. It includes guides on analog input configuration via GPIO, PyFibre Python bindings, and connectivity options via USB, UART, and CAN protocol.

Tokens
27.6K
Snippets
85
Records
182
Agent score
67%

What's inside ODrive

  1. Choose an integration approach for fibre-cpp

    master

    There are two ways to integrate Fibre into your project depending on your target platform:

    1. Embedding fibre-cpp (Recommended for embedded systems): Include the fibre-cpp source code directly in your application's build process. This allows you to use the C++ API to interact with Fibre.

    2. Linking to libfibre (Recommended for desktop systems): Link against a precompiled libfibre library and use the C API. This approach is easier for desktop environments as it avoids managing build dependencies.

    Note: When linking to libfibre, only the client role is currently supported (you can discover and access remote objects, but cannot expose local objects).

  2. Understand the ODrive Communication Protocol

    master

    Communication with an ODrive is performed via endpoint operations. Each operation sends bytes to an endpoint ID and can optionally receive bytes from that same endpoint.

    Key concepts:

    • Endpoints: Available endpoints can be discovered by reading the JSON definition from endpoint 0. The JSON defines the IDs and types of all available endpoints.
    • Serialization: POD (Plain Old Data) types have a default little-endian serialization. For custom types, you must handle (de)serialization manually.
    • Exchange Semantics: For combined read/write requests, the convention is an exchange, where the returned value is the old value.
    • Protocol Variants:
      • Packet-based: Used by default for USB.
      • Stream-based: Used by default for UART.
    • Client/Server Model: The PC acts as the client (sending requests) and the ODrive acts as the server (sending responses).
  3. Understand ODrive USB device composition

    master

    The ODrive presents itself as a single USB configuration containing a composite device. This means it provides two distinct interface groups that can be treated as separate devices by the host OS.

    Note: The two interfaces cannot be used simultaneously.

  4. Check firmware compatibility for ODrive hardware

    master

    The firmware in this repository is specifically compatible with ODrive v3.x (NRND). It is no longer under active development.

    If you are using newer generation hardware such as ODrive Pro, S1, or Micro, this repository's firmware is not the correct version. The source code for newer hardware is not publicly available, though access may be requested via NDA through the ODrive team.

  5. Understand the ODrive Cascaded Control Structure

    master

    The ODrive motor controller uses a cascaded control loop architecture consisting of Position, Velocity, and Current stages. The behavior changes based on the selected control mode:

    • Position Control Mode: The full cascaded loop (Position $\rightarrow$ Velocity $\rightarrow$ Current) is active.
    • Velocity Control Mode: The position control stage is bypassed; the velocity command is fed directly into the velocity controller.
    • Torque (Current) Control Mode: Only the current controller is used.

    Note: The controller uses torque in Newton-meters at the system level. The torque_constant parameter is used to convert between torque and current.

  6. Avoid CANOpen conflicts with CAN Simple

    master

    To prevent collisions with CANOpen devices, you can reserve specific message ranges by choosing specific Node IDs.

    For example, setting a Node ID of 0x010 reserves messages 0x200 through 0x21F.

    To ensure compatibility, if you use CANOpen, ensure all CANOpen node IDs are $\ge 32$. This guarantees that the resulting CANOpen receive PDO addresses (e.g., 0x200 + nodeID) will not fall into the range reserved for CAN Simple nodes.

  7. Enable closed loop control for a motor

    master

    To start closed loop control (where the ODrive attempts to hold the motor's position), set the axis requested_state to AXIS_STATE_CLOSED_LOOP_CONTROL.

    Note that the motor's resistance to manual movement is determined by odrv0.axis0.motor.config.current_lim. If the motor vibrates, you may need to lower the controller gains.

    odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL
  8. Use Circular Position Control for continuous rotation

    master

    Circular position control is designed for applications requiring continuous incremental movement (e.g., conveyors, extruders, or robots rolling indefinitely). It prevents floating-point precision loss by wrapping the input_pos within a specific range.

    Key Details:

    • By default, input_pos is expected in the range [0, 1).
    • If input_pos exceeds the range, it automatically wraps around.
    • Uses encoder.pos_circular for feedback instead of encoder.pos_estimate.
    • If a single step exceeds the circular range, the motor may rotate the long way around.
    • You can increase the circular range using circular_setpoints_range.
  9. Use Filtered Position Control to reduce jerky movement

    master

    If raw position setpoints cause jerky movement (common when using low-frequency external trajectories), you can use a second-order position filter. A good starting point for the filter bandwidth is one half of your setpoint command rate.

    To use this mode:

    1. Set the input_filter_bandwidth [Hz].
    2. Set input_mode to INPUT_MODE_POS_FILTER.
    3. Provide setpoints via input_pos.