Skip to main content

roboflex.dynamixel

Support for Robotis' Dynamixel motor product line. Some of it anyway (tested on XH430-V350-R, XH430-W350, XM540-W270, XL-330-M288-T, others may work as well).

We provide two layers to controlling dynamixel motors:

  • dynamixel_controller.h defines DynamixelGroupController: a controller for a group of dynamixels connected together (following Robotis' instructions), which uses no message passing or other roboflex functionality at all.
  • dynamixel.h, which defines helper classes to control the above, using roboflex.

DynamixelGroupController (see dynamixel_controller.h)

Controls a group of dynamixel motors, connected together according to Robotis' instructions, to create robot arms, pan-tilt controllers, and other robots. The DynamixelGroupController abstracts the repetitive part of the communication with the motors, and provides a convenient class that can control a group of motors through a callback function: a 'ReadWriteLoop' function. It calls this function synchronously with communication with the dynamixel motors, as fast as the interface can manage, depending on configured baud rate (think > 100hz).

This code is completely stand-alone; it uses nothing from roboflex.

Each dynamixel can have its own independent operation mode (current, position, velocity, etc), but this class makes it particularly easy to control groups of motors all in the same mode; see the constructors and static methods of DynamixelGroupController in dynamixel_controller.h.

Unless using the PositionController or VelocityController methods to instantiate a controller, the client must decide which control table entries to read and which to write. In general, you can write to the control table entries that are named DXLControlTable::Goal*, and read everything else. Refer to Robotis documentation for details.

The controller automatically paces its read/write loop based on the configured baud rate and the amount of data requested per cycle. If you need to tune this, call set_loop_sleep_ms() (to force a specific delay per cycle) or set_servo_processing_margin_ms() (to tweak the margin the controller adds after each write). Both getters are exposed so you can inspect the calculated values at runtime.

Roboflex additions (see dynamixel.h)

This layer defines additional functionality to integrate with roboflex-style message passing. It defines Messages that encapsulate State and Command types, and several useful nodes.

The first of these is DynamixelGroupControllerNode. This Node sub-class adapts the non-roboflex 'business logic' of DynamixelGroupController to the roboflex paradigm by configuration - you give this Node an instance of a DynamixelGroupController. This Node performs three functions:

  1. Adapts DynamixelGroupController's control loop to the roboflex threading model: in child_thread_fn, it calls run_readwrite_loop on the controller. When stop is called on this Node, it stops the thread.

  2. Provides a simple, overrideable abstract method to actually perform the control: the user should subclass this class and override:

     virtual DXLIdsToValues readwrite_loop_function(
         const DynamixelGroupState& state,
         const core::MessagePtr last_msg) 
     {
         return DXLIdsToValues{ 
             5: {DXLControlTable::GoalVelocity: 12 },
             6: {DXLControlTable::GoalVelocity: 2 }
         }
     }
    
     # in python:
    
     def readwrite_loop_function(state, last_msg):
         # use state and last_msg as you wish
         return {
             5: {DXLControlTable.GoalVelocity: 12 },
             6: {DXLControlTable.GoalVelocity: 2 }
         }
    
     # In both of these cases, this means you want to set the goal velocity of
     # dynamixel motor with id 5 to 12, and motor 6 to 2.
    
  3. Provides basic message handling. It will:

    3.1. Save the most recent message. You can use this to send in, for instance, some new position or velocity you want to move the motors to. This Node's control loop might be operating at a different frequency that the incoming messages - it should still work.

    3.2. Broadcast the state and command (your command values) sent to the motor group at every loop cycle, in the form of a DynamixelCommandStateMessage.

Messages

DynamixelCommandStateMessage:

Encapsulates the a state and command of the dynamixel group. Used to communicate the last-known state of the motors, and last-known command sent to the motors. Serializes this schema to flexbuffers:

{
    ...
    "state": {                  # the present state of the group of motors:
        5: {                    # motor with id 5
            128: 2,             # has present velocity = 2
            132: 204,           # has present position = 204
        },
        6: {                    # motor with id 6, etc.
            128: 12,
            132: 301,
        }
    }
    "command": {                # the last-known command you sent
        5: {104: 4},            # motor with id 5 should get goal velocity = 4
        6: {104: 5}             # motor with id 6 should get goal velocity = 5
    }
    "t0": 170002032.2122312,    # time just before communication with motor
    "t1": 170002032.2283432,    # time just after communication with motor
}

For more 'distributed' operation:

The second of these is DynamixelGroupNode. This node inherits RunnableNode; it is designed to be started and stopped. When instantiated, this node must be given an instance of a DynamixelGroupController. When started, it runs a ReadWriteLoopFunction on that instance inside its run_readwrite_loop method, using the last known GroupCommandMessage it has received, and then emits a GroupStateMessage.

We also provided DynamixelRemoteController. This is an abstract base class that requires implementation of the 'readwrite_loop_function' virtual method. Here is where your custom control logic would go. The benefit of this approach is that the DynamixelGroupNode can run in its own thread, and keep up with the motors. This node, then, can be run from anywhere, and using transport classes, the controller can even run on a totally separate computer.

We also provide DynamixelRemoteFrequencyController, which is exactly the same, but is driven at some frequency from a thread via inheritance from FrequencyGenerator.

Troubleshooting

You might benefit from the Robotis Dynamixel Wizard program - just google for it.

If you can't access /dev/ttyUSB0, try this:

sudo usermod -a -G dialout $USER
sudo reboot

Metadata

Release files for roboflex.dynamixel 0.1.24

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for roboflex.dynamixel 0.1.24
File Size Uploaded
roboflex_dynamixel-0.1.24.tar.gz 27.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for roboflex.dynamixel 0.1.24
File Interpreter ABI Platform
roboflex_dynamixel-0.1.24-cp311-cp311-macosx_15_0_arm64.whl CPython 3.11 CPython 3.11 macOS 15.0+ ARM64 Details

Total release size: 412.7 kB

Release files / roboflex_dynamixel-0.1.24.tar.gz

Download URL roboflex_dynamixel-0.1.24.tar.gz
Size 27.5 kB
Tags Source
SHA-256 checksum
How to use checksums
d32b2c52dc59eaac12c32195b6a3b1f42955392b499f91f799534bd6bb4fc1ab
BLAKE2b-256 checksum
How to use checksums
ef6bf3161fa7d59eb712bd261613179e23dd729f3b13e8bc5227ff076adac782
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.5

Release files / roboflex_dynamixel-0.1.24-cp311-cp311-macosx_15_0_arm64.whl

Download URL roboflex_dynamixel-0.1.24-cp311-cp311-macosx_15_0_arm64.whl
Size 385.2 kB
Tags CPython 3.11 macOS 15.0+ ARM64
SHA-256 checksum
How to use checksums
331d1c7ef2bf1d363f7b751ef05bf878fce25ac77f1e30ba2b26f6d8fd602ebe
BLAKE2b-256 checksum
How to use checksums
69e8e02089afd792ad746aec74e88bd5ec163806a09751258bc7d6e6e1ab55ee
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.5

Release history Release notifications | RSS feed

This release

0.1.24 This release

2 release files

0.1.23

2 release files

0.1.22

2 release files

0.1.21

2 release files

0.1.20

2 release files

0.1.19

2 release files

0.1.18

2 release files

0.1.17

2 release files

0.1.16

1 release file

0.1.15

1 release file

0.1.14

1 release file

0.1.13

1 release file

0.1.12

1 release file

0.1.11

1 release file

0.1.10

1 release file

0.1.9

1 release file

0.1.8

1 release file

0.1.7

1 release file

0.1.6

1 release file

0.1.5

1 release file

0.1.4

1 release file

0.1.3

1 release file

0.1.2

1 release file

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page