28 #include <unordered_map>
33 #include "ros/serialization.h"
37 #include "common/model/dxl_command_type_enum.hpp"
38 #include "common/model/end_effector_state.hpp"
39 #include "common/model/hardware_type_enum.hpp"
40 #include "common/model/stepper_calibration_status_enum.hpp"
41 #include "common/model/stepper_motor_state.hpp"
42 #include "common/model/tool_state.hpp"
45 #include "dynamixel_sdk/packet_handler.h"
58 #include "ttl_driver/CalibrationStatus.h"
60 using ::std::ostringstream;
62 using ::std::shared_ptr;
64 using ::std::to_string;
67 using ::common::model::EHardwareType;
68 using ::common::model::EndEffectorState;
69 using ::common::model::EStepperCalibrationStatus;
70 using ::common::model::HardwareTypeEnum;
71 using ::common::model::JointState;
72 using ::common::model::StepperMotorState;
73 using ::common::model::ConveyorState;
80 TtlManager::TtlManager(ros::NodeHandle &
nh) : _nh(
nh), _debug_error_message(
"TtlManager - No connection with TTL motors has been made yet")
82 ROS_DEBUG(
"TtlManager - ctor");
87 ROS_WARN(
"TtlManager - TTL Communication Failed");
110 bool use_simu_gripper{
false};
111 bool use_simu_conveyor{
false};
118 nh.getParam(
"simu_gripper", use_simu_gripper);
119 nh.getParam(
"simu_conveyor", use_simu_conveyor);
121 ROS_DEBUG(
"TtlManager::init - Dxl : set port name (%s), baudrate(%d)",
_device_name.c_str(),
_baudrate);
124 ROS_DEBUG(
"TtlManager::init - Simulation mode: %s, simu_gripper: %s, simu_conveyor: %s",
_simulation_mode ?
"True" :
"False", use_simu_gripper ?
"True" :
"False",
125 use_simu_conveyor ?
"True" :
"False");
152 int ret = COMM_NOT_AVAILABLE;
154 ROS_DEBUG(
"TtlManager::setupCommunication - initializing connection...");
175 ros::Duration(0.1).sleep();
184 ROS_ERROR(
"TtlManager::setupCommunication - Failed to set baudrate for Dynamixel bus");
191 ROS_ERROR(
"TtlManager::setupCommunication - Failed to open Uart port for Dynamixel bus");
197 ROS_ERROR(
"TtlManager::setupCommunication - Invalid port handler");
211 return niryo_robot_msgs::CommandStatus::FAILURE;
214 EHardwareType hardware_type = state->getHardwareType();
215 uint8_t
id = state->getId();
217 ROS_DEBUG(
"TtlManager::addHardwareComponent : %s", state->str().c_str());
224 ROS_ERROR(
"TtlManager::addHardwareComponent - No driver found for hardware type %d",
static_cast<int>(hardware_type));
225 return niryo_robot_msgs::CommandStatus::FAILURE;
227 auto driver = driver_it->second;
230 if (state->getStrictModelNumber() && driver->checkModelNumber(
id) != COMM_SUCCESS)
232 ROS_WARN(
"TtlManager::addHardwareComponent - Model number check failed for hardware id %d",
id);
233 return niryo_robot_msgs::CommandStatus::HARDWARE_NOT_SUPPORTED;
238 int res = COMM_RX_FAIL;
239 for (
int tries = 10; tries > 0; tries--)
241 res = driver->readFirmwareVersion(
id, version);
242 if (COMM_SUCCESS == res)
244 state->setFirmwareVersion(version);
247 ros::Duration(0.1).sleep();
250 if (COMM_SUCCESS != res)
252 ROS_WARN(
"TtlManager::addHardwareComponent : Unable to retrieve firmware version for "
253 "hardware id %d : result = %d",
261 _ids_map[hardware_type].emplace_back(
id);
264 if (common::model::EComponentType::CONVEYOR == state->getComponentType())
271 if (common::model::EComponentType::JOINT == state->getComponentType())
273 if (!(common::model::EHardwareType::FAKE_STEPPER_MOTOR == hardware_type
274 || common::model::EHardwareType::FAKE_DXL_MOTOR == hardware_type))
281 return niryo_robot_msgs::CommandStatus::SUCCESS;
290 ROS_DEBUG(
"TtlManager::removeMotor - Remove motor id: %d",
id);
294 EHardwareType type =
_state_map.at(
id)->getHardwareType();
300 ids.erase(std::remove(ids.begin(), ids.end(),
id), ids.end());
324 return (
static_cast<int>(type) <= 7);
340 int ret = COMM_TX_FAIL;
342 if (old_id == new_id)
348 auto driver = std::dynamic_pointer_cast<AbstractMotorDriver>(
_driver_map.at(motor_type));
352 ret = driver->changeId(old_id, new_id);
353 if (COMM_SUCCESS == ret)
361 std::swap(
_state_map[new_id], i_state->second);
368 if (common::model::EComponentType::CONVEYOR ==
_state_map.at(new_id)->getComponentType())
382 _ids_map.at(motor_type).emplace_back(new_id);
397 ROS_DEBUG(
"TtlManager::scanAndCheck");
398 int result = COMM_PORT_BUSY;
404 for (
int counter = 0; counter < 50 && COMM_SUCCESS != result; ++counter)
407 ROS_DEBUG_COND(COMM_SUCCESS != result,
"TtlManager::scanAndCheck status: %d (counter: %d)", result, counter);
408 ros::Duration(TIME_TO_WAIT_IF_BUSY).sleep();
411 if (COMM_SUCCESS == result)
415 std::string error_motors_message;
420 uint8_t
id = istate.first;
426 error_motors_message +=
" " + to_string(
id);
427 istate.second->setConnectionStatus(
true);
431 istate.second->setConnectionStatus(
false);
450 _debug_error_message =
"TtlManager - Failed to scan motors, physical bus is too busy. Will retry...";
451 ROS_WARN_THROTTLE(1,
"TtlManager::scanAndCheck - Failed to scan motors, physical bus is too busy");
484 int return_value = COMM_TX_FAIL;
488 EHardwareType type =
_state_map.at(hw_id)->getHardwareType();
489 ROS_DEBUG(
"TtlManager::rebootHardware - Reboot hardware with ID: %d", hw_id);
492 return_value =
_driver_map.at(type)->reboot(hw_id);
493 if (COMM_SUCCESS == return_value)
496 int res = COMM_RX_FAIL;
497 for (
int tries = 10; tries > 0; tries--)
499 res =
_driver_map.at(type)->readFirmwareVersion(hw_id, version);
500 if (COMM_SUCCESS == res)
502 _state_map.at(hw_id)->setFirmwareVersion(version);
505 ros::Duration(0.1).sleep();
508 if (COMM_SUCCESS != res)
510 ROS_WARN(
"TtlManager::addHardwareComponent : Unable to retrieve firmware version for "
511 "hardware id %d : result = %d",
515 ROS_WARN_COND(COMM_SUCCESS != return_value,
"TtlManager::rebootHardware - Failed to reboot hardware: %d", return_value);
530 auto hw_type = it.first;
531 auto driver = std::dynamic_pointer_cast<ttl_driver::AbstractMotorDriver>(it.second);
536 vector<uint8_t> ids_list =
_ids_map.at(hw_type);
540 for (
size_t i = 0; i < ids_list.size(); ++i)
542 auto jState_it = std::find_if(jStates.begin(), jStates.end(), [i](
const std::shared_ptr<JointState> &jState){
543 return i == jState->getId();
545 if (jState_it == jStates.end())
549 auto jState = *jState_it;
550 ROS_DEBUG(
"TtlManager::resetTorques - Torque ON on stepper ID: %d",
static_cast<int>(ids_list.at(i)));
551 driver->writeTorquePercentage(ids_list.at(i), jState->getTorquePercentage());
568 uint32_t position = 0;
569 EHardwareType hardware_type = motor_state.getHardwareType();
572 auto driver = std::dynamic_pointer_cast<AbstractMotorDriver>(
_driver_map.at(hardware_type));
577 if (COMM_SUCCESS == driver->readPosition(motor_state.getId(), position))
587 ROS_ERROR_THROTTLE(1,
"TtlManager::getPosition - motor connection problem - Failed to read from bus");
595 ROS_ERROR_THROTTLE(1,
"TtlManager::getPosition - Driver not found for requested motor id");
603 EHardwareType hw_type(EHardwareType::STEPPER);
604 auto driver = std::dynamic_pointer_cast<ttl_driver::StepperDriver<ttl_driver::StepperReg>>(
_driver_map[hw_type]);
608 vector<uint8_t> ids_list =
_ids_map.at(hw_type);
611 vector<uint32_t> homing_abs_position_list;
614 int res = driver->syncReadHomingAbsPosition(ids_list, homing_abs_position_list);
615 if (COMM_SUCCESS == res)
617 if (ids_list.size() == homing_abs_position_list.size())
620 for (
size_t i = 0; i < ids_list.size(); ++i)
622 uint8_t
id = ids_list.at(i);
626 auto state = std::dynamic_pointer_cast<common::model::StepperMotorState>(
_state_map.at(
id));
629 state->setHomingAbsPosition(
static_cast<uint32_t
>(homing_abs_position_list.at(i)));
633 ROS_ERROR(
"TtlManager::readHomingAbsPosition - null pointer");
639 ROS_ERROR(
"TtlManager::readHomingAbsPosition - No hardware state assossiated to ID: %d",
static_cast<int>(
id));
646 ROS_ERROR(
"TtlManager::readHomingAbsPosition - size of requested id %d mismatch size of retrieved homing position %d",
static_cast<int>(ids_list.size()),
647 static_cast<int>(homing_abs_position_list.size()));
653 ROS_ERROR(
"TtlManager::readHomingAbsPosition - communication error: %d",
static_cast<int>(res));
659 ROS_ERROR(
"TtlManager::readHomingAbsPosition - null pointer or no hardware type in map %d or empty vector of ids: %d",
static_cast<int>(
_ids_map.count(hw_type)),
660 static_cast<int>(
_ids_map.at(hw_type).empty()));
673 uint8_t hw_errors_increment = 0;
680 auto hw_type = it.first;
681 auto driver = std::dynamic_pointer_cast<ttl_driver::AbstractMotorDriver>(it.second);
687 auto id_list_it =
_ids_map.find(hw_type);
692 auto ids_list = id_list_it->second;
694 if (ids_list.empty())
704 if (COMM_SUCCESS == res)
709 for (
size_t i = 0; i < ids_list.size(); ++i)
711 uint8_t
id = ids_list.at(i);
715 auto state = std::dynamic_pointer_cast<common::model::AbstractMotorState>(
_state_map.at(
id));
726 ROS_WARN(
"TtlManager::readJointStatus : Fail to sync read joint state - "
727 "vector mismatch (id_list size %d, position_list size %d)",
728 static_cast<int>(ids_list.size()),
static_cast<int>(
_position_list.size()));
729 hw_errors_increment++;
736 ROS_DEBUG(
"TtlManager::readJointStatus : Fail to sync read joint state - "
737 "driver fail to syncReadPosition");
738 hw_errors_increment++;
761 ROS_DEBUG_THROTTLE(2,
"_hw_fail_counter_read, hw_errors_increment: %d, %d",
_hw_fail_counter_read, hw_errors_increment);
764 if (0 == hw_errors_increment)
773 return (0 == hw_errors_increment);
787 EHardwareType ee_type;
790 ee_type = EHardwareType::FAKE_END_EFFECTOR;
791 else if (
_driver_map.count(EHardwareType::END_EFFECTOR))
792 ee_type = EHardwareType::END_EFFECTOR;
793 else if (
_driver_map.count(EHardwareType::NED3PRO_END_EFFECTOR))
794 ee_type = EHardwareType::NED3PRO_END_EFFECTOR;
799 unsigned int hw_errors_increment = 0;
801 auto driver = std::dynamic_pointer_cast<AbstractEndEffectorDriver>(
_driver_map.at(ee_type));
806 uint8_t
id =
_ids_map.at(ee_type).front();
811 auto state = std::dynamic_pointer_cast<EndEffectorState>(
_state_map[
id]);
815 vector<common::model::EActionType> action_list;
819 if (COMM_SUCCESS == driver->syncReadButtonsStatus(
id, action_list))
821 for (uint8_t i = 0; i < action_list.size(); i++)
823 state->setButtonStatus(i, action_list.at(i));
826 if (action_list.at(i) != common::model::EActionType::NO_ACTION)
842 hw_errors_increment++;
847 if (COMM_SUCCESS == driver->readDigitalInput(
id, digital_data))
849 state->setDigitalIn(digital_data);
853 hw_errors_increment++;
861 if (0 == hw_errors_increment)
876 ROS_ERROR(
"TtlManager::readEndEffectorStatus - motor connection problem - Failed to read from bus (hw_fail_counter_read : %d)",
_end_effector_fail_counter_read);
897 EHardwareType ee_type;
900 ee_type = EHardwareType::FAKE_END_EFFECTOR;
901 else if (
_driver_map.count(EHardwareType::END_EFFECTOR))
902 ee_type = EHardwareType::END_EFFECTOR;
903 else if (
_driver_map.count(EHardwareType::NED3PRO_END_EFFECTOR))
904 ee_type = EHardwareType::NED3PRO_END_EFFECTOR;
908 unsigned int hw_errors_increment = 0;
910 auto driver = std::dynamic_pointer_cast<AbstractEndEffectorDriver>(
_driver_map.at(ee_type));
915 uint8_t
id =
_ids_map.at(ee_type).front();
944 hw_errors_increment++;
955 if (0 == hw_errors_increment)
980 EHardwareType ee_type;
983 ee_type = EHardwareType::FAKE_END_EFFECTOR;
984 else if (
_driver_map.count(EHardwareType::END_EFFECTOR))
985 ee_type = EHardwareType::END_EFFECTOR;
986 else if (
_driver_map.count(EHardwareType::NED3PRO_END_EFFECTOR))
987 ee_type = EHardwareType::NED3PRO_END_EFFECTOR;
991 auto driver = std::dynamic_pointer_cast<AbstractEndEffectorDriver>(
_driver_map.at(ee_type));
997 uint8_t
id =
_ids_map.at(ee_type).front();
1044 unsigned int hw_errors_increment = 0;
1049 auto type = it.first;
1050 auto driver = it.second;
1055 vector<uint8_t> ids_list =
_ids_map.at(type);
1059 vector<std::pair<double, uint8_t>> hw_data_list;
1061 if (COMM_SUCCESS != driver->syncReadHwStatus(ids_list, hw_data_list))
1064 hw_errors_increment++;
1066 else if (ids_list.size() != hw_data_list.size())
1069 ROS_ERROR(
"TtlManager::readHardwareStatusOptimized : syncReadHwStatus failed - "
1070 "vector mistmatch (id_list size %d, hw_data_list size %d)",
1071 static_cast<int>(ids_list.size()),
static_cast<int>(hw_data_list.size()));
1073 hw_errors_increment++;
1077 vector<uint8_t> hw_error_status_list;
1079 if (COMM_SUCCESS != driver->syncReadHwErrorStatus(ids_list, hw_error_status_list))
1081 hw_errors_increment++;
1083 else if (ids_list.size() != hw_error_status_list.size())
1085 ROS_ERROR(
"TtlManager::readHardwareStatus : syncReadTemperature failed - "
1086 "vector mistmatch (id_list size %d, hw_status_list size %d)",
1087 static_cast<int>(ids_list.size()),
static_cast<int>(hw_error_status_list.size()));
1089 hw_errors_increment++;
1093 for (
size_t i = 0; i < ids_list.size(); ++i)
1095 uint8_t
id = ids_list.at(i);
1102 if (hw_data_list.size() > i)
1104 double voltage = (hw_data_list.at(i)).first;
1105 uint8_t temperature = (hw_data_list.at(i)).second;
1107 state->setTemperature(temperature);
1108 state->setRawVoltage(voltage);
1112 if (hw_error_status_list.size() > i)
1114 state->setHardwareError(hw_error_status_list.at(i));
1118 string hardware_message = driver->interpretErrorState(state->getHardwareError());
1119 state->setHardwareError(hardware_message);
1129 if (0 == hw_errors_increment)
1144 ROS_ERROR_THROTTLE(1,
1145 "TtlManager::readHardwareStatus - motor connection problem - "
1146 "Failed to read from bus (hw_fail_counter_read : %d)",
1163 uint8_t hw_errors_increment = 0;
1167 if (stepper_joint_driver)
1169 if (hw_type == EHardwareType::STEPPER || hw_type == EHardwareType::FAKE_STEPPER_MOTOR )
1180 vector<uint8_t> id_list =
_ids_map.at(hw_type);
1181 vector<uint8_t> stepper_id_list;
1182 std::copy_if(id_list.begin(), id_list.end(), std::back_inserter(stepper_id_list),
1183 [
this](uint8_t
id) { return _state_map[id] && _state_map.at(id)->getComponentType() != common::model::EComponentType::CONVEYOR; });
1198 std::vector<uint8_t> homing_status_list;
1199 if (COMM_SUCCESS == stepper_joint_driver->syncReadHomingStatus(stepper_id_list, homing_status_list))
1201 if (stepper_id_list.size() == homing_status_list.size())
1204 int max_status = -1;
1207 std::ostringstream ss_debug;
1208 ss_debug <<
"homing status : ";
1210 bool still_in_progress =
false;
1213 for (
size_t i = 0; i < homing_status_list.size(); ++i)
1215 uint8_t
id = stepper_id_list.at(i);
1216 ss_debug << static_cast<int>(homing_status_list.at(i)) <<
", ";
1220 EStepperCalibrationStatus status = stepper_joint_driver->interpretHomingData(homing_status_list.at(i));
1223 auto stepperState = std::dynamic_pointer_cast<StepperMotorState>(
_state_map.at(
id));
1224 if (stepperState && !stepperState->isConveyor())
1226 stepperState->setCalibration(status, 1);
1237 if (0 != max_status && homing_status_list.at(i) > max_status)
1238 max_status = homing_status_list.at(i);
1241 if ((0 == homing_status_list.at(i)) || EStepperCalibrationStatus::IN_PROGRESS == status)
1243 still_in_progress =
true;
1249 ss_debug <<
" => max_status: " <<
static_cast<int>(max_status);
1251 ROS_DEBUG_THROTTLE(2.0,
"TtlManager::readCalibrationStatus : %s", ss_debug.str().c_str());
1266 _calibration_status = stepper_joint_driver->interpretHomingData(
static_cast<uint8_t
>(max_status));
1279 ROS_ERROR(
"TtlManager::readCalibrationStatus : syncReadHomingStatus failed - "
1280 "vector mistmatch (id_list size %d, homing_status_list size %d)",
1281 static_cast<int>(stepper_id_list.size()),
static_cast<int>(homing_status_list.size()));
1283 hw_errors_increment++;
1288 hw_errors_increment++;
1292 else if (hw_type == EHardwareType::NED3PRO_STEPPER)
1300 auto conveyor_id = conveyor_state->getId();
1301 auto conveyor_hw_type = conveyor_state->getHardwareType();
1302 auto conveyor_driver = std::dynamic_pointer_cast<ttl_driver::AbstractStepperDriver>(
_driver_map[conveyor_hw_type]);
1303 int32_t conveyor_speed_percent = 0;
1304 int32_t direction = 0;
1305 if (COMM_SUCCESS == conveyor_driver->readConveyorVelocity(conveyor_id, conveyor_speed_percent, direction))
1307 conveyor_state->setGoalDirection(direction);
1308 conveyor_state->setSpeed(conveyor_speed_percent);
1309 conveyor_state->setState(conveyor_speed_percent);
1313 hw_errors_increment++;
1318 ROS_DEBUG_THROTTLE(2.0,
"TtlManager::readCalibrationStatus: _calibration_status: %s", common::model::StepperCalibrationStatusEnum(
_calibration_status).toString().c_str());
1319 ROS_DEBUG_THROTTLE(2.0,
"TtlManager::readCalibrationStatus: _calib_machine_state: %d",
static_cast<int>(
_calib_machine_state.
status()));
1321 return hw_errors_increment;
1326 uint8_t hw_errors_increment = 0;
1328 EHardwareType hw_type = EHardwareType::NED3PRO_STEPPER;
1339 vector<uint8_t> id_list =
_ids_map.at(hw_type);
1340 vector<uint8_t> stepper_id_list;
1341 std::copy_if(id_list.begin(), id_list.end(), std::back_inserter(stepper_id_list), [
this](uint8_t
id) {
1342 return _state_map[id] &&
1343 _state_map.at(id)->getComponentType() != common::model::EComponentType::CONVEYOR;
1348 std::vector<uint8_t> homing_status_list;
1349 if (stepper_joint_driver &&
1350 COMM_SUCCESS == stepper_joint_driver->syncReadHomingStatus(stepper_id_list, homing_status_list))
1352 if (stepper_id_list.size() == homing_status_list.size())
1355 ttl_driver::CalibrationStatus calibration_status_msg;
1357 EStepperCalibrationStatus highest_priority_status = EStepperCalibrationStatus::UNINITIALIZED;
1359 for (
size_t i = 0; i < homing_status_list.size(); ++i)
1361 uint8_t
id = stepper_id_list.at(i);
1366 auto stepperState = std::dynamic_pointer_cast<StepperMotorState>(
_state_map.at(
id));
1367 if (stepperState && !stepperState->isConveyor())
1369 auto status = stepper_joint_driver->interpretHomingData(homing_status_list.at(i));
1370 stepperState->setCalibration(status, 1);
1372 if (status > highest_priority_status)
1373 highest_priority_status = status;
1375 calibration_status_msg.ids.push_back(
id);
1379 case EStepperCalibrationStatus::IN_PROGRESS:
1380 calibration_status_msg.status.push_back(ttl_driver::CalibrationStatus::CALIBRATING);
1382 case EStepperCalibrationStatus::OK:
1383 calibration_status_msg.status.push_back(ttl_driver::CalibrationStatus::CALIBRATED);
1385 case EStepperCalibrationStatus::FAIL:
1386 calibration_status_msg.status.push_back(ttl_driver::CalibrationStatus::CALIBRATION_ERROR);
1389 calibration_status_msg.status.push_back(ttl_driver::CalibrationStatus::CALIBRATION_ERROR);
1401 ROS_ERROR(
"TtlManager::readCalibrationStatus : syncReadHomingStatus failed - "
1402 "vector mistmatch (id_list size %d, homing_status_list size %d)",
1403 static_cast<int>(stepper_id_list.size()),
static_cast<int>(homing_status_list.size()));
1405 hw_errors_increment++;
1410 hw_errors_increment++;
1414 return hw_errors_increment;
1426 int result = COMM_RX_FAIL;
1431 vector<uint8_t> l_idList;
1433 id_list.insert(id_list.end(), l_idList.begin(), l_idList.end());
1436 for (
auto const &
id : l_idList)
1437 ids_str += to_string(
id) +
" ";
1439 ROS_DEBUG_THROTTLE(1,
"TtlManager::getAllIdsOnTtlBus - Found ids (%s) on bus using default driver", ids_str.c_str());
1441 if (COMM_SUCCESS != result)
1443 if (COMM_RX_TIMEOUT != result)
1446 "Make sure that motors are correctly connected and powered on.";
1452 ROS_WARN_THROTTLE(1,
1453 "TtlManager::getAllIdsOnTtlBus - Broadcast ping failed, "
1454 "result : %d (-3001: timeout, -3002: corrupted packet)",
1461 result = COMM_SUCCESS;
1479 int ret = niryo_robot_msgs::CommandStatus::TTL_WRITE_ERROR;
1483 if (mType == EHardwareType::FAKE_DXL_MOTOR)
1484 return niryo_robot_msgs::CommandStatus::SUCCESS;
1487 vector<uint8_t> id_list;
1492 auto driver = std::dynamic_pointer_cast<AbstractDxlDriver>(
_driver_map.at(mType));
1496 vector<uint8_t> command_led_value(id_list.size(),
static_cast<uint8_t
>(led));
1497 if (0 <= led && 7 >= led)
1499 int result = COMM_TX_FAIL;
1500 for (
int error_counter = 0; result != COMM_SUCCESS && error_counter < 5; ++error_counter)
1502 ros::Duration(TIME_TO_WAIT_IF_BUSY).sleep();
1503 result = driver->syncWriteLed(id_list, command_led_value);
1506 if (COMM_SUCCESS == result)
1507 ret = niryo_robot_msgs::CommandStatus::SUCCESS;
1509 ROS_WARN(
"TtlManager::setLeds - Failed to write LED");
1514 ROS_DEBUG(
"Set leds failed. Driver is not compatible, check the driver's implementation ");
1515 return niryo_robot_msgs::CommandStatus::FAILURE;
1520 ROS_DEBUG(
"Set leds failed. It is maybe that this service is not support for this product");
1521 ret = niryo_robot_msgs::CommandStatus::SUCCESS;
1537 int result = COMM_TX_FAIL;
1538 ROS_DEBUG(
"TtlManager::sendCustomCommand:\n"
1539 "\t\t ID: %d, Value: %d, Address: %d, Size: %d",
1540 static_cast<int>(
id), value, reg_address, byte_number);
1544 EHardwareType motor_type =
_state_map.at(
id)->getHardwareType();
1546 if (motor_type == EHardwareType::STEPPER || motor_type == EHardwareType::FAKE_STEPPER_MOTOR) {
1547 return niryo_robot_msgs::CommandStatus::SUCCESS;
1552 int32_t value_conv = value;
1553 result =
_driver_map.at(motor_type)->writeCustom(
static_cast<uint16_t
>(reg_address),
static_cast<uint8_t
>(byte_number),
id,
static_cast<uint32_t
>(value_conv));
1554 if (result != COMM_SUCCESS)
1556 ROS_WARN(
"TtlManager::sendCustomCommand - Failed to write custom command: %d", result);
1558 result = niryo_robot_msgs::CommandStatus::TTL_WRITE_ERROR;
1563 ROS_ERROR_THROTTLE(1,
"TtlManager::sendCustomCommand - driver for motor %s not available", HardwareTypeEnum(motor_type).toString().c_str());
1564 result = niryo_robot_msgs::CommandStatus::WRONG_MOTOR_TYPE;
1569 ROS_ERROR_THROTTLE(1,
"TtlManager::sendCustomCommand - driver for motor id %d unknown",
static_cast<int>(
id));
1570 result = niryo_robot_msgs::CommandStatus::WRONG_MOTOR_TYPE;
1573 ros::Duration(0.005).sleep();
1587 int result = COMM_RX_FAIL;
1588 ROS_DEBUG(
"TtlManager::readCustomCommand: ID: %d, Address: %d, Size: %d",
static_cast<int>(
id),
static_cast<int>(reg_address), byte_number);
1592 EHardwareType motor_type =
_state_map.at(
id)->getHardwareType();
1597 result =
_driver_map.at(motor_type)->readCustom(
static_cast<uint16_t
>(reg_address),
static_cast<uint8_t
>(byte_number),
id, data);
1598 auto data_conv =
static_cast<int32_t
>(data);
1601 if (result != COMM_SUCCESS)
1603 ROS_WARN(
"TtlManager::readCustomCommand - Failed to read custom command: %d", result);
1604 result = niryo_robot_msgs::CommandStatus::TTL_READ_ERROR;
1609 ROS_ERROR_THROTTLE(1,
"TtlManager::readCustomCommand - driver for motor %s not available", HardwareTypeEnum(motor_type).toString().c_str());
1610 result = niryo_robot_msgs::CommandStatus::WRONG_MOTOR_TYPE;
1615 ROS_ERROR_THROTTLE(1,
"TtlManager::readCustomCommand - driver for motor id %d unknown",
static_cast<int>(
id));
1616 result = niryo_robot_msgs::CommandStatus::WRONG_MOTOR_TYPE;
1619 ros::Duration(0.005).sleep();
1635 int TtlManager::readMotorPID(uint8_t
id, uint16_t &pos_p_gain, uint16_t &pos_i_gain, uint16_t &pos_d_gain, uint16_t &vel_p_gain, uint16_t &vel_i_gain, uint16_t &ff1_gain,
1638 int result = COMM_RX_FAIL;
1642 EHardwareType motor_type =
_state_map.at(
id)->getHardwareType();
1646 auto driver = std::dynamic_pointer_cast<AbstractDxlDriver>(
_driver_map.at(motor_type));
1649 std::vector<uint16_t> data;
1650 result = driver->readPID(
id, data);
1652 if (COMM_SUCCESS == result)
1654 pos_p_gain = data.at(0);
1655 pos_i_gain = data.at(1);
1656 pos_d_gain = data.at(2);
1657 vel_p_gain = data.at(3);
1658 vel_i_gain = data.at(4);
1659 ff1_gain = data.at(5);
1660 ff2_gain = data.at(6);
1664 ROS_WARN(
"TtlManager::readMotorPID - Failed to read PID: %d", result);
1665 result = niryo_robot_msgs::CommandStatus::TTL_READ_ERROR;
1672 ROS_ERROR_THROTTLE(1,
"TtlManager::readMotorPID - driver for motor %s not available", HardwareTypeEnum(motor_type).toString().c_str());
1673 result = niryo_robot_msgs::CommandStatus::WRONG_MOTOR_TYPE;
1678 ROS_ERROR_THROTTLE(1,
"TtlManager::readMotorPID - driver for motor id %d unknown",
static_cast<int>(
id));
1679 result = niryo_robot_msgs::CommandStatus::WRONG_MOTOR_TYPE;
1682 ros::Duration(0.005).sleep();
1699 int TtlManager::readVelocityProfile(uint8_t
id, uint32_t &v_start, uint32_t &a_1, uint32_t &v_1, uint32_t &a_max, uint32_t &v_max, uint32_t &d_max, uint32_t &d_1, uint32_t &v_stop)
1701 int result = COMM_RX_FAIL;
1705 EHardwareType motor_type =
_state_map.at(
id)->getHardwareType();
1707 if (joint_stepper_driver)
1709 std::vector<uint32_t> data;
1710 result = joint_stepper_driver->readVelocityProfile(
id, data);
1712 if (COMM_SUCCESS == result)
1714 v_start = data.at(0);
1721 v_stop = data.at(7);
1725 ROS_WARN(
"TtlManager::readVelocityProfile - Failed to read velocity profile: %d", result);
1726 result = niryo_robot_msgs::CommandStatus::TTL_READ_ERROR;
1732 ROS_ERROR_THROTTLE(1,
"TtlManager::readVelocityProfile - driver for motor %s not available", HardwareTypeEnum(motor_type).toString().c_str());
1733 result = niryo_robot_msgs::CommandStatus::WRONG_MOTOR_TYPE;
1738 ROS_ERROR_THROTTLE(1,
"TtlManager::readVelocityProfile - driver for motor id %d unknown",
static_cast<int>(
id));
1739 result = niryo_robot_msgs::CommandStatus::WRONG_MOTOR_TYPE;
1742 ros::Duration(0.005).sleep();
1754 int result = COMM_RX_FAIL;
1758 EHardwareType motor_type =
_state_map.at(
id)->getHardwareType();
1761 if (
_driver_map.count(motor_type) && (motor_type == EHardwareType::XL330 || motor_type == EHardwareType::XL320|| motor_type == EHardwareType::FAKE_DXL_MOTOR))
1763 auto driver = std::dynamic_pointer_cast<AbstractDxlDriver>(
_driver_map.at(motor_type));
1766 result = driver->readMoving(
id, status);
1771 ROS_ERROR_THROTTLE(1,
"TtlManager::readMoving - register MOVING for motor %s not available", HardwareTypeEnum(motor_type).toString().c_str());
1772 result = niryo_robot_msgs::CommandStatus::WRONG_MOTOR_TYPE;
1777 ROS_ERROR_THROTTLE(1,
"TtlManager::readMoving - driver for motor id %d unknown",
static_cast<int>(
id));
1778 result = niryo_robot_msgs::CommandStatus::WRONG_MOTOR_TYPE;
1781 ros::Duration(0.005).sleep();
1793 int result = COMM_RX_FAIL;
1797 EHardwareType motor_type =
_state_map.at(
id)->getHardwareType();
1801 auto driver = std::dynamic_pointer_cast<AbstractDxlDriver>(
_driver_map.at(motor_type));
1804 result = driver->readControlMode(
id, control_mode);
1809 ROS_ERROR_THROTTLE(1,
"TtlManager::readControlMode - driver for motor %s not available", HardwareTypeEnum(motor_type).toString().c_str());
1810 result = niryo_robot_msgs::CommandStatus::WRONG_MOTOR_TYPE;
1815 ROS_ERROR_THROTTLE(1,
"TtlManager::readControlMode - driver for motor id %d unknown",
static_cast<int>(
id));
1816 result = niryo_robot_msgs::CommandStatus::WRONG_MOTOR_TYPE;
1819 ros::Duration(0.005).sleep();
1830 int result = COMM_TX_ERROR;
1831 ROS_DEBUG_THROTTLE(0.5,
"TtlManager::writeSynchronizeCommand: %s", cmd->str().c_str());
1835 std::set<EHardwareType> typesToProcess = cmd->getMotorTypes();
1840 ROS_DEBUG_THROTTLE(0.5,
"TtlManager::writeSynchronizeCommand: try to sync write (counter %d)", counter);
1844 if (typesToProcess.count(it.first) != 0)
1846 result = COMM_TX_ERROR;
1849 auto driver = std::dynamic_pointer_cast<AbstractMotorDriver>(it.second);
1852 result = driver->writeSyncCmd(cmd->getCmdType(), cmd->getMotorsId(it.first), cmd->getParams(it.first));
1854 ros::Duration(0.05).sleep();
1858 if (COMM_SUCCESS == result)
1860 typesToProcess.erase(typesToProcess.find(it.first));
1864 ROS_ERROR(
"TtlManager::writeSynchronizeCommand : unable to sync write function : %d", result);
1870 if (typesToProcess.empty())
1872 result = COMM_SUCCESS;
1876 ros::Duration(TIME_TO_WAIT_IF_BUSY).sleep();
1881 ROS_ERROR(
"TtlManager::writeSynchronizeCommand - Invalid command");
1884 if (COMM_SUCCESS != result)
1886 ROS_ERROR_THROTTLE(0.5,
"TtlManager::writeSynchronizeCommand - Failed to write synchronize position");
1900 int result = COMM_TX_ERROR;
1902 uint8_t
id = cmd->getId();
1908 ROS_DEBUG(
"TtlManager::writeSingleCommand: %s", cmd->str().c_str());
1913 while ((COMM_SUCCESS != result) && (counter < 50))
1915 EHardwareType hardware_type = state->getHardwareType();
1916 result = COMM_TX_ERROR;
1920 result =
_driver_map.at(hardware_type)->writeSingleCmd(cmd);
1925 ros::Duration(TIME_TO_WAIT_IF_BUSY).sleep();
1930 ROS_DEBUG(
"TtlManager::writeSingleCommand: command is sent to a removed hardware component. Skipped or write to a unknow device");
1931 result = COMM_TX_ERROR;
1935 if (result != COMM_SUCCESS)
1937 ROS_WARN(
"TtlManager::writeSingleCommand - Fail to write single command : %s", cmd->str().c_str());
1955 for (
auto const &cmd : cmd_vec)
1965 auto driver = std::dynamic_pointer_cast<AbstractMotorDriver>(it.second);
1970 if (err != COMM_SUCCESS)
1972 ROS_WARN(
"TtlManager::executeJointTrajectoryCmd - Failed to write position");
1988 ROS_DEBUG(
"TtlManager::startCalibration: starting...");
1990 std::vector<uint8_t> stepper_list;
1991 if (
_ids_map.count(EHardwareType::STEPPER))
1995 stepper_list =
_ids_map.at(EHardwareType::STEPPER);
1997 else if (
_ids_map.count(EHardwareType::NED3PRO_STEPPER))
1999 stepper_list =
_ids_map.at(EHardwareType::NED3PRO_STEPPER);
2001 else if (
_ids_map.count(EHardwareType::FAKE_STEPPER_MOTOR))
2005 stepper_list =
_ids_map.at(EHardwareType::FAKE_STEPPER_MOTOR);
2008 for (
auto const &
id : stepper_list)
2012 auto stepperState = std::dynamic_pointer_cast<StepperMotorState>(
_state_map.at(
id));
2014 if (stepperState && !stepperState->isConveyor())
2016 stepperState->setCalibration(EStepperCalibrationStatus::IN_PROGRESS, 1);
2027 ROS_INFO(
"TtlManager::resetCalibration: reseting...");
2029 std::vector<uint8_t> stepper_list;
2030 if (
_ids_map.count(EHardwareType::STEPPER))
2034 stepper_list =
_ids_map.at(EHardwareType::STEPPER);
2036 else if (
_ids_map.count(EHardwareType::NED3PRO_STEPPER))
2037 stepper_list =
_ids_map.at(EHardwareType::NED3PRO_STEPPER);
2039 for (
auto const id : stepper_list)
2043 auto stepperState = std::dynamic_pointer_cast<StepperMotorState>(
_state_map.at(
id));
2045 if (stepperState && !stepperState->isConveyor())
2047 stepperState->setCalibration(EStepperCalibrationStatus::UNINITIALIZED, 1);
2061 throw std::out_of_range(
"TtlManager::getMotorsState: Unknown motor id");
2063 return std::dynamic_pointer_cast<StepperMotorState>(
_state_map.at(motor_id))->getCalibrationValue();
2089 std::vector<std::shared_ptr<JointState>> states;
2093 if (it.second && it.second->getComponentType() == common::model::EComponentType::JOINT)
2095 states.emplace_back(std::dynamic_pointer_cast<JointState>(it.second));
2104 std::vector<std::shared_ptr<ConveyorState>> conveyor_states;
2107 if (it.second && it.second->getComponentType() == common::model::EComponentType::CONVEYOR)
2109 conveyor_states.emplace_back(std::dynamic_pointer_cast<ConveyorState>(it.second));
2113 return conveyor_states;
2124 throw std::out_of_range(
"TtlManager::getMotorsState: Unknown motor id");
2142 switch (hardware_type)
2144 case EHardwareType::STEPPER:
2147 case EHardwareType::NED3PRO_STEPPER:
2150 case EHardwareType::FAKE_STEPPER_MOTOR:
2153 case EHardwareType::XL430:
2156 case EHardwareType::XC430:
2159 case EHardwareType::XM430:
2162 case EHardwareType::XL320:
2165 case EHardwareType::XL330:
2168 case EHardwareType::XH430:
2171 case EHardwareType::FAKE_DXL_MOTOR:
2174 case EHardwareType::END_EFFECTOR:
2177 case EHardwareType::NED3PRO_END_EFFECTOR:
2180 case EHardwareType::FAKE_END_EFFECTOR:
2181 _driver_map.insert(std::make_pair(hardware_type, std::make_shared<MockEndEffectorDriver>(
_fake_data)));
2184 ROS_ERROR(
"TtlManager - Unable to instanciate driver, unknown type");
2195 _fake_data = std::make_shared<FakeTtlData>();
2197 if (
_nh.hasParam(
"fake_params"))
2199 std::vector<int> full_id_list;
2200 if (
_nh.hasParam(
"fake_params/id_list"))
2201 _nh.getParam(
"fake_params/id_list", full_id_list);
2202 for (
auto id : full_id_list)
2203 _fake_data->full_id_list.emplace_back(
static_cast<uint8_t
>(
id));
2205 if (
_nh.hasParam(
"fake_params/steppers"))
2207 std::string current_ns =
"fake_params/steppers/";
2211 if (
_nh.hasParam(
"fake_params/dynamixels/"))
2213 std::string current_ns =
"fake_params/dynamixels/";
2217 if (
_nh.hasParam(
"fake_params/end_effector"))
2219 string current_ns =
"fake_params/end_effector/";
2220 vector<int> id_list, temperature_list, voltage_list;
2221 vector<string> firmware_list;
2222 _nh.getParam(current_ns +
"id", id_list);
2223 _nh.getParam(current_ns +
"temperature", temperature_list);
2224 _nh.getParam(current_ns +
"voltage", voltage_list);
2225 _nh.getParam(current_ns +
"firmware", firmware_list);
2227 assert(!id_list.empty());
2228 assert(!temperature_list.empty());
2229 assert(!voltage_list.empty());
2230 assert(!firmware_list.empty());
2232 _fake_data->end_effector.id =
static_cast<uint8_t
>(id_list.at(0));
2233 _fake_data->end_effector.temperature =
static_cast<uint8_t
>(temperature_list.at(0));
2234 _fake_data->end_effector.voltage =
static_cast<double>(voltage_list.at(0));
2236 _fake_data->end_effector.firmware = firmware_list.at(0);
2239 if (use_simu_gripper &&
_nh.hasParam(
"fake_params/tool/"))
2241 std::string current_ns =
"fake_params/tool/";
2245 if (use_simu_conveyor &&
_nh.hasParam(
"fake_params/conveyors/"))
2247 std::string current_ns =
"fake_params/conveyors/";
2262 auto some_joint_state_it = std::find_if(joint_states.begin(), joint_states.end(), [](
const std::shared_ptr<JointState>& joint_state){
2263 return joint_state->isStepper();
2265 if (some_joint_state_it == joint_states.end()){
2268 auto some_joint_state = *some_joint_state_it;
2269 auto hardware_type = some_joint_state->getHardwareType();
2271 .driver = std::dynamic_pointer_cast<AbstractStepperDriver>(
_driver_map.at(hardware_type)),
2272 .hardware_type = hardware_type