Edit on GitHub

Step 2: Read Data from 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_step2.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)

    present_position = motor1.getPresentPosition()
    print("Present Position:", present_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)
    

Get Present Position

  • You can read the present position of the motor using the getPresentPosition method.
        present_position = motor1.getPresentPosition()
        print("Present Position:", present_position)
    

Error Handling

  • When an error occurs, DxlRuntimeError is raised.
  • You can catch this error using a try-except block.
    try:
        motor1.getPresentPosition()
    except DxlRuntimeError as e:
        print(e)
    
  • DxlRuntimeError contains DxlError Enum that provides detailed information about the error.
    try:
        motor1.getPresentPosition()
    except DxlRuntimeError as e:
        if e.dxl_error == DxlError.SDK_COMM_TX_FAIL:
            print("Transmission failed.")
        elif e.dxl_error == DxlError.SDK_COMM_RX_FAIL:
            print("Receive failed.")
    

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_step2.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);

  auto result_int32_t = motor1->getPresentPosition();
  int present_position = result_int32_t.value();
  std::cout << "Present Position: " << present_position << std::endl;
}

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.

Get Present Position

  • You can read the present position of the motor using the getPresentPosition method.
  • Return type of this method is Result<int32_t, Error>. You can get the actual position value using the value() method of the Result object.
      auto result_int32_t = motor1->getPresentPosition();
      int present_position = result_int32_t.value();
      std::cout << "Present Position: " << present_position << std::endl;
    }
    

Error Handling

  • To ensure your code is robust, every method that sends a command to the motor returns a Result object that encapsulates values and 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.
  • If you use value() when error occurred without checking for errors, it may throw an exception.

    Example

      auto result_int32_t = motor1->getPresentPosition();
      if (!result_int32_t.isSuccess()) {
        std::cerr << dynamixel::getErrorMessage(result_int32_t.error()) << std::endl;
        return 1;
      }
      int present_position = result_int32_t.value();
    

Compile and Run

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

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_int32_t = motor1->getPresentPosition();
  if (!result_int32_t.isSuccess()) {
    std::cerr << dynamixel::getErrorMessage(result_int32_t.error()) << std::endl;
    return 1;
  }
  int present_position = result_int32_t.value();
  std::cout << "Present Position: " << present_position << std::endl;
}