Edit on GitHub

Step 1: Moving Dynamixel

NOTE: It assumes that you have already installed the SDK.

Make py file

  • Create a new Python source file Open it with your editor.
    $ touch tutorial_step1.py
    

Check the Port Names

  • Before running the code, check the port name of the connected Dynamixel.
  • For General
    • OpenRB-150: ttyACM0: USB ACM device
    • U2D2: FTDI USB Serial Device converter now attached to ttyUSB0
      $ sudo dmesg | grep tty
      

Source Code Description

from dynamixel_easy_sdk import *

def main():
    connector = Connector("/dev/ttyACM0", 57600)
    motor1 = connector.createMotor(1)

    motor1.disableTorque()
    motor1.setOperatingMode(OperatingMode.POSITION)
    motor1.enableTorque()

    target_position = 500
    motor1.setGoalPosition(target_position)

if __name__ == "__main__":
    main()

Import Library

  • Import dynamixel_easy_sdk.
    from dynamixel_easy_sdk import *
    

Create Connector and Motor Object

  • Create a Connector object with port name and baud rate to manage the communication.
    def main():
        connector = Connector("/dev/ttyACM0", 57600)
    
  • Create a Motor object for each Dynamixel servo you want to control with its ID, using the createMotor method of the Connector class.
        motor1 = connector.createMotor(1)
    

Set Operating Mode to Position Control Mode

  • Use the methods provided by the Motor class to control the Dynamixel servo.
  • Set the operating mode to position control mode.
        motor1.disableTorque()
        motor1.setOperatingMode(OperatingMode.POSITION)
        motor1.enableTorque()
    

Move Motor to Goal Position

  • Move the motor to the goal position that you want.
        target_position = 500
        motor1.setGoalPosition(target_position)
    

Error Handling

  • When an error occurs, DxlRuntimeError is raised.
  • You can catch this error using a try-except block.
    try:
        motor1.setGoalPosition(target_position)
    except DxlRuntimeError as e:
        print(e)
    
  • DxlRuntimeError contains DxlError Enum that provides detailed information about the error.
    try:
        motor1.setGoalPosition(target_position)
    except DxlRuntimeError as e:
        if e.dxl_error == DxlError.EASY_SDK_TORQUE_STATUS_MISMATCH:
            print("Torque is off.")
        elif e.dxl_error == DxlError.EASY_SDK_OPERATING_MODE_MISMATCH:
            print("Operating mode is not position control.")
    

NOTE: It assumes that you have already installed and built the SDK.

Make cpp file

  • Create a new C++ source file Open it with your editor.
    $ touch tutorial_step1.cpp
    

Check the Port Names

  • Before running the code, check the port name of the connected Dynamixel.
  • For General
    • OpenRB-150: ttyACM0: USB ACM device
    • U2D2: FTDI USB Serial Device converter now attached to ttyUSB0
      $ sudo dmesg | grep tty
      

Source Code Description

#include "dynamixel_easy_sdk/dynamixel_easy_sdk.hpp"

int main(){

  dynamixel::Connector connector("/dev/ttyACM0", 57600);
  std::unique_ptr<dynamixel::Motor> motor1 = connector.createMotor(1);

  motor1->disableTorque();
  motor1->setOperatingMode(dynamixel::Motor::OperatingMode::POSITION);
  motor1->enableTorque();

  int target_position = 500;
  motor1->setGoalPosition(target_position);
}

Add Header Files

  • Add dynamixel_easy_sdk/dynamixel_easy_sdk.hpp to the top of your CPP file. This class is included in the Dynamixel SDK package.
    #include "dynamixel_easy_sdk/dynamixel_easy_sdk.hpp"
    

Create Connector and Motor Object

  • Create a Connector object with port name and baud rate to manage the communication.
    int main(){
      dynamixel::Connector connector("/dev/ttyACM0", 57600);
    
  • Create a Motor object for each Dynamixel servo you want to control, using the createMotor method of the Connector class.
  • This method takes the motor ID as an argument and returns a unique pointer to a Motor instance. (shared_ptr is also available)
      std::unique_ptr<dynamixel::Motor> motor1 = connector.createMotor(1);
    
  • This process throws a DxlRuntimeError if the object creation fails.

Set Operating Mode to Position Control Mode

  • Use the methods provided by the Motor class to control the Dynamixel servo.
  • Set the operating mode to position control mode.
      motor1->disableTorque();
      motor1->setOperatingMode(dynamixel::Motor::OperatingMode::POSITION);
      motor1->enableTorque();
    

Move Motor to Goal Position

  • Move the motor to the goal position that you want.
      int target_position = 500;
      motor1->setGoalPosition(target_position);
    

Error Handling

  • To ensure your code is robust, every method that sends a command to the motor returns a Result object that encapsulates errors.
  • This object lets you safely check for any communication or device errors before proceeding.
  • You can check for communication errors and device(dynamixel) errors using the Result object.

    Example

      auto result_void = motor1->disableTorque(); // type of 'result_void' variable is Result<void, DxlError>
      if (!result_void.isSuccess()) {
        std::cerr << dynamixel::getErrorMessage(result_void.error()) << std::endl;
        return 1;
      }
    

Compile and Run

  • You can compile and run the code using the following commands
    $ g++ tutorial_step1.cpp -o tutorial_step1 -l dxl_x64_cpp
    $ ./tutorial_step1
    

Full Source Code With Error Handling

#include "dynamixel_easy_sdk/dynamixel_easy_sdk.hpp"

int main(){
  dynamixel::Connector connector("/dev/ttyACM0", 57600);
  std::unique_ptr<dynamixel::Motor> motor1 = connector.createMotor(1);

  auto result_void = motor1->disableTorque(); // type of 'result_void' variable is Result<void, DxlError>
  if (!result_void.isSuccess()) {
    std::cerr << dynamixel::getErrorMessage(result_void.error()) << std::endl;
    return 1;
  }

  result_void = motor1->setOperatingMode(dynamixel::Motor::OperatingMode::POSITION);
  if (!result_void.isSuccess()) {
    std::cerr << dynamixel::getErrorMessage(result_void.error()) << std::endl;
    return 1;
  }

  result_void = motor1->enableTorque();
  if (!result_void.isSuccess()) {
    std::cerr << dynamixel::getErrorMessage(result_void.error()) << std::endl;
    return 1;
  }

  int target_position = 500;
  result_void = motor1->setGoalPosition(target_position);
  if (!result_void.isSuccess()) {
    std::cerr << dynamixel::getErrorMessage(result_void.error()) << std::endl;
    return 1;
  }
}