17 #ifndef STEPPER_DRIVER_HPP
18 #define STEPPER_DRIVER_HPP
25 #include "ros/duration.h"
37 template <
typename reg_type = StepperReg>
41 StepperDriver(std::shared_ptr<dynamixel::PortHandler> portHandler,
42 std::shared_ptr<dynamixel::PacketHandler> packetHandler);
46 std::string
str()
const override;
52 int readVoltage(uint8_t
id,
double &voltage)
override;
55 int syncReadFirmwareVersion(
const std::vector<uint8_t> &id_list, std::vector<std::string> &firmware_list)
override;
56 int syncReadTemperature(
const std::vector<uint8_t> &id_list, std::vector<uint8_t> &temperature_list)
override;
57 int syncReadVoltage(
const std::vector<uint8_t> &id_list, std::vector<double> &voltage_list)
override;
58 int syncReadRawVoltage(
const std::vector<uint8_t> &id_list, std::vector<double> &voltage_list)
override;
59 int syncReadHwStatus(
const std::vector<uint8_t> &id_list, std::vector<std::pair<double, uint8_t>> &data_list)
override;
61 int syncReadHwErrorStatus(
const std::vector<uint8_t> &id_list, std::vector<uint8_t> &hw_error_list)
override;
68 int changeId(uint8_t
id, uint8_t new_id)
override;
77 int syncWriteTorquePercentage(
const std::vector<uint8_t> &id_list,
const std::vector<uint8_t> &torque_percentage_list)
override;
78 int syncWritePositionGoal(
const std::vector<uint8_t> &id_list,
const std::vector<uint32_t> &position_list)
override;
79 int syncWriteVelocityGoal(
const std::vector<uint8_t> &id_list,
const std::vector<uint32_t> &velocity_list)
override;
82 int readPosition(uint8_t
id, uint32_t &present_position)
override;
83 int readVelocity(uint8_t
id, uint32_t &present_velocity)
override;
85 int syncReadPosition(
const std::vector<uint8_t> &id_list, std::vector<uint32_t> &position_list)
override;
86 int syncReadVelocity(
const std::vector<uint8_t> &id_list, std::vector<uint32_t> &velocity_list)
override;
87 int syncReadJointStatus(
const std::vector<uint8_t> &id_list, std::vector<std::array<uint32_t, 2>> &data_array_list)
override;
98 int writeHomingSetup(uint8_t
id, uint8_t direction, uint8_t stall_threshold)
override;
101 int syncReadHomingStatus(
const std::vector<uint8_t> &id_list, std::vector<uint8_t> &status_list)
override;
112 int writeA1(uint8_t
id, uint32_t a_1);
113 int writeV1(uint8_t
id, uint32_t v_1);
114 int writeAMax(uint8_t
id, uint32_t a_max);
115 int writeVMax(uint8_t
id, uint32_t v_max);
116 int writeDMax(uint8_t
id, uint32_t d_max);
117 int writeD1(uint8_t
id, uint32_t d_1);
126 template <
typename reg_type>
128 std::shared_ptr<dynamixel::PacketHandler> packetHandler) :
AbstractStepperDriver(std::move(portHandler),
129 std::move(packetHandler))
141 template <
typename reg_type>
153 template <
typename reg_type>
158 int res = write<typename reg_type::TYPE_ID>(reg_type::ADDR_ID,
id, new_id);
159 if (res == COMM_RX_TIMEOUT)
169 template <
typename reg_type>
172 uint16_t model_number = 0;
173 int ping_result = getModelNumber(
id, model_number);
175 if (ping_result == COMM_SUCCESS)
177 if (model_number && model_number != reg_type::MODEL_NUMBER)
179 return PING_WRONG_MODEL_NUMBER;
192 template <
typename reg_type>
197 res = read<typename reg_type::TYPE_FIRMWARE_VERSION>(reg_type::ADDR_FIRMWARE_VERSION,
id, data);
198 version = interpretFirmwareVersion(data);
208 template <
typename reg_type>
211 return read<typename reg_type::TYPE_MIN_POSITION_LIMIT>(reg_type::ADDR_MIN_POSITION_LIMIT,
id, pos);
220 template <
typename reg_type>
223 return read<typename reg_type::TYPE_MAX_POSITION_LIMIT>(reg_type::ADDR_MAX_POSITION_LIMIT,
id, pos);
234 template <
typename reg_type>
237 auto torque_enable = torque_percentage > 0 ? 1 : 0;
238 return write<typename reg_type::TYPE_TORQUE_ENABLE>(reg_type::ADDR_TORQUE_ENABLE,
id, torque_enable);
247 template <
typename reg_type>
250 return write<typename reg_type::TYPE_GOAL_POSITION>(reg_type::ADDR_GOAL_POSITION,
id, position);
260 template <
typename reg_type>
263 return write<typename reg_type::TYPE_GOAL_VELOCITY>(reg_type::ADDR_GOAL_VELOCITY,
id, velocity);
272 template <
typename reg_type>
275 std::vector<uint8_t> torque_enable_list;
276 for(
const auto &torque_percentage : torque_percentage_list)
278 auto torque_enable = torque_percentage > 0 ? 1 : 0;
279 torque_enable_list.push_back(torque_enable);
281 return syncWrite<typename reg_type::TYPE_TORQUE_ENABLE>(reg_type::ADDR_TORQUE_ENABLE, id_list, torque_enable_list);
290 template <
typename reg_type>
293 return syncWrite<typename reg_type::TYPE_GOAL_POSITION>(reg_type::ADDR_GOAL_POSITION, id_list, position_list);
302 template <
typename reg_type>
305 return syncWrite<typename reg_type::TYPE_GOAL_VELOCITY>(reg_type::ADDR_GOAL_VELOCITY, id_list, velocity_list);
316 template <
typename reg_type>
319 return read<typename reg_type::TYPE_PRESENT_POSITION>(reg_type::ADDR_PRESENT_POSITION,
id, present_position);
328 template <
typename reg_type>
331 return read<typename reg_type::TYPE_PRESENT_VELOCITY>(reg_type::ADDR_PRESENT_VELOCITY,
id, present_velocity);
340 template <
typename reg_type>
343 return read<typename reg_type::TYPE_PRESENT_TEMPERATURE>(reg_type::ADDR_PRESENT_TEMPERATURE,
id, temperature);
352 template <
typename reg_type>
355 uint16_t voltage_mV = 0;
356 int res = read<typename reg_type::TYPE_PRESENT_VOLTAGE>(reg_type::ADDR_PRESENT_VOLTAGE,
id, voltage_mV);
357 voltage =
static_cast<double>(voltage_mV) / reg_type::VOLTAGE_CONVERSION;
367 template <
typename reg_type>
370 return read<typename reg_type::TYPE_HW_ERROR_STATUS>(reg_type::ADDR_HW_ERROR_STATUS,
id, hardware_error_status);
379 template <
typename reg_type>
382 return syncRead<typename reg_type::TYPE_PRESENT_POSITION>(reg_type::ADDR_PRESENT_POSITION, id_list, position_list);
391 template <
typename reg_type>
394 return syncRead<typename reg_type::TYPE_PRESENT_VELOCITY>(reg_type::ADDR_PRESENT_VELOCITY, id_list, velocity_list);
404 template <
typename reg_type>
406 std::vector<std::array<uint32_t, 2>> &data_array_list)
408 int res = COMM_TX_FAIL;
413 data_array_list.clear();
416 typename reg_type::TYPE_TORQUE_ENABLE torque{1};
417 res = read<typename reg_type::TYPE_TORQUE_ENABLE>(reg_type::ADDR_TORQUE_ENABLE, id_list.at(0), torque);
418 if (COMM_SUCCESS != res)
419 std::cout <<
"#############"
420 " ERROR reading stepper torque in syncReadJointStatus (error "
421 << res <<
")" << std::endl;
426 res = syncReadConsecutiveBytes<uint32_t, 2>(reg_type::ADDR_PRESENT_VELOCITY, id_list, data_array_list);
430 std::vector<uint32_t> position_list;
431 res = syncReadPosition(id_list, position_list);
432 for (
auto p : position_list)
433 data_array_list.emplace_back(std::array<uint32_t, 2>{1, p});
445 template <
typename reg_type>
449 firmware_list.clear();
450 std::vector<uint32_t> data_list{};
451 res = syncRead<typename reg_type::TYPE_FIRMWARE_VERSION>(reg_type::ADDR_FIRMWARE_VERSION, id_list, data_list);
452 for (
auto const &data : data_list)
453 firmware_list.emplace_back(interpretFirmwareVersion(data));
463 template <
typename reg_type>
466 return syncRead<typename reg_type::TYPE_PRESENT_TEMPERATURE>(reg_type::ADDR_PRESENT_TEMPERATURE, id_list, temperature_list);
475 template <
typename reg_type>
478 voltage_list.clear();
479 std::vector<uint16_t> v_read;
480 int res = syncRead<typename reg_type::TYPE_PRESENT_VOLTAGE>(reg_type::ADDR_PRESENT_VOLTAGE, id_list, v_read);
481 for (
auto const &v : v_read)
482 voltage_list.emplace_back(
static_cast<double>(v) / reg_type::VOLTAGE_CONVERSION);
492 template <
typename reg_type>
495 voltage_list.clear();
496 std::vector<uint16_t> v_read;
497 int res = syncRead<typename reg_type::TYPE_PRESENT_VOLTAGE>(reg_type::ADDR_PRESENT_VOLTAGE, id_list, v_read);
498 for (
auto const &v : v_read)
499 voltage_list.emplace_back(
static_cast<double>(v));
509 template <
typename reg_type>
511 std::vector<std::pair<double, uint8_t>> &data_list)
515 std::vector<std::array<uint8_t, 3>> raw_data;
516 int res = syncReadConsecutiveBytes<uint8_t, 3>(reg_type::ADDR_PRESENT_VOLTAGE, id_list, raw_data);
518 for (
auto const &data : raw_data)
521 auto v =
static_cast<uint16_t
>((
static_cast<uint16_t
>(data.at(1)) << 8) | data.at(0));
522 auto voltage =
static_cast<double>(v);
525 uint8_t temperature = data.at(2);
527 data_list.emplace_back(std::make_pair(voltage, temperature));
538 template <
typename reg_type>
541 return syncRead<typename reg_type::TYPE_HW_ERROR_STATUS>(reg_type::ADDR_HW_ERROR_STATUS, id_list, hw_error_list);
548 template <
typename reg_type>
551 return read<typename reg_type::TYPE_OPERATING_MODE>(reg_type::ADDR_OPERATING_MODE,
id, operating_mode);
554 template <
typename reg_type>
557 return write<typename reg_type::TYPE_OPERATING_MODE>(reg_type::ADDR_OPERATING_MODE,
id, operating_mode);
566 template <
typename reg_type>
569 int res = COMM_RX_FAIL;
572 std::vector<std::array<typename reg_type::TYPE_PROFILE, 8>> data_array_list;
573 if (COMM_SUCCESS == syncReadConsecutiveBytes<typename reg_type::TYPE_PROFILE, 8>(reg_type::ADDR_VSTART, {
id}, data_array_list))
575 if (!data_array_list.empty())
577 auto block = data_array_list.at(0);
579 for (
auto data : block)
581 data_list.emplace_back(data);
589 std::cout <<
"Failures during read Velocity Profile" << std::endl;
602 template <
typename reg_type>
606 int res = COMM_RX_FAIL;
607 double wait_duration = 0.05;
610 constexpr
auto ACTIVE_TORQUE_PERCENT = 1;
611 writeTorquePercentage(
id, ACTIVE_TORQUE_PERCENT);
617 ros::Duration(wait_duration).sleep();
618 res = writeVStart(
id, data_list.at(0));
619 if (res == COMM_SUCCESS)
622 if (res != COMM_SUCCESS)
629 ros::Duration(wait_duration).sleep();
630 res = writeA1(
id, data_list.at(1));
631 if (res == COMM_SUCCESS)
634 if (res != COMM_SUCCESS)
641 ros::Duration(wait_duration).sleep();
642 res = writeV1(
id, data_list.at(2));
643 if (res == COMM_SUCCESS)
646 if (res != COMM_SUCCESS)
653 ros::Duration(wait_duration).sleep();
654 res = writeAMax(
id, data_list.at(3));
655 if (res == COMM_SUCCESS)
658 if (res != COMM_SUCCESS)
665 ros::Duration(wait_duration).sleep();
666 res = writeVMax(
id, data_list.at(4));
667 if (res == COMM_SUCCESS)
670 if (res != COMM_SUCCESS)
677 ros::Duration(wait_duration).sleep();
678 res = writeDMax(
id, data_list.at(5));
679 if (res == COMM_SUCCESS)
682 if (res != COMM_SUCCESS)
689 ros::Duration(wait_duration).sleep();
690 res = writeD1(
id, data_list.at(6));
691 if (res == COMM_SUCCESS)
694 if (res != COMM_SUCCESS)
701 ros::Duration(wait_duration).sleep();
702 res = writeVStop(
id, data_list.at(7));
703 if (res == COMM_SUCCESS)
715 template <
typename reg_type>
718 return write<typename reg_type::TYPE_COMMAND>(reg_type::ADDR_COMMAND,
id, 0);
729 template <
typename reg_type>
733 double wait_duration = 0.05;
736 constexpr
auto ACTIVE_TORQUE_PERCENT = 1;
737 writeTorquePercentage(
id, ACTIVE_TORQUE_PERCENT);
738 ros::Duration(wait_duration).sleep();
740 if (COMM_SUCCESS != write<typename reg_type::TYPE_HOMING_DIRECTION>(reg_type::ADDR_HOMING_DIRECTION,
id, direction))
742 ros::Duration(wait_duration).sleep();
750 std::cout <<
"Failures during writeVelocityProfile : " << res << std::endl;
763 template <
typename reg_type>
766 return read<typename reg_type::TYPE_HOMING_STATUS>(reg_type::ADDR_HOMING_STATUS,
id, status);
775 template <
typename reg_type>
778 return syncRead<typename reg_type::TYPE_HOMING_STATUS>(reg_type::ADDR_HOMING_STATUS, id_list, status_list);
787 template <
typename reg_type>
790 typename reg_type::TYPE_FIRMWARE_RUNNING data{};
791 int res = read<typename reg_type::TYPE_FIRMWARE_RUNNING>(reg_type::ADDR_FIRMWARE_RUNNING,
id, data);
802 template <
typename reg_type>
805 return syncWrite<typename reg_type::TYPE_HOMING_ABS_POSITION>(reg_type::ADDR_HOMING_ABS_POSITION, id_list, abs_position);
814 template <
typename reg_type>
817 return syncRead<typename reg_type::TYPE_HOMING_ABS_POSITION>(reg_type::ADDR_HOMING_ABS_POSITION, id_list, abs_position);
828 template <
typename reg_type>
831 return write<typename reg_type::TYPE_PROFILE>(reg_type::ADDR_VSTART,
id, v_start);
840 template <
typename reg_type>
843 return write<typename reg_type::TYPE_PROFILE>(reg_type::ADDR_A1,
id, a_1);
852 template <
typename reg_type>
855 return write<typename reg_type::TYPE_PROFILE>(reg_type::ADDR_V1,
id, v_1);
864 template <
typename reg_type>
867 return write<typename reg_type::TYPE_PROFILE>(reg_type::ADDR_AMAX,
id, a_max);
876 template <
typename reg_type>
879 return write<typename reg_type::TYPE_PROFILE>(reg_type::ADDR_VMAX,
id, v_max);
888 template <
typename reg_type>
891 return write<typename reg_type::TYPE_PROFILE>(reg_type::ADDR_DMAX,
id, d_max);
900 template <
typename reg_type>
903 return write<typename reg_type::TYPE_PROFILE>(reg_type::ADDR_D1,
id, d_1);
912 template <
typename reg_type>
915 return write<typename reg_type::TYPE_PROFILE>(reg_type::ADDR_VSTOP,
id, v_stop);
918 template <
typename reg_type>
921 return reg_type::VELOCITY_UNIT;
926 #endif // STEPPER_DRIVER_HPP