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"
44 #include "dynamixel_sdk/packet_handler.h"
45 #include "niryo_robot_msgs/CommandStatus.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::ConveyorState;
68 using ::common::model::EHardwareType;
69 using ::common::model::EndEffectorState;
70 using ::common::model::EStepperCalibrationStatus;
71 using ::common::model::HardwareTypeEnum;
72 using ::common::model::JointState;
73 using ::common::model::StepperMotorState;
81 : _nh(
nh), _debug_error_message(
"TtlManager - No connection with TTL motors has been made yet")
83 ROS_DEBUG(
"TtlManager - ctor");
88 ROS_WARN(
"TtlManager - TTL Communication Failed");
111 bool use_simu_gripper{
false };
112 bool use_simu_conveyor{
false };
121 nh.getParam(
"simu_gripper", use_simu_gripper);
122 nh.getParam(
"simu_conveyor", use_simu_conveyor);
129 ROS_DEBUG(
"TtlManager::init - Dxl : set port name (%s), baudrate(%d)",
_device_name.c_str(),
_baudrate);
132 ROS_DEBUG(
"TtlManager::init - Simulation mode: %s, simu_gripper: %s, simu_conveyor: %s",
134 use_simu_conveyor ?
"True" :
"False");
165 status = niryo_robot_msgs::CommandStatus::TOOL_FAILURE;
166 message =
"Tool change failed : Real robot mode";
170 auto driver = it_driver->second;
173 status = niryo_robot_msgs::CommandStatus::TOOL_ID_INVALID;
174 message =
"Tool change failed : Driver not found";
184 status = niryo_robot_msgs::CommandStatus::TOOL_ID_INVALID;
185 message =
"Tool change failed: Tool ID is invalid";
198 status = niryo_robot_msgs::CommandStatus::SUCCESS;
199 message =
"Tool change succeeded";
203 status = niryo_robot_msgs::CommandStatus::TOOL_NOT_CONNECTED;
204 message =
"Tool change failed: Communication error";
217 int ret = COMM_NOT_AVAILABLE;
219 ROS_DEBUG(
"TtlManager::setupCommunication - initializing connection...");
240 ros::Duration(0.1).sleep();
249 ROS_ERROR(
"TtlManager::setupCommunication - Failed to set baudrate for Dynamixel bus");
256 ROS_ERROR(
"TtlManager::setupCommunication - Failed to open Uart port for Dynamixel bus");
262 ROS_ERROR(
"TtlManager::setupCommunication - Invalid port handler");
276 return niryo_robot_msgs::CommandStatus::FAILURE;
279 EHardwareType hardware_type = state->getHardwareType();
280 uint8_t
id = state->getId();
282 ROS_DEBUG(
"TtlManager::addHardwareComponent : %s", state->str().c_str());
289 ROS_ERROR(
"TtlManager::addHardwareComponent - No driver found for hardware type %d",
290 static_cast<int>(hardware_type));
291 return niryo_robot_msgs::CommandStatus::FAILURE;
293 auto driver = driver_it->second;
295 uint16_t model_number = 0;
297 if (state->getStrictModelNumber() && driver->checkModelNumber(
id, model_number) != COMM_SUCCESS)
299 ROS_WARN(
"TtlManager::addHardwareComponent - Model number check failed for hardware id %d",
id);
300 return niryo_robot_msgs::CommandStatus::HARDWARE_NOT_SUPPORTED;
302 else if (driver->getModelNumber(
id, model_number) != COMM_SUCCESS)
304 ROS_WARN(
"TtlManager::addHardwareComponent - Unable to retrieve model number for hardware id %d",
id);
305 return niryo_robot_msgs::CommandStatus::HARDWARE_NOT_SUPPORTED;
308 state->setModelNumber(model_number);
312 int res = COMM_RX_FAIL;
313 for (
int tries = 10; tries > 0; tries--)
315 res = driver->readFirmwareVersion(
id, version);
316 if (COMM_SUCCESS == res)
318 state->setFirmwareVersion(version);
321 ros::Duration(0.1).sleep();
324 if (COMM_SUCCESS != res)
327 "TtlManager::addHardwareComponent : Unable to retrieve firmware version for "
328 "hardware id %d : result = %d",
337 _motor_state_map[id] = std::dynamic_pointer_cast<common::model::AbstractMotorState>(state);
345 _ids_map[hardware_type].emplace_back(
id);
348 if (common::model::EComponentType::CONVEYOR == state->getComponentType())
355 if (common::model::EComponentType::JOINT == state->getComponentType())
357 if (!(common::model::EHardwareType::FAKE_STEPPER_MOTOR == hardware_type ||
358 common::model::EHardwareType::FAKE_DXL_MOTOR == hardware_type))
365 return niryo_robot_msgs::CommandStatus::SUCCESS;
374 ROS_DEBUG(
"TtlManager::removeMotor - Remove motor id: %d",
id);
378 EHardwareType type =
_state_map.at(
id)->getHardwareType();
384 ids.erase(std::remove(ids.begin(), ids.end(),
id), ids.end());
411 return (
static_cast<int>(type) <= 7);
427 int ret = COMM_TX_FAIL;
429 if (old_id == new_id)
439 ret = driver->changeId(old_id, new_id);
440 if (COMM_SUCCESS == ret)
448 auto current_state = i_state->second;
452 motor_node.key() = new_id;
458 if (common::model::EComponentType::CONVEYOR == current_state->getComponentType())
470 .erase(std::remove(
_ids_map.at(motor_type).begin(),
_ids_map.at(motor_type).end(), old_id),
474 _ids_map.at(motor_type).emplace_back(new_id);
489 ROS_DEBUG(
"TtlManager::scanAndCheck");
490 int result = COMM_PORT_BUSY;
496 for (
int counter = 0; counter < 50 && COMM_SUCCESS != result; ++counter)
499 ROS_DEBUG_COND(COMM_SUCCESS != result,
"TtlManager::scanAndCheck status: %d (counter: %d)", result, counter);
500 ros::Duration(TIME_TO_WAIT_IF_BUSY).sleep();
503 if (COMM_SUCCESS == result)
507 std::string error_motors_message;
512 uint8_t
id = istate.first;
518 error_motors_message +=
" " + to_string(
id);
519 istate.second->setConnectionStatus(
true);
523 istate.second->setConnectionStatus(
false);
542 _debug_error_message =
"TtlManager - Failed to scan motors, physical bus is too busy. Will retry...";
543 ROS_WARN_THROTTLE(1,
"TtlManager::scanAndCheck - Failed to scan motors, physical bus is too busy");
576 int return_value = COMM_TX_FAIL;
580 EHardwareType type =
_state_map.at(hw_id)->getHardwareType();
581 ROS_DEBUG(
"TtlManager::rebootHardware - Reboot hardware with ID: %d", hw_id);
584 return_value =
_driver_map.at(type)->reboot(hw_id);
585 if (COMM_SUCCESS == return_value)
588 int res = COMM_RX_FAIL;
589 for (
int tries = 10; tries > 0; tries--)
591 res =
_driver_map.at(type)->readFirmwareVersion(hw_id, version);
592 if (COMM_SUCCESS == res)
594 _state_map.at(hw_id)->setFirmwareVersion(version);
597 ros::Duration(0.1).sleep();
600 if (COMM_SUCCESS != res)
603 "TtlManager::addHardwareComponent : Unable to retrieve firmware version for "
604 "hardware id %d : result = %d",
608 ROS_WARN_COND(COMM_SUCCESS != return_value,
"TtlManager::rebootHardware - Failed to reboot hardware: %d",
627 vector<uint8_t> ids_list =
_ids_map.at(hw_type);
631 for (
size_t i = 0; i < ids_list.size(); ++i)
633 auto jState_it = std::find_if(jStates.begin(), jStates.end(),
634 [i](
const std::shared_ptr<JointState> &jState) { return i == jState->getId(); });
635 if (jState_it == jStates.end())
639 auto jState = *jState_it;
640 ROS_DEBUG(
"TtlManager::resetTorques - Torque ON on stepper ID: %d",
static_cast<int>(ids_list.at(i)));
641 driver->writeTorquePercentage(ids_list.at(i), jState->getTorquePercentage());
658 uint32_t position = 0;
659 EHardwareType hardware_type = motor_state.getHardwareType();
667 if (COMM_SUCCESS == driver->readPosition(motor_state.getId(), position))
677 ROS_ERROR_THROTTLE(1,
"TtlManager::getPosition - motor connection problem - Failed to read from bus");
685 ROS_ERROR_THROTTLE(1,
"TtlManager::getPosition - Driver not found for requested motor id");
693 EHardwareType hw_type(EHardwareType::STEPPER);
694 auto driver = std::dynamic_pointer_cast<ttl_driver::StepperDriver<ttl_driver::StepperReg>>(
_driver_map[hw_type]);
698 vector<uint8_t> ids_list =
_ids_map.at(hw_type);
701 vector<uint32_t> homing_abs_position_list;
704 int res = driver->syncReadHomingAbsPosition(ids_list, homing_abs_position_list);
705 if (COMM_SUCCESS == res)
707 if (ids_list.size() == homing_abs_position_list.size())
710 for (
size_t i = 0; i < ids_list.size(); ++i)
712 uint8_t
id = ids_list.at(i);
716 auto state = std::dynamic_pointer_cast<common::model::StepperMotorState>(
_state_map.at(
id));
719 state->setHomingAbsPosition(
static_cast<uint32_t
>(homing_abs_position_list.at(i)));
723 ROS_ERROR(
"TtlManager::readHomingAbsPosition - null pointer");
729 ROS_ERROR(
"TtlManager::readHomingAbsPosition - No hardware state assossiated to ID: %d",
730 static_cast<int>(
id));
738 "TtlManager::readHomingAbsPosition - size of requested id %d mismatch size of retrieved homing position %d",
739 static_cast<int>(ids_list.size()),
static_cast<int>(homing_abs_position_list.size()));
745 ROS_ERROR(
"TtlManager::readHomingAbsPosition - communication error: %d",
static_cast<int>(res));
752 "TtlManager::readHomingAbsPosition - null pointer or no hardware type in map %d or empty vector of ids: %d",
753 static_cast<int>(
_ids_map.count(hw_type)),
static_cast<int>(
_ids_map.at(hw_type).empty()));
766 uint8_t hw_errors_increment = 0;
777 auto id_list_it =
_ids_map.find(hw_type);
782 const auto &ids_list = id_list_it->second;
784 if (ids_list.empty())
794 if (COMM_SUCCESS == res)
799 for (
size_t i = 0; i < ids_list.size(); ++i)
801 uint8_t
id = ids_list[i];
806 auto state = motor_it->second;
818 "TtlManager::readJointStatus : Fail to sync read joint state - "
819 "vector mismatch (id_list size %d, position_list size %d)",
820 static_cast<int>(ids_list.size()),
static_cast<int>(
_position_list.size()));
821 hw_errors_increment++;
829 "TtlManager::readJointStatus : Fail to sync read joint state - "
830 "driver fail to syncReadPosition");
831 hw_errors_increment++;
855 hw_errors_increment);
858 if (0 == hw_errors_increment)
867 return (0 == hw_errors_increment);
881 EHardwareType ee_type;
884 ee_type = EHardwareType::FAKE_END_EFFECTOR;
886 ee_type = EHardwareType::END_EFFECTOR;
888 ee_type = EHardwareType::NED3PRO_END_EFFECTOR;
892 unsigned int hw_errors_increment = 0;
899 uint8_t
id =
_ids_map.at(ee_type).front();
908 vector<common::model::EActionType> action_list;
912 if (COMM_SUCCESS == driver->syncReadButtonsStatus(
id, action_list))
914 for (uint8_t i = 0; i < action_list.size(); i++)
916 state->setButtonStatus(i, action_list.at(i));
920 if (action_list.at(i) != common::model::EActionType::NO_ACTION)
937 hw_errors_increment++;
942 if (COMM_SUCCESS == driver->readDigitalInput(
id, digital_data))
944 state->setDigitalIn(digital_data);
948 hw_errors_increment++;
956 if (0 == hw_errors_increment)
973 "TtlManager::readEndEffectorStatus - motor connection problem - Failed to read from bus "
974 "(hw_fail_counter_read : %d)",
996 EHardwareType ee_type;
999 ee_type = EHardwareType::FAKE_END_EFFECTOR;
1001 ee_type = EHardwareType::END_EFFECTOR;
1003 ee_type = EHardwareType::NED3PRO_END_EFFECTOR;
1007 unsigned int hw_errors_increment = 0;
1014 uint8_t
id =
_ids_map.at(ee_type).front();
1043 hw_errors_increment++;
1054 if (0 == hw_errors_increment)
1080 EHardwareType ee_type;
1083 ee_type = EHardwareType::FAKE_END_EFFECTOR;
1085 ee_type = EHardwareType::END_EFFECTOR;
1087 ee_type = EHardwareType::NED3PRO_END_EFFECTOR;
1091 auto driver = it->second;
1097 uint8_t
id =
_ids_map.at(ee_type).front();
1144 unsigned int hw_errors_increment = 0;
1149 auto type = it.first;
1150 auto driver = it.second;
1155 vector<uint8_t> ids_list =
_ids_map.at(type);
1159 vector<std::pair<double, uint8_t>> hw_data_list;
1161 if (COMM_SUCCESS != driver->syncReadHwStatus(ids_list, hw_data_list))
1164 hw_errors_increment++;
1166 else if (ids_list.size() != hw_data_list.size())
1170 "TtlManager::readHardwareStatusOptimized : syncReadHwStatus failed - "
1171 "vector mistmatch (id_list size %d, hw_data_list size %d)",
1172 static_cast<int>(ids_list.size()),
static_cast<int>(hw_data_list.size()));
1174 hw_errors_increment++;
1178 vector<uint8_t> hw_error_status_list;
1180 if (COMM_SUCCESS != driver->syncReadHwErrorStatus(ids_list, hw_error_status_list))
1182 hw_errors_increment++;
1184 else if (ids_list.size() != hw_error_status_list.size())
1187 "TtlManager::readHardwareStatus : syncReadTemperature failed - "
1188 "vector mistmatch (id_list size %d, hw_status_list size %d)",
1189 static_cast<int>(ids_list.size()),
static_cast<int>(hw_error_status_list.size()));
1191 hw_errors_increment++;
1195 for (
size_t i = 0; i < ids_list.size(); ++i)
1197 uint8_t
id = ids_list.at(i);
1204 if (hw_data_list.size() > i)
1206 double voltage = (hw_data_list.at(i)).first;
1207 uint8_t temperature = (hw_data_list.at(i)).second;
1209 state->setTemperature(temperature);
1210 state->setRawVoltage(voltage);
1214 if (hw_error_status_list.size() > i)
1216 state->setHardwareError(hw_error_status_list.at(i));
1220 string hardware_message = driver->interpretErrorState(state->getHardwareError());
1221 state->setHardwareError(hardware_message);
1231 if (0 == hw_errors_increment)
1246 ROS_ERROR_THROTTLE(1,
1247 "TtlManager::readHardwareStatus - motor connection problem - "
1248 "Failed to read from bus (hw_fail_counter_read : %d)",
1265 uint8_t hw_errors_increment = 0;
1269 if (stepper_joint_driver)
1271 if (hw_type == EHardwareType::STEPPER || hw_type == EHardwareType::FAKE_STEPPER_MOTOR)
1282 vector<uint8_t> id_list =
_ids_map.at(hw_type);
1283 vector<uint8_t> stepper_id_list;
1284 std::copy_if(id_list.begin(), id_list.end(), std::back_inserter(stepper_id_list), [
this](uint8_t
id) {
1285 return _state_map[id] && _state_map.at(id)->getComponentType() != common::model::EComponentType::CONVEYOR;
1301 std::vector<uint8_t> homing_status_list;
1302 if (COMM_SUCCESS == stepper_joint_driver->syncReadHomingStatus(stepper_id_list, homing_status_list))
1304 if (stepper_id_list.size() == homing_status_list.size())
1308 int max_status = -1;
1311 std::ostringstream ss_debug;
1312 ss_debug <<
"homing status : ";
1314 bool still_in_progress =
false;
1317 for (
size_t i = 0; i < homing_status_list.size(); ++i)
1319 uint8_t
id = stepper_id_list.at(i);
1320 ss_debug << static_cast<int>(homing_status_list.at(i)) <<
", ";
1324 EStepperCalibrationStatus status = stepper_joint_driver->interpretHomingData(homing_status_list.at(i));
1327 auto stepperState = std::dynamic_pointer_cast<StepperMotorState>(
_state_map.at(
id));
1328 if (stepperState && !stepperState->isConveyor())
1330 stepperState->setCalibration(status, 1);
1341 if (0 != max_status && homing_status_list.at(i) > max_status)
1342 max_status = homing_status_list.at(i);
1345 if ((0 == homing_status_list.at(i)) || EStepperCalibrationStatus::IN_PROGRESS == status)
1347 still_in_progress =
true;
1353 ss_debug <<
" => max_status: " <<
static_cast<int>(max_status);
1355 ROS_DEBUG_THROTTLE(2.0,
"TtlManager::readCalibrationStatus : %s", ss_debug.str().c_str());
1370 _calibration_status = stepper_joint_driver->interpretHomingData(
static_cast<uint8_t
>(max_status));
1384 "TtlManager::readCalibrationStatus : syncReadHomingStatus failed - "
1385 "vector mistmatch (id_list size %d, homing_status_list size %d)",
1386 static_cast<int>(stepper_id_list.size()),
static_cast<int>(homing_status_list.size()));
1388 hw_errors_increment++;
1393 hw_errors_increment++;
1397 else if (hw_type == EHardwareType::NED3PRO_STEPPER)
1405 auto conveyor_id = conveyor_state->getId();
1406 auto conveyor_hw_type = conveyor_state->getHardwareType();
1407 auto conveyor_driver =
1408 std::dynamic_pointer_cast<ttl_driver::AbstractStepperDriver>(
_driver_map[conveyor_hw_type]);
1409 int32_t conveyor_speed_percent = 0;
1410 int32_t direction = 0;
1411 if (COMM_SUCCESS == conveyor_driver->readConveyorVelocity(conveyor_id, conveyor_speed_percent, direction))
1413 conveyor_state->setGoalDirection(direction);
1414 conveyor_state->setSpeed(conveyor_speed_percent);
1415 conveyor_state->setState(conveyor_speed_percent);
1419 hw_errors_increment++;
1424 ROS_DEBUG_THROTTLE(2.0,
"TtlManager::readCalibrationStatus: _calibration_status: %s",
1426 ROS_DEBUG_THROTTLE(2.0,
"TtlManager::readCalibrationStatus: _calib_machine_state: %d",
1429 return hw_errors_increment;
1434 uint8_t hw_errors_increment = 0;
1436 EHardwareType hw_type = EHardwareType::NED3PRO_STEPPER;
1447 vector<uint8_t> id_list =
_ids_map.at(hw_type);
1448 vector<uint8_t> stepper_id_list;
1449 std::copy_if(id_list.begin(), id_list.end(), std::back_inserter(stepper_id_list), [
this](uint8_t
id) {
1450 return _state_map[id] && _state_map.at(id)->getComponentType() != common::model::EComponentType::CONVEYOR;
1455 std::vector<uint8_t> homing_status_list;
1456 if (stepper_joint_driver &&
1457 COMM_SUCCESS == stepper_joint_driver->syncReadHomingStatus(stepper_id_list, homing_status_list))
1459 if (stepper_id_list.size() == homing_status_list.size())
1462 ttl_driver::CalibrationStatus calibration_status_msg;
1464 EStepperCalibrationStatus highest_priority_status = EStepperCalibrationStatus::UNINITIALIZED;
1466 for (
size_t i = 0; i < homing_status_list.size(); ++i)
1468 uint8_t
id = stepper_id_list.at(i);
1473 auto stepperState = std::dynamic_pointer_cast<StepperMotorState>(
_state_map.at(
id));
1474 if (stepperState && !stepperState->isConveyor())
1476 auto status = stepper_joint_driver->interpretHomingData(homing_status_list.at(i));
1477 stepperState->setCalibration(status, 1);
1479 if (status > highest_priority_status)
1480 highest_priority_status = status;
1482 calibration_status_msg.ids.push_back(
id);
1486 case EStepperCalibrationStatus::IN_PROGRESS:
1487 calibration_status_msg.status.push_back(ttl_driver::CalibrationStatus::CALIBRATING);
1489 case EStepperCalibrationStatus::OK:
1490 calibration_status_msg.status.push_back(ttl_driver::CalibrationStatus::CALIBRATED);
1492 case EStepperCalibrationStatus::FAIL:
1493 calibration_status_msg.status.push_back(ttl_driver::CalibrationStatus::CALIBRATION_ERROR);
1496 calibration_status_msg.status.push_back(ttl_driver::CalibrationStatus::CALIBRATION_ERROR);
1509 "TtlManager::readCalibrationStatus : syncReadHomingStatus failed - "
1510 "vector mistmatch (id_list size %d, homing_status_list size %d)",
1511 static_cast<int>(stepper_id_list.size()),
static_cast<int>(homing_status_list.size()));
1513 hw_errors_increment++;
1518 hw_errors_increment++;
1522 return hw_errors_increment;
1534 int result = COMM_RX_FAIL;
1539 vector<uint8_t> l_idList;
1541 id_list.insert(id_list.end(), l_idList.begin(), l_idList.end());
1544 for (
auto const &
id : l_idList)
1545 ids_str += to_string(
id) +
" ";
1547 ROS_DEBUG_THROTTLE(1,
"TtlManager::getAllIdsOnTtlBus - Found ids (%s) on bus using default driver",
1550 if (COMM_SUCCESS != result)
1552 if (COMM_RX_TIMEOUT != result)
1555 "TtlManager - No motor found. "
1556 "Make sure that motors are correctly connected and powered on.";
1562 ROS_WARN_THROTTLE(1,
1563 "TtlManager::getAllIdsOnTtlBus - Broadcast ping failed, "
1564 "result : %d (-3001: timeout, -3002: corrupted packet)",
1571 result = COMM_SUCCESS;
1589 int ret = niryo_robot_msgs::CommandStatus::TTL_WRITE_ERROR;
1593 if (mType == EHardwareType::FAKE_DXL_MOTOR)
1594 return niryo_robot_msgs::CommandStatus::SUCCESS;
1597 vector<uint8_t> id_list;
1602 auto driver = std::dynamic_pointer_cast<AbstractDxlDriver>(
_driver_map.at(mType));
1606 vector<uint8_t> command_led_value(id_list.size(),
static_cast<uint8_t
>(led));
1607 if (0 <= led && 7 >= led)
1609 int result = COMM_TX_FAIL;
1610 for (
int error_counter = 0; result != COMM_SUCCESS && error_counter < 5; ++error_counter)
1612 ros::Duration(TIME_TO_WAIT_IF_BUSY).sleep();
1613 result = driver->syncWriteLed(id_list, command_led_value);
1616 if (COMM_SUCCESS == result)
1617 ret = niryo_robot_msgs::CommandStatus::SUCCESS;
1619 ROS_WARN(
"TtlManager::setLeds - Failed to write LED");
1624 ROS_DEBUG(
"Set leds failed. Driver is not compatible, check the driver's implementation ");
1625 return niryo_robot_msgs::CommandStatus::FAILURE;
1630 ROS_DEBUG(
"Set leds failed. It is maybe that this service is not support for this product");
1631 ret = niryo_robot_msgs::CommandStatus::SUCCESS;
1647 int result = COMM_TX_FAIL;
1649 "TtlManager::sendCustomCommand:\n"
1650 "\t\t ID: %d, Value: %d, Address: %d, Size: %d",
1651 static_cast<int>(
id), value, reg_address, byte_number);
1655 EHardwareType motor_type =
_state_map.at(
id)->getHardwareType();
1657 if (motor_type == EHardwareType::STEPPER || motor_type == EHardwareType::FAKE_STEPPER_MOTOR)
1659 return niryo_robot_msgs::CommandStatus::SUCCESS;
1664 int32_t value_conv = value;
1666 ->writeCustom(
static_cast<uint16_t
>(reg_address),
static_cast<uint8_t
>(byte_number),
id,
1667 static_cast<uint32_t
>(value_conv));
1668 if (result != COMM_SUCCESS)
1670 ROS_WARN(
"TtlManager::sendCustomCommand - Failed to write custom command: %d", result);
1672 result = niryo_robot_msgs::CommandStatus::TTL_WRITE_ERROR;
1677 ROS_ERROR_THROTTLE(1,
"TtlManager::sendCustomCommand - driver for motor %s not available",
1678 HardwareTypeEnum(motor_type).toString().c_str());
1679 result = niryo_robot_msgs::CommandStatus::WRONG_MOTOR_TYPE;
1684 ROS_ERROR_THROTTLE(1,
"TtlManager::sendCustomCommand - driver for motor id %d unknown",
static_cast<int>(
id));
1685 result = niryo_robot_msgs::CommandStatus::WRONG_MOTOR_TYPE;
1688 ros::Duration(0.005).sleep();
1702 int result = COMM_RX_FAIL;
1703 ROS_DEBUG(
"TtlManager::readCustomCommand: ID: %d, Address: %d, Size: %d",
static_cast<int>(
id),
1704 static_cast<int>(reg_address), byte_number);
1708 EHardwareType motor_type =
_state_map.at(
id)->getHardwareType();
1714 ->readCustom(
static_cast<uint16_t
>(reg_address),
static_cast<uint8_t
>(byte_number),
id, data);
1715 auto data_conv =
static_cast<int32_t
>(data);
1718 if (result != COMM_SUCCESS)
1720 ROS_WARN(
"TtlManager::readCustomCommand - Failed to read custom command: %d", result);
1721 result = niryo_robot_msgs::CommandStatus::TTL_READ_ERROR;
1726 ROS_ERROR_THROTTLE(1,
"TtlManager::readCustomCommand - driver for motor %s not available",
1727 HardwareTypeEnum(motor_type).toString().c_str());
1728 result = niryo_robot_msgs::CommandStatus::WRONG_MOTOR_TYPE;
1733 ROS_ERROR_THROTTLE(1,
"TtlManager::readCustomCommand - driver for motor id %d unknown",
static_cast<int>(
id));
1734 result = niryo_robot_msgs::CommandStatus::WRONG_MOTOR_TYPE;
1737 ros::Duration(0.005).sleep();
1754 uint16_t &vel_p_gain, uint16_t &vel_i_gain, uint16_t &ff1_gain, uint16_t &ff2_gain)
1756 int result = COMM_RX_FAIL;
1760 EHardwareType motor_type =
_state_map.at(
id)->getHardwareType();
1764 auto driver = std::dynamic_pointer_cast<AbstractDxlDriver>(
_driver_map.at(motor_type));
1767 std::vector<uint16_t> data;
1768 result = driver->readPID(
id, data);
1770 if (COMM_SUCCESS == result)
1772 pos_p_gain = data.at(0);
1773 pos_i_gain = data.at(1);
1774 pos_d_gain = data.at(2);
1775 vel_p_gain = data.at(3);
1776 vel_i_gain = data.at(4);
1777 ff1_gain = data.at(5);
1778 ff2_gain = data.at(6);
1782 ROS_WARN(
"TtlManager::readMotorPID - Failed to read PID: %d", result);
1783 result = niryo_robot_msgs::CommandStatus::TTL_READ_ERROR;
1790 ROS_ERROR_THROTTLE(1,
"TtlManager::readMotorPID - driver for motor %s not available",
1791 HardwareTypeEnum(motor_type).toString().c_str());
1792 result = niryo_robot_msgs::CommandStatus::WRONG_MOTOR_TYPE;
1797 ROS_ERROR_THROTTLE(1,
"TtlManager::readMotorPID - driver for motor id %d unknown",
static_cast<int>(
id));
1798 result = niryo_robot_msgs::CommandStatus::WRONG_MOTOR_TYPE;
1801 ros::Duration(0.005).sleep();
1819 uint32_t &v_max, uint32_t &d_max, uint32_t &d_1, uint32_t &v_stop)
1821 int result = COMM_RX_FAIL;
1825 EHardwareType motor_type =
_state_map.at(
id)->getHardwareType();
1827 if (joint_stepper_driver)
1829 std::vector<uint32_t> data;
1830 result = joint_stepper_driver->readVelocityProfile(
id, data);
1832 if (COMM_SUCCESS == result)
1834 v_start = data.at(0);
1841 v_stop = data.at(7);
1845 ROS_WARN(
"TtlManager::readVelocityProfile - Failed to read velocity profile: %d", result);
1846 result = niryo_robot_msgs::CommandStatus::TTL_READ_ERROR;
1852 ROS_ERROR_THROTTLE(1,
"TtlManager::readVelocityProfile - driver for motor %s not available",
1853 HardwareTypeEnum(motor_type).toString().c_str());
1854 result = niryo_robot_msgs::CommandStatus::WRONG_MOTOR_TYPE;
1859 ROS_ERROR_THROTTLE(1,
"TtlManager::readVelocityProfile - driver for motor id %d unknown",
static_cast<int>(
id));
1860 result = niryo_robot_msgs::CommandStatus::WRONG_MOTOR_TYPE;
1863 ros::Duration(0.005).sleep();
1875 int result = COMM_RX_FAIL;
1879 EHardwareType motor_type =
_state_map.at(
id)->getHardwareType();
1882 if (
_driver_map.count(motor_type) && (motor_type == EHardwareType::XL330 || motor_type == EHardwareType::XL320 ||
1883 motor_type == EHardwareType::FAKE_DXL_MOTOR))
1885 auto driver = std::dynamic_pointer_cast<AbstractDxlDriver>(
_driver_map.at(motor_type));
1888 result = driver->readMoving(
id, status);
1893 ROS_ERROR_THROTTLE(1,
"TtlManager::readMoving - register MOVING for motor %s not available",
1894 HardwareTypeEnum(motor_type).toString().c_str());
1895 result = niryo_robot_msgs::CommandStatus::WRONG_MOTOR_TYPE;
1900 ROS_ERROR_THROTTLE(1,
"TtlManager::readMoving - driver for motor id %d unknown",
static_cast<int>(
id));
1901 result = niryo_robot_msgs::CommandStatus::WRONG_MOTOR_TYPE;
1904 ros::Duration(0.005).sleep();
1916 int result = COMM_RX_FAIL;
1920 EHardwareType motor_type =
_state_map.at(
id)->getHardwareType();
1924 auto driver = std::dynamic_pointer_cast<AbstractDxlDriver>(
_driver_map.at(motor_type));
1927 result = driver->readControlMode(
id, control_mode);
1932 ROS_ERROR_THROTTLE(1,
"TtlManager::readControlMode - driver for motor %s not available",
1933 HardwareTypeEnum(motor_type).toString().c_str());
1934 result = niryo_robot_msgs::CommandStatus::WRONG_MOTOR_TYPE;
1939 ROS_ERROR_THROTTLE(1,
"TtlManager::readControlMode - driver for motor id %d unknown",
static_cast<int>(
id));
1940 result = niryo_robot_msgs::CommandStatus::WRONG_MOTOR_TYPE;
1943 ros::Duration(0.005).sleep();
1954 int result = COMM_TX_ERROR;
1955 ROS_DEBUG_THROTTLE(0.5,
"TtlManager::writeSynchronizeCommand: %s", cmd->str().c_str());
1959 std::set<EHardwareType> typesToProcess = cmd->getMotorTypes();
1964 ROS_DEBUG_THROTTLE(0.5,
"TtlManager::writeSynchronizeCommand: try to sync write (counter %d)", counter);
1968 if (typesToProcess.count(hw_type) != 0)
1970 result = COMM_TX_ERROR;
1975 result = driver->writeSyncCmd(cmd->getCmdType(), cmd->getMotorsId(hw_type), cmd->getParams(hw_type));
1977 ros::Duration(0.05).sleep();
1981 if (COMM_SUCCESS == result)
1983 typesToProcess.erase(typesToProcess.find(hw_type));
1987 ROS_ERROR(
"TtlManager::writeSynchronizeCommand : unable to sync write function : %d", result);
1993 if (typesToProcess.empty())
1995 result = COMM_SUCCESS;
1999 ros::Duration(TIME_TO_WAIT_IF_BUSY).sleep();
2004 ROS_ERROR(
"TtlManager::writeSynchronizeCommand - Invalid command");
2007 if (COMM_SUCCESS != result)
2009 ROS_ERROR_THROTTLE(0.5,
"TtlManager::writeSynchronizeCommand - Failed to write synchronize position");
2023 int result = COMM_TX_ERROR;
2025 uint8_t
id = cmd->getId();
2031 ROS_DEBUG(
"TtlManager::writeSingleCommand: %s", cmd->str().c_str());
2036 while ((COMM_SUCCESS != result) && (counter < 50))
2038 EHardwareType hardware_type = state->getHardwareType();
2039 result = COMM_TX_ERROR;
2044 result =
_driver_map.at(hardware_type)->writeSingleCmd(cmd);
2049 ros::Duration(TIME_TO_WAIT_IF_BUSY).sleep();
2055 "TtlManager::writeSingleCommand: command is sent to a removed hardware component. Skipped or write to a "
2057 result = COMM_TX_ERROR;
2061 if (result != COMM_SUCCESS)
2063 ROS_WARN(
"TtlManager::writeSingleCommand - Fail to write single command : %s", cmd->str().c_str());
2081 for (
auto const &cmd : cmd_vec)
2093 if (err != COMM_SUCCESS)
2095 ROS_WARN(
"TtlManager::executeJointTrajectoryCmd - Failed to write position");
2111 ROS_DEBUG(
"TtlManager::startCalibration: starting...");
2113 std::vector<uint8_t> stepper_list;
2114 if (
_ids_map.count(EHardwareType::STEPPER))
2118 stepper_list =
_ids_map.at(EHardwareType::STEPPER);
2120 else if (
_ids_map.count(EHardwareType::NED3PRO_STEPPER))
2122 stepper_list =
_ids_map.at(EHardwareType::NED3PRO_STEPPER);
2124 else if (
_ids_map.count(EHardwareType::FAKE_STEPPER_MOTOR))
2128 stepper_list =
_ids_map.at(EHardwareType::FAKE_STEPPER_MOTOR);
2131 for (
auto const &
id : stepper_list)
2135 auto stepperState = std::dynamic_pointer_cast<StepperMotorState>(
_state_map.at(
id));
2137 if (stepperState && !stepperState->isConveyor())
2139 stepperState->setCalibration(EStepperCalibrationStatus::IN_PROGRESS, 1);
2150 ROS_INFO(
"TtlManager::resetCalibration: reseting...");
2152 std::vector<uint8_t> stepper_list;
2153 if (
_ids_map.count(EHardwareType::STEPPER))
2157 stepper_list =
_ids_map.at(EHardwareType::STEPPER);
2159 else if (
_ids_map.count(EHardwareType::NED3PRO_STEPPER))
2160 stepper_list =
_ids_map.at(EHardwareType::NED3PRO_STEPPER);
2162 for (
auto const id : stepper_list)
2166 auto stepperState = std::dynamic_pointer_cast<StepperMotorState>(
_state_map.at(
id));
2168 if (stepperState && !stepperState->isConveyor())
2170 stepperState->setCalibration(EStepperCalibrationStatus::UNINITIALIZED, 1);
2184 throw std::out_of_range(
"TtlManager::getMotorsState: Unknown motor id");
2186 return std::dynamic_pointer_cast<StepperMotorState>(
_state_map.at(motor_id))->getCalibrationValue();
2212 std::vector<std::shared_ptr<JointState>> states;
2216 if (it.second && it.second->getComponentType() == common::model::EComponentType::JOINT)
2218 states.emplace_back(std::dynamic_pointer_cast<JointState>(it.second));
2227 std::vector<std::shared_ptr<ConveyorState>> conveyor_states;
2230 if (it.second && it.second->getComponentType() == common::model::EComponentType::CONVEYOR)
2232 conveyor_states.emplace_back(std::dynamic_pointer_cast<ConveyorState>(it.second));
2236 return conveyor_states;
2247 throw std::out_of_range(
"TtlManager::getMotorsState: Unknown motor id");
2265 std::shared_ptr<ttl_driver::AbstractTtlDriver> new_driver =
nullptr;
2266 switch (hardware_type)
2268 case EHardwareType::STEPPER: {
2274 case EHardwareType::NED3PRO_STEPPER: {
2280 case EHardwareType::FAKE_STEPPER_MOTOR: {
2281 auto motor = std::make_shared<MockStepperDriver>(
_fake_data);
2286 case EHardwareType::XL430: {
2292 case EHardwareType::XC430: {
2298 case EHardwareType::XM430: {
2304 case EHardwareType::XL320: {
2310 case EHardwareType::XL330: {
2316 case EHardwareType::XH430: {
2322 case EHardwareType::FAKE_DXL_MOTOR: {
2323 auto motor = std::make_shared<MockDxlDriver>(
_fake_data);
2328 case EHardwareType::END_EFFECTOR: {
2334 case EHardwareType::NED3PRO_END_EFFECTOR: {
2340 case EHardwareType::FAKE_END_EFFECTOR: {
2341 auto ee = std::make_shared<MockEndEffectorDriver>(
_fake_data);
2347 ROS_ERROR(
"TtlManager - Unable to instanciate driver, unknown type");
2350 if (new_driver !=
nullptr)
2352 _driver_map.insert({ hardware_type, new_driver });
2362 _fake_data = std::make_shared<FakeTtlData>();
2364 if (
_nh.hasParam(
"fake_params"))
2366 std::vector<int> full_id_list;
2367 if (
_nh.hasParam(
"fake_params/id_list"))
2368 _nh.getParam(
"fake_params/id_list", full_id_list);
2369 for (
auto id : full_id_list)
2370 _fake_data->full_id_list.emplace_back(
static_cast<uint8_t
>(
id));
2372 if (
_nh.hasParam(
"fake_params/steppers"))
2374 std::string current_ns =
"fake_params/steppers/";
2378 if (
_nh.hasParam(
"fake_params/dynamixels/"))
2380 std::string current_ns =
"fake_params/dynamixels/";
2384 if (use_simu_gripper &&
_nh.hasParam(
"fake_params/tool/"))
2386 std::string current_ns =
"fake_params/tool/";
2390 if (
_nh.hasParam(
"fake_params/end_effector"))
2392 string current_ns =
"fake_params/end_effector/";
2393 vector<int> id_list, temperature_list, voltage_list;
2394 vector<string> firmware_list;
2395 _nh.getParam(current_ns +
"id", id_list);
2396 _nh.getParam(current_ns +
"temperature", temperature_list);
2397 _nh.getParam(current_ns +
"voltage", voltage_list);
2398 _nh.getParam(current_ns +
"firmware", firmware_list);
2400 assert(!id_list.empty());
2401 assert(!temperature_list.empty());
2402 assert(!voltage_list.empty());
2403 assert(!firmware_list.empty());
2405 _fake_data->end_effector.id =
static_cast<uint8_t
>(id_list.at(0));
2406 _fake_data->end_effector.temperature =
static_cast<uint8_t
>(temperature_list.at(0));
2407 _fake_data->end_effector.voltage =
static_cast<double>(voltage_list.at(0));
2409 _fake_data->end_effector.firmware = firmware_list.at(0);
2412 if (use_simu_conveyor &&
_nh.hasParam(
"fake_params/conveyors/"))
2414 std::string current_ns =
"fake_params/conveyors/";
2430 auto some_joint_state_it =
2431 std::find_if(joint_states.begin(), joint_states.end(),
2432 [](
const std::shared_ptr<JointState> &joint_state) { return joint_state->isStepper(); });
2433 if (some_joint_state_it == joint_states.end())
2437 auto some_joint_state = *some_joint_state_it;
2438 auto hardware_type = some_joint_state->getHardwareType();
2439 return { .driver = std::dynamic_pointer_cast<AbstractStepperDriver>(
_driver_map.at(hardware_type)),
2440 .hardware_type = hardware_type };