dynamixel-community / dynamixel_hardware

ros2_control packages for ROBOTIS Dynamixel
Apache License 2.0
117 stars 57 forks source link

Can this hardware library be used with wheeled robot? #18

Closed robofoundry closed 2 years ago

robofoundry commented 2 years ago

First of all, pretty awesome library. I tried to use this lib for a wheeled robot with foxy + ros2_control and standard diff_drive_controller but had some issues with it. Can this be used with wheeled robot in Velocity control mode or will it have to be modified to work with it? And what changes you would suggest. Thanks.

youtalk commented 2 years ago

Thank you for using the dynamixel_control. I haven't used it with wheeled robot but I hope you can do it without any modification. Please show me the log.

robofoundry commented 2 years ago

I was able to troubleshoot the issue and it actually works with some minor changes:

  1. Main issue was ros2_control diff_drive_controller continuously sends linear and angular velocities of 0 when the cmd_vel timeout is detected when you let go of joystick. So when you are moving the robot around, it works fine but it never stops the robot due to the if statement in line 286, of write method, which only goes into that logic if velocity != 0. So I had to comment that if statement so the robot will stop when 0 velocities are sent by the diff_drive_controller.
// commented if statement to allow robot to receive 0 velocity from diff_drive_controller
286 //if (std::any_of(
//        joints_.cbegin(), joints_.cend(), [](auto j) { return j.command.velocity != 0.0; })) {
    // Velocity control
   // line below is also not necessary to call every time if the robot is only used in velocity control mode and it is set during configure method
    set_control_mode(ControlMode::Velocity); 
    for (uint i = 0; i < ids.size(); i++) {
      commands[i] = dynamixel_workbench_.convertVelocity2Value(
        ids[i], static_cast<float>(joints_[i].command.velocity));
    }
    if (!dynamixel_workbench_.syncWrite(
          kGoalVelocityIndex, ids.data(), ids.size(), commands.data(), 1, &log)) {
      RCLCPP_ERROR(rclcpp::get_logger(kDynamixelHardware), "%s", log);
    }
    return return_type::OK;
 // }
  1. Optional change 1 - since I'm using the robot in wheel mode/velocity mode, I commented out position control code in write method as it is not being used. This change is not required for the fix.
  2. Optional change 2 - in header file I set the default control mode to velocity mode instead of position control. This change is also not required for the fix. ControlMode control_mode_{ControlMode::Velocity};

Alternatively, you can set the default mode velocity control in line 93 of on_init method:

  enable_torque(false);
93  set_control_mode(ControlMode::Velocity, true);
  enable_torque(true);

I also ran into issues related to dynamixel speed not working correctly but those issues were fixed by tuning the diff_drive_controller config file parameters and had nothing to do with hardware interface code.

Thanks again for such a quick response and hope this helps someone else.

youtalk commented 2 years ago

Nice report. Thank you!