Skip to content

Commit c1bcc12

Browse files
urfeexmergify[bot]
authored andcommitted
Refactor prepare_switch method (#1417)
Refactored prepare_switch mechanism. This way it should be easier to understand and to extend. (cherry picked from commit effc0a0) # Conflicts: # ur_robot_driver/src/hardware_interface.cpp
1 parent 817e565 commit c1bcc12

File tree

2 files changed

+104
-38
lines changed

2 files changed

+104
-38
lines changed

ur_robot_driver/include/ur_robot_driver/hardware_interface.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,11 @@
4040
#define UR_ROBOT_DRIVER__HARDWARE_INTERFACE_HPP_
4141

4242
// System
43+
#include <limits>
4344
#include <memory>
4445
#include <string>
46+
#include <unordered_map>
4547
#include <vector>
46-
#include <limits>
4748

4849
// ros2_control hardware_interface
4950
#include "hardware_interface/hardware_info.hpp"
@@ -114,6 +115,7 @@ class URPositionHardwareInterface : public hardware_interface::SystemInterface
114115
{
115116
public:
116117
RCLCPP_SHARED_PTR_DEFINITIONS(URPositionHardwareInterface);
118+
URPositionHardwareInterface();
117119
virtual ~URPositionHardwareInterface();
118120

119121
hardware_interface::CallbackReturn on_init(const hardware_interface::HardwareInfo& system_info) final;
@@ -316,6 +318,8 @@ class URPositionHardwareInterface : public hardware_interface::SystemInterface
316318
const std::string FORCE_MODE_GPIO = "force_mode";
317319
const std::string FREEDRIVE_MODE_GPIO = "freedrive_mode";
318320
const std::string TOOL_CONTACT_GPIO = "tool_contact";
321+
322+
std::unordered_map<std::string, std::unordered_map<std::string, bool>> mode_compatibility_;
319323
};
320324
} // namespace ur_robot_driver
321325

ur_robot_driver/src/hardware_interface.cpp

Lines changed: 99 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,45 @@ namespace rtde = urcl::rtde_interface;
5757
namespace ur_robot_driver
5858
{
5959

60+
URPositionHardwareInterface::URPositionHardwareInterface()
61+
{
62+
mode_compatibility_[hardware_interface::HW_IF_POSITION][hardware_interface::HW_IF_VELOCITY] = false;
63+
mode_compatibility_[hardware_interface::HW_IF_POSITION][FORCE_MODE_GPIO] = false;
64+
mode_compatibility_[hardware_interface::HW_IF_POSITION][PASSTHROUGH_GPIO] = false;
65+
mode_compatibility_[hardware_interface::HW_IF_POSITION][FREEDRIVE_MODE_GPIO] = false;
66+
mode_compatibility_[hardware_interface::HW_IF_POSITION][TOOL_CONTACT_GPIO] = true;
67+
68+
mode_compatibility_[hardware_interface::HW_IF_VELOCITY][hardware_interface::HW_IF_POSITION] = false;
69+
mode_compatibility_[hardware_interface::HW_IF_VELOCITY][FORCE_MODE_GPIO] = false;
70+
mode_compatibility_[hardware_interface::HW_IF_VELOCITY][PASSTHROUGH_GPIO] = false;
71+
mode_compatibility_[hardware_interface::HW_IF_VELOCITY][FREEDRIVE_MODE_GPIO] = false;
72+
mode_compatibility_[hardware_interface::HW_IF_VELOCITY][TOOL_CONTACT_GPIO] = true;
73+
74+
mode_compatibility_[FORCE_MODE_GPIO][hardware_interface::HW_IF_POSITION] = false;
75+
mode_compatibility_[FORCE_MODE_GPIO][hardware_interface::HW_IF_VELOCITY] = false;
76+
mode_compatibility_[FORCE_MODE_GPIO][PASSTHROUGH_GPIO] = true;
77+
mode_compatibility_[FORCE_MODE_GPIO][FREEDRIVE_MODE_GPIO] = false;
78+
mode_compatibility_[FORCE_MODE_GPIO][TOOL_CONTACT_GPIO] = false;
79+
80+
mode_compatibility_[PASSTHROUGH_GPIO][hardware_interface::HW_IF_POSITION] = false;
81+
mode_compatibility_[PASSTHROUGH_GPIO][hardware_interface::HW_IF_VELOCITY] = false;
82+
mode_compatibility_[PASSTHROUGH_GPIO][FORCE_MODE_GPIO] = true;
83+
mode_compatibility_[PASSTHROUGH_GPIO][FREEDRIVE_MODE_GPIO] = false;
84+
mode_compatibility_[PASSTHROUGH_GPIO][TOOL_CONTACT_GPIO] = true;
85+
86+
mode_compatibility_[FREEDRIVE_MODE_GPIO][hardware_interface::HW_IF_POSITION] = false;
87+
mode_compatibility_[FREEDRIVE_MODE_GPIO][hardware_interface::HW_IF_VELOCITY] = false;
88+
mode_compatibility_[FREEDRIVE_MODE_GPIO][FORCE_MODE_GPIO] = false;
89+
mode_compatibility_[FREEDRIVE_MODE_GPIO][PASSTHROUGH_GPIO] = false;
90+
mode_compatibility_[FREEDRIVE_MODE_GPIO][TOOL_CONTACT_GPIO] = false;
91+
92+
mode_compatibility_[TOOL_CONTACT_GPIO][hardware_interface::HW_IF_POSITION] = true;
93+
mode_compatibility_[TOOL_CONTACT_GPIO][hardware_interface::HW_IF_VELOCITY] = true;
94+
mode_compatibility_[TOOL_CONTACT_GPIO][FORCE_MODE_GPIO] = false;
95+
mode_compatibility_[TOOL_CONTACT_GPIO][PASSTHROUGH_GPIO] = true;
96+
mode_compatibility_[TOOL_CONTACT_GPIO][FREEDRIVE_MODE_GPIO] = false;
97+
}
98+
6099
URPositionHardwareInterface::~URPositionHardwareInterface()
61100
{
62101
}
@@ -1094,11 +1133,25 @@ hardware_interface::return_type URPositionHardwareInterface::prepare_command_mod
10941133
}
10951134
}
10961135

1136+
auto is_mode_compatible = [this](const std::string& mode, const std::vector<std::string>& other_modes) {
1137+
for (auto& other : other_modes) {
1138+
if (mode == other)
1139+
continue;
1140+
1141+
if (mode_compatibility_[mode][other] == false) {
1142+
RCLCPP_ERROR(get_logger(), "Starting %s together with %s is not allowed. ", mode.c_str(), other.c_str());
1143+
return false;
1144+
}
1145+
}
1146+
return true;
1147+
};
1148+
10971149
// Starting interfaces
10981150
// If a joint has been reserved already, raise an error.
10991151
// Modes that are not directly mapped to a single joint such as force_mode reserve all joints.
11001152
for (const auto& key : start_interfaces) {
11011153
for (auto i = 0u; i < info_.joints.size(); i++) {
1154+
<<<<<<< HEAD
11021155
if (key == info_.joints[i].name + "/" + hardware_interface::HW_IF_POSITION) {
11031156
if (std::any_of(start_modes_[i].begin(), start_modes_[i].end(), [&](const std::string& item) {
11041157
return item == hardware_interface::HW_IF_VELOCITY || item == PASSTHROUGH_GPIO ||
@@ -1161,6 +1214,25 @@ hardware_interface::return_type URPositionHardwareInterface::prepare_command_mod
11611214
return hardware_interface::return_type::ERROR;
11621215
}
11631216
start_modes_[i].push_back(TOOL_CONTACT_GPIO);
1217+
=======
1218+
const std::vector<std::pair<std::string, std::string>> start_modes_to_check{
1219+
{ info_.joints[i].name + "/" + hardware_interface::HW_IF_POSITION, hardware_interface::HW_IF_POSITION },
1220+
{ info_.joints[i].name + "/" + hardware_interface::HW_IF_VELOCITY, hardware_interface::HW_IF_VELOCITY },
1221+
{ tf_prefix + FORCE_MODE_GPIO + "/type", FORCE_MODE_GPIO },
1222+
{ tf_prefix + PASSTHROUGH_GPIO + "/setpoint_positions_" + std::to_string(i), PASSTHROUGH_GPIO },
1223+
{ tf_prefix + FREEDRIVE_MODE_GPIO + "/async_success", FREEDRIVE_MODE_GPIO },
1224+
{ tf_prefix + TOOL_CONTACT_GPIO + "/tool_contact_set_state", TOOL_CONTACT_GPIO }
1225+
};
1226+
1227+
for (auto& item : start_modes_to_check) {
1228+
if (key == item.first) {
1229+
if (!is_mode_compatible(item.second, start_modes_[i])) {
1230+
return hardware_interface::return_type::ERROR;
1231+
}
1232+
start_modes_[i].push_back(item.second);
1233+
continue;
1234+
}
1235+
>>>>>>> effc0a0 (Refactor prepare_switch method (#1417))
11641236
}
11651237
}
11661238
}
@@ -1175,48 +1247,32 @@ hardware_interface::return_type URPositionHardwareInterface::prepare_command_mod
11751247
// add stop interface per joint in tmp var for later check
11761248
for (const auto& key : stop_interfaces) {
11771249
for (auto i = 0u; i < info_.joints.size(); i++) {
1178-
if (key == info_.joints[i].name + "/" + hardware_interface::HW_IF_POSITION) {
1179-
stop_modes_[i].push_back(StoppingInterface::STOP_POSITION);
1180-
control_modes[i].erase(
1181-
std::remove_if(control_modes[i].begin(), control_modes[i].end(),
1182-
[](const std::string& item) { return item == hardware_interface::HW_IF_POSITION; }),
1183-
control_modes[i].end());
1184-
}
1185-
if (key == info_.joints[i].name + "/" + hardware_interface::HW_IF_VELOCITY) {
1186-
stop_modes_[i].push_back(StoppingInterface::STOP_VELOCITY);
1187-
control_modes[i].erase(
1188-
std::remove_if(control_modes[i].begin(), control_modes[i].end(),
1189-
[](const std::string& item) { return item == hardware_interface::HW_IF_VELOCITY; }),
1190-
control_modes[i].end());
1191-
}
1192-
if (key == tf_prefix + FORCE_MODE_GPIO + "/disable_cmd") {
1193-
stop_modes_[i].push_back(StoppingInterface::STOP_FORCE_MODE);
1194-
control_modes[i].erase(std::remove_if(control_modes[i].begin(), control_modes[i].end(),
1195-
[&](const std::string& item) { return item == FORCE_MODE_GPIO; }),
1196-
control_modes[i].end());
1197-
}
1198-
if (key == tf_prefix + PASSTHROUGH_GPIO + "/setpoint_positions_" + std::to_string(i)) {
1199-
stop_modes_[i].push_back(StoppingInterface::STOP_PASSTHROUGH);
1200-
control_modes[i].erase(std::remove_if(control_modes[i].begin(), control_modes[i].end(),
1201-
[&](const std::string& item) { return item == PASSTHROUGH_GPIO; }),
1202-
control_modes[i].end());
1203-
}
1204-
if (key == tf_prefix + FREEDRIVE_MODE_GPIO + "/async_success") {
1205-
stop_modes_[i].push_back(StoppingInterface::STOP_FREEDRIVE);
1206-
control_modes[i].erase(std::remove_if(control_modes[i].begin(), control_modes[i].end(),
1207-
[&](const std::string& item) { return item == FREEDRIVE_MODE_GPIO; }),
1208-
control_modes[i].end());
1209-
}
1210-
if (key == tf_prefix + TOOL_CONTACT_GPIO + "/tool_contact_set_state") {
1211-
stop_modes_[i].push_back(StoppingInterface::STOP_TOOL_CONTACT);
1212-
control_modes[i].erase(std::remove_if(control_modes[i].begin(), control_modes[i].end(),
1213-
[&](const std::string& item) { return item == TOOL_CONTACT_GPIO; }),
1214-
control_modes[i].end());
1250+
const std::vector<std::tuple<std::string, std::string, StoppingInterface>> stop_modes_to_check{
1251+
{ info_.joints[i].name + "/" + hardware_interface::HW_IF_POSITION, hardware_interface::HW_IF_POSITION,
1252+
StoppingInterface::STOP_POSITION },
1253+
{ info_.joints[i].name + "/" + hardware_interface::HW_IF_VELOCITY, hardware_interface::HW_IF_VELOCITY,
1254+
StoppingInterface::STOP_VELOCITY },
1255+
{ tf_prefix + FORCE_MODE_GPIO + "/disable_cmd", FORCE_MODE_GPIO, StoppingInterface::STOP_FORCE_MODE },
1256+
{ tf_prefix + PASSTHROUGH_GPIO + "/setpoint_positions_" + std::to_string(i), PASSTHROUGH_GPIO,
1257+
StoppingInterface::STOP_PASSTHROUGH },
1258+
{ tf_prefix + FREEDRIVE_MODE_GPIO + "/async_success", FREEDRIVE_MODE_GPIO, StoppingInterface::STOP_FREEDRIVE },
1259+
{ tf_prefix + TOOL_CONTACT_GPIO + "/tool_contact_set_state", TOOL_CONTACT_GPIO,
1260+
StoppingInterface::STOP_TOOL_CONTACT }
1261+
};
1262+
for (auto& item : stop_modes_to_check) {
1263+
if (key == std::get<0>(item)) {
1264+
stop_modes_[i].push_back(std::get<2>(item));
1265+
control_modes[i].erase(
1266+
std::remove_if(control_modes[i].begin(), control_modes[i].end(),
1267+
[&item](const std::string& entry) { return entry == std::get<1>(item); }),
1268+
control_modes[i].end());
1269+
}
12151270
}
12161271
}
12171272
}
12181273

12191274
// Do not start conflicting controllers
1275+
<<<<<<< HEAD
12201276
// Passthrough controller requested to start
12211277
if (std::any_of(start_modes_[0].begin(), start_modes_[0].end(),
12221278
[this](auto& item) { return (item == PASSTHROUGH_GPIO); }) &&
@@ -1320,6 +1376,12 @@ hardware_interface::return_type URPositionHardwareInterface::prepare_command_mod
13201376
"position mode or force_mode or freedrive mode "
13211377
"running.");
13221378
ret_val = hardware_interface::return_type::ERROR;
1379+
=======
1380+
for (auto& start_mode : start_modes_[0]) {
1381+
if (!is_mode_compatible(start_mode, control_modes[0])) {
1382+
return hardware_interface::return_type::ERROR;
1383+
}
1384+
>>>>>>> effc0a0 (Refactor prepare_switch method (#1417))
13231385
}
13241386

13251387
controllers_initialized_ = true;

0 commit comments

Comments
 (0)