Skip to content

Commit b18bfc3

Browse files
committed
Refactor tool contact controller
1 parent 57b4693 commit b18bfc3

File tree

3 files changed

+52
-49
lines changed

3 files changed

+52
-49
lines changed

ur_controllers/include/ur_controllers/tool_contact_controller.hpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,9 @@ class ToolContactController : public controller_interface::ControllerInterface
9090

9191
RealtimeGoalHandleBuffer rt_active_goal_; ///< Currently active action goal, if any.
9292
rclcpp::TimerBase::SharedPtr goal_handle_timer_; ///< Timer to frequently check on the running goal
93-
rclcpp::Duration action_monitor_period_ = rclcpp::Duration(std::chrono::milliseconds(50));
93+
std::chrono::nanoseconds action_monitor_period_;
94+
95+
void action_handler(RealtimeGoalHandlePtr rt_goal);
9496

9597
rclcpp_action::GoalResponse goal_received_callback(const rclcpp_action::GoalUUID& /*uuid*/,
9698
std::shared_ptr<const ur_msgs::action::ToolContact::Goal> goal);
@@ -101,9 +103,6 @@ class ToolContactController : public controller_interface::ControllerInterface
101103
rclcpp_action::CancelResponse goal_cancelled_callback(
102104
const std::shared_ptr<rclcpp_action::ServerGoalHandle<ur_msgs::action::ToolContact>> goal_handle);
103105

104-
controller_interface::return_type failed_update();
105-
106-
double tool_contact_enable_ref_interface;
107106
double tool_contact_active_state_interface;
108107

109108
std::atomic<bool> tool_contact_enable_ = false;
@@ -112,10 +111,8 @@ class ToolContactController : public controller_interface::ControllerInterface
112111
std::atomic<bool> change_requested_ = false;
113112
std::atomic<bool> logged_once_ = false;
114113

115-
double old_reference_val = 0.0;
116-
117114
std::optional<std::reference_wrapper<hardware_interface::LoanedStateInterface>> tool_contact_result_interface_;
118-
std::optional<std::reference_wrapper<hardware_interface::LoanedStateInterface>> tool_contact_version_interface_;
115+
std::optional<std::reference_wrapper<hardware_interface::LoanedStateInterface>> major_version_state_interface_;
119116
std::optional<std::reference_wrapper<hardware_interface::LoanedCommandInterface>> tool_contact_status_interface_;
120117
std::optional<std::reference_wrapper<hardware_interface::LoanedCommandInterface>> reference_interface_;
121118

ur_controllers/src/tool_contact_controller.cpp

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ controller_interface::CallbackReturn
5959
ToolContactController::on_configure(const rclcpp_lifecycle::State& /* previous_state */)
6060
{
6161
tool_contact_action_server_ = rclcpp_action::create_server<ur_msgs::action::ToolContact>(
62-
get_node(), std::string(get_node()->get_name()) + "/enable_tool_contact",
62+
get_node(), std::string(get_node()->get_name()) + "/detect_tool_contact",
6363
std::bind(&ToolContactController::goal_received_callback, this, std::placeholders::_1, std::placeholders::_2),
6464
std::bind(&ToolContactController::goal_cancelled_callback, this, std::placeholders::_1),
6565
std::bind(&ToolContactController::goal_accepted_callback, this, std::placeholders::_1));
@@ -130,23 +130,25 @@ ToolContactController::on_activate(const rclcpp_lifecycle::State& /* previous_st
130130
auto it = std::find_if(state_interfaces_.begin(), state_interfaces_.end(),
131131
[&](auto& interface) { return (interface.get_name() == interface_name); });
132132
if (it != state_interfaces_.end()) {
133-
tool_contact_version_interface_ = *it;
134-
if (!tool_contact_result_interface_->get().get_value()) {
133+
major_version_state_interface_ = *it;
134+
double major_version = 0.0;
135+
if (!tool_contact_result_interface_->get().get_value(major_version)) {
135136
RCLCPP_ERROR(get_node()->get_logger(),
136137
"Failed to read '%s' state interface, aborting activation of controller.", interface_name.c_str());
137138
return controller_interface::CallbackReturn::ERROR;
138139
}
140+
if (major_version < 5) {
141+
RCLCPP_ERROR(get_node()->get_logger(), "This feature is not supported on CB3 robots, controller will not be "
142+
"started.");
143+
return controller_interface::CallbackReturn::ERROR;
144+
}
139145
} else {
140146
RCLCPP_ERROR(get_node()->get_logger(), "Did not find '%s' in state interfaces.", interface_name.c_str());
141147
return controller_interface::CallbackReturn::ERROR;
142148
}
143149
}
144-
if (tool_contact_version_interface_->get().get_value() < 5) {
145-
RCLCPP_ERROR(get_node()->get_logger(), "This feature is not supported on CB3 robots, controller will not be "
146-
"started.");
147-
return controller_interface::CallbackReturn::ERROR;
148-
}
149150

151+
action_monitor_period_ = rclcpp::Rate(tool_contact_params.action_monitor_rate).period();
150152
return controller_interface::CallbackReturn::SUCCESS;
151153
}
152154

@@ -166,7 +168,7 @@ ToolContactController::on_deactivate(const rclcpp_lifecycle::State& /* previous_
166168
if (tool_contact_active_) {
167169
tool_contact_active_ = false;
168170
if (!tool_contact_status_interface_->get().set_value(TOOL_CONTACT_WAITING_END)) {
169-
failed_update();
171+
RCLCPP_FATAL(get_node()->get_logger(), "Controller failed to update command interface.");
170172
return controller_interface::CallbackReturn::ERROR;
171173
}
172174
}
@@ -209,11 +211,26 @@ void ToolContactController::goal_accepted_callback(
209211
rt_goal->execute();
210212
rt_active_goal_.writeFromNonRT(rt_goal);
211213
goal_handle_timer_.reset();
212-
goal_handle_timer_ = get_node()->create_wall_timer(action_monitor_period_.to_chrono<std::chrono::nanoseconds>(),
213-
std::bind(&RealtimeGoalHandle::runNonRealtime, rt_goal));
214+
goal_handle_timer_ =
215+
get_node()->create_wall_timer(action_monitor_period_, std::bind(&ToolContactController::action_handler, rt_goal));
214216
return;
215217
}
216218

219+
void ToolContactController::action_handler(RealtimeGoalHandlePtr rt_goal)
220+
{
221+
const auto active_goal = *rt_active_goal_.readFromNonRT();
222+
if (active_goal) {
223+
// Save the value if any of the goal ending conditions have been activated
224+
static bool reset_goal = active_goal->req_abort_ | active_goal->req_cancel_ | active_goal->req_succeed_;
225+
// Allow the goal to handle any actions it needs to perform
226+
rt_goal->runNonRealtime();
227+
// If one of the goal ending conditions were met, reset our active goal pointer
228+
if (reset_goal) {
229+
rt_active_goal_.writeFromNonRT(RealtimeGoalHandlePtr());
230+
}
231+
}
232+
}
233+
217234
rclcpp_action::CancelResponse ToolContactController::goal_cancelled_callback(
218235
const std::shared_ptr<rclcpp_action::ServerGoalHandle<ur_msgs::action::ToolContact>> goal_handle)
219236
{
@@ -234,27 +251,19 @@ rclcpp_action::CancelResponse ToolContactController::goal_cancelled_callback(
234251
return rclcpp_action::CancelResponse::ACCEPT;
235252
}
236253

237-
controller_interface::return_type ToolContactController::failed_update()
238-
{
239-
RCLCPP_FATAL(get_node()->get_logger(), "Controller failed to update or read command/state interface.");
240-
return controller_interface::return_type::ERROR;
241-
}
242-
243254
controller_interface::return_type ToolContactController::update(const rclcpp::Time& /* time */,
244255
const rclcpp::Duration& /* period */)
245256
{
257+
static bool write_success = true;
258+
246259
// Abort takes priority
247260
if (tool_contact_abort_) {
248261
tool_contact_abort_ = false;
249262
tool_contact_enable_ = false;
250-
if (!tool_contact_status_interface_->get().set_value(TOOL_CONTACT_WAITING_END)) {
251-
return failed_update();
252-
}
263+
write_success &= tool_contact_status_interface_->get().set_value(TOOL_CONTACT_WAITING_END);
253264
} else if (tool_contact_enable_) {
254265
tool_contact_enable_ = false;
255-
if (!tool_contact_status_interface_->get().set_value(TOOL_CONTACT_WAITING_BEGIN)) {
256-
return failed_update();
257-
}
266+
write_success &= tool_contact_status_interface_->get().set_value(TOOL_CONTACT_WAITING_BEGIN);
258267
}
259268

260269
const auto active_goal = *rt_active_goal_.readFromRT();
@@ -272,27 +281,22 @@ controller_interface::return_type ToolContactController::update(const rclcpp::Ti
272281
if (result == 0.0) {
273282
tool_contact_active_ = false;
274283
RCLCPP_INFO(get_node()->get_logger(), "Tool contact finished successfully.");
275-
if (!tool_contact_status_interface_->get().set_value(TOOL_CONTACT_WAITING_END)) {
276-
return failed_update();
277-
}
284+
285+
write_success &= tool_contact_status_interface_->get().set_value(TOOL_CONTACT_WAITING_END);
278286
if (active_goal) {
279287
auto result = std::make_shared<ur_msgs::action::ToolContact::Result>();
280288
result->result = ur_msgs::action::ToolContact::Result::SUCCESS;
281289
active_goal->setSucceeded(result);
282-
rt_active_goal_.writeFromNonRT(RealtimeGoalHandlePtr());
283290
}
284291
} else if (result == 1.0) {
285292
tool_contact_active_ = false;
286293
RCLCPP_ERROR(get_node()->get_logger(), "Tool contact aborted by hardware.");
287294

288-
if (!tool_contact_status_interface_->get().set_value(TOOL_CONTACT_STANDBY)) {
289-
return failed_update();
290-
}
295+
write_success &= tool_contact_status_interface_->get().set_value(TOOL_CONTACT_STANDBY);
291296
if (active_goal) {
292297
auto result = std::make_shared<ur_msgs::action::ToolContact::Result>();
293298
result->result = ur_msgs::action::ToolContact::Result::ABORTED_BY_HARDWARE;
294299
active_goal->setAborted(result);
295-
rt_active_goal_.writeFromNonRT(RealtimeGoalHandlePtr());
296300
}
297301
}
298302
} break;
@@ -301,40 +305,33 @@ controller_interface::return_type ToolContactController::update(const rclcpp::Ti
301305
{
302306
RCLCPP_ERROR(get_node()->get_logger(), "Tool contact could not be enabled.");
303307
tool_contact_active_ = false;
304-
if (!tool_contact_status_interface_->get().set_value(TOOL_CONTACT_STANDBY)) {
305-
return failed_update();
306-
}
308+
write_success &= tool_contact_status_interface_->get().set_value(TOOL_CONTACT_STANDBY);
307309

308310
if (active_goal) {
309311
auto result = std::make_shared<ur_msgs::action::ToolContact::Result>();
310312
result->result = ur_msgs::action::ToolContact::Result::ABORTED_BY_HARDWARE;
311313
active_goal->setAborted(result);
312-
rt_active_goal_.writeFromNonRT(RealtimeGoalHandlePtr());
313314
}
314315
} break;
315316

316317
case static_cast<int>(TOOL_CONTACT_SUCCESS_END):
317318
{
318319
RCLCPP_INFO(get_node()->get_logger(), "Tool contact disabled successfully.");
319320
tool_contact_active_ = false;
320-
if (!tool_contact_status_interface_->get().set_value(TOOL_CONTACT_STANDBY)) {
321-
return failed_update();
322-
}
321+
322+
write_success &= tool_contact_status_interface_->get().set_value(TOOL_CONTACT_STANDBY);
323323
} break;
324324

325325
case static_cast<int>(TOOL_CONTACT_FAILURE_END):
326326
{
327327
RCLCPP_ERROR(get_node()->get_logger(), "Tool contact could not be disabled.");
328328

329-
if (!tool_contact_status_interface_->get().set_value(TOOL_CONTACT_STANDBY)) {
330-
return failed_update();
331-
}
329+
write_success &= tool_contact_status_interface_->get().set_value(TOOL_CONTACT_STANDBY);
332330

333331
if (active_goal) {
334332
auto result = std::make_shared<ur_msgs::action::ToolContact::Result>();
335333
result->result = ur_msgs::action::ToolContact::Result::ABORTED_BY_HARDWARE;
336334
active_goal->setAborted(result);
337-
rt_active_goal_.writeFromNonRT(RealtimeGoalHandlePtr());
338335
}
339336
} break;
340337
case static_cast<int>(TOOL_CONTACT_STANDBY):
@@ -348,6 +345,10 @@ controller_interface::return_type ToolContactController::update(const rclcpp::Ti
348345
} else {
349346
tool_contact_active_state_interface = static_cast<double>(tool_contact_active_);
350347
}
348+
if (!write_success) {
349+
RCLCPP_FATAL(get_node()->get_logger(), "Controller failed to update or read command/state interface.");
350+
return controller_interface::return_type::ERROR;
351+
}
351352
return controller_interface::return_type::OK;
352353
}
353354

ur_controllers/src/tool_contact_controller_parameters.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,8 @@ tool_contact_controller:
44
default_value: "",
55
description: "Urdf prefix of the corresponding arm"
66
}
7+
action_monitor_rate: {
8+
type: double,
9+
default_value: 20.0,
10+
description: "The rate at which the action should be monitored in Hz."
11+
}

0 commit comments

Comments
 (0)