Skip to content

Commit 188d28f

Browse files
URJalaurfeex
authored andcommitted
Add retry for realtime boxes outside realtime thread in tool contact controller.
1 parent 9e2e5d5 commit 188d28f

File tree

2 files changed

+52
-31
lines changed

2 files changed

+52
-31
lines changed

ur_controllers/include/ur_controllers/tool_contact_controller.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ class ToolContactController : public controller_interface::ControllerInterface
9292
RealtimeGoalHandleBuffer rt_active_goal_; ///< Currently active action goal, if any.
9393
ur_msgs::action::ToolContact::Feedback::SharedPtr feedback_; ///< preallocated feedback
9494
rclcpp::TimerBase::SharedPtr goal_handle_timer_; ///< Timer to frequently check on the running goal
95-
std::optional<RealtimeGoalHandlePtr> get_rt_buffer();
95+
std::optional<RealtimeGoalHandlePtr> get_rt_goal_from_non_rt();
96+
bool set_rt_goal_from_non_rt(const RealtimeGoalHandlePtr& goal_handle);
9697

9798
// non-rt function that will be called with action_monitor_period to monitor the rt action
9899
rclcpp::Duration action_monitor_period_ = rclcpp::Duration::from_seconds(0.05);

ur_controllers/src/tool_contact_controller.cpp

Lines changed: 50 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -177,18 +177,17 @@ controller_interface::CallbackReturn
177177
ToolContactController::on_deactivate(const rclcpp_lifecycle::State& /* previous_state */)
178178
{
179179
// Abort active goal (if any)
180-
const auto active_goal = get_rt_buffer();
181-
182-
if (!active_goal.has_value()) {
183-
RCLCPP_ERROR(get_node()->get_logger(), "Failed to read active goal, aborting deactivation of controller.");
180+
RealtimeGoalHandlePtr active_goal;
181+
if (!rt_active_goal_.try_get([&active_goal](const RealtimeGoalHandlePtr& goal) { active_goal = goal; })) {
182+
RCLCPP_ERROR(get_node()->get_logger(), "Failed to read active goal, deactivation of controller failed.");
184183
return controller_interface::CallbackReturn::ERROR;
185184
}
186185

187-
if (active_goal.value()) {
186+
if (active_goal) {
188187
RCLCPP_INFO(get_node()->get_logger(), "Aborting tool contact, as controller has been deactivated.");
189188
// Mark the current goal as abort
190189
auto result = std::make_shared<ur_msgs::action::ToolContact::Result>();
191-
active_goal.value()->setAborted(result);
190+
active_goal->setAborted(result);
192191
should_reset_goal = true;
193192
}
194193
if (tool_contact_active_) {
@@ -216,10 +215,10 @@ rclcpp_action::GoalResponse ToolContactController::goal_received_callback(
216215
return rclcpp_action::GoalResponse::REJECT;
217216
}
218217

219-
const auto active_goal = get_rt_buffer();
218+
const auto active_goal = get_rt_goal_from_non_rt();
220219

221220
if (!active_goal.has_value()) {
222-
RCLCPP_ERROR(get_node()->get_logger(), "Failed to read active goal, rejecting goal.");
221+
RCLCPP_ERROR(get_node()->get_logger(), "Failed to read if active goal is present, rejecting goal.");
223222
return rclcpp_action::GoalResponse::REJECT;
224223
}
225224

@@ -236,13 +235,15 @@ void ToolContactController::goal_accepted_callback(
236235
RCLCPP_INFO(get_node()->get_logger(), "Goal accepted.");
237236
tool_contact_enable_ = true;
238237
tool_contact_abort_ = false;
238+
239239
RealtimeGoalHandlePtr rt_goal = std::make_shared<RealtimeGoalHandle>(goal_handle);
240-
rt_goal->execute();
241-
bool write_success;
242-
write_success = rt_active_goal_.try_set([&rt_goal](RealtimeGoalHandlePtr& goal) { goal = rt_goal; });
243-
if (!write_success) {
244-
RCLCPP_ERROR(get_node()->get_logger(), "Failed to set active goal.");
240+
if (!set_rt_goal_from_non_rt(rt_goal)) {
241+
RCLCPP_ERROR(get_node()->get_logger(), "Failed to set active goal in realtime box, aborting goal.");
242+
goal_handle->abort(std::make_shared<ur_msgs::action::ToolContact::Result>());
243+
return;
245244
}
245+
246+
rt_goal->execute();
246247
goal_handle_timer_.reset();
247248
auto period = std::chrono::duration_cast<std::chrono::nanoseconds>(
248249
std::chrono::nanoseconds(action_monitor_period_.nanoseconds()));
@@ -252,7 +253,7 @@ void ToolContactController::goal_accepted_callback(
252253

253254
void ToolContactController::action_handler()
254255
{
255-
const auto active_goal = get_rt_buffer();
256+
const auto active_goal = get_rt_goal_from_non_rt();
256257
if (!active_goal.has_value()) {
257258
RCLCPP_ERROR(get_node()->get_logger(), "Failed to read active goal, aborting action handler.");
258259
return;
@@ -262,8 +263,9 @@ void ToolContactController::action_handler()
262263
active_goal.value()->runNonRealtime();
263264
// If one of the goal ending conditions were met, reset our active goal pointer
264265
if (should_reset_goal) {
265-
rt_active_goal_.try_set([](RealtimeGoalHandlePtr& goal) { goal = RealtimeGoalHandlePtr(); });
266-
should_reset_goal = false;
266+
if (set_rt_goal_from_non_rt(RealtimeGoalHandlePtr())) {
267+
should_reset_goal = false;
268+
}
267269
}
268270
}
269271
}
@@ -272,7 +274,7 @@ rclcpp_action::CancelResponse ToolContactController::goal_canceled_callback(
272274
const std::shared_ptr<rclcpp_action::ServerGoalHandle<ur_msgs::action::ToolContact>> goal_handle)
273275
{
274276
// Check that cancel request refers to currently active goal (if any)
275-
const auto active_goal = get_rt_buffer();
277+
const auto active_goal = get_rt_goal_from_non_rt();
276278
if (!active_goal.has_value()) {
277279
RCLCPP_ERROR(get_node()->get_logger(), "Failed to read active goal, rejecting cancel.");
278280
return rclcpp_action::CancelResponse::REJECT;
@@ -307,8 +309,8 @@ controller_interface::return_type ToolContactController::update(const rclcpp::Ti
307309
write_success &= tool_contact_set_state_interface_->get().set_value(TOOL_CONTACT_WAITING_BEGIN);
308310
}
309311

310-
const auto active_goal = get_rt_buffer();
311-
if (!active_goal.has_value()) {
312+
RealtimeGoalHandlePtr active_goal;
313+
if (!rt_active_goal_.try_get([&active_goal](const RealtimeGoalHandlePtr& goal) { active_goal = goal; })) {
312314
RCLCPP_ERROR(get_node()->get_logger(), "Failed to read active goal, skipping update cycle.");
313315
return controller_interface::return_type::OK;
314316
}
@@ -341,7 +343,7 @@ controller_interface::return_type ToolContactController::update(const rclcpp::Ti
341343
write_success &= tool_contact_set_state_interface_->get().set_value(TOOL_CONTACT_WAITING_END);
342344
if (active_goal) {
343345
auto result = std::make_shared<ur_msgs::action::ToolContact::Result>();
344-
active_goal.value()->setSucceeded(result);
346+
active_goal->setSucceeded(result);
345347
should_reset_goal = true;
346348
}
347349
} else if (result.value() == 1.0) {
@@ -351,7 +353,7 @@ controller_interface::return_type ToolContactController::update(const rclcpp::Ti
351353
write_success &= tool_contact_set_state_interface_->get().set_value(TOOL_CONTACT_STANDBY);
352354
if (active_goal) {
353355
auto result = std::make_shared<ur_msgs::action::ToolContact::Result>();
354-
active_goal.value()->setAborted(result);
356+
active_goal->setAborted(result);
355357
should_reset_goal = true;
356358
}
357359
}
@@ -365,7 +367,7 @@ controller_interface::return_type ToolContactController::update(const rclcpp::Ti
365367

366368
if (active_goal) {
367369
auto result = std::make_shared<ur_msgs::action::ToolContact::Result>();
368-
active_goal.value()->setAborted(result);
370+
active_goal->setAborted(result);
369371
should_reset_goal = true;
370372
}
371373
} break;
@@ -388,7 +390,7 @@ controller_interface::return_type ToolContactController::update(const rclcpp::Ti
388390

389391
if (active_goal) {
390392
auto result = std::make_shared<ur_msgs::action::ToolContact::Result>();
391-
active_goal.value()->setAborted(result);
393+
active_goal->setAborted(result);
392394
should_reset_goal = true;
393395
}
394396
} break;
@@ -398,8 +400,8 @@ controller_interface::return_type ToolContactController::update(const rclcpp::Ti
398400
default:
399401
break;
400402
}
401-
if (active_goal.value()) {
402-
active_goal.value()->setFeedback(feedback_);
403+
if (active_goal) {
404+
active_goal->setFeedback(feedback_);
403405
}
404406

405407
if (!write_success) {
@@ -409,17 +411,35 @@ controller_interface::return_type ToolContactController::update(const rclcpp::Ti
409411
return controller_interface::return_type::OK;
410412
}
411413

412-
std::optional<ToolContactController::RealtimeGoalHandlePtr> ToolContactController::get_rt_buffer()
414+
std::optional<ToolContactController::RealtimeGoalHandlePtr> ToolContactController::get_rt_goal_from_non_rt()
413415
{
414416
RealtimeGoalHandlePtr active_goal = nullptr;
415-
const bool read_success =
416-
rt_active_goal_.try_get([&active_goal](const RealtimeGoalHandlePtr& goal) { active_goal = goal; });
417-
if (!read_success) {
418-
return std::nullopt;
417+
int tries = 0;
418+
while (!rt_active_goal_.try_get([&active_goal](const RealtimeGoalHandlePtr& goal) { active_goal = goal; })) {
419+
if (tries > 9) {
420+
RCLCPP_ERROR(get_node()->get_logger(), "Failed to read active goal.");
421+
return std::nullopt;
422+
}
423+
rclcpp::sleep_for(std::chrono::milliseconds(50));
424+
tries++;
419425
}
420426
return active_goal;
421427
}
422428

429+
bool ToolContactController::set_rt_goal_from_non_rt(const RealtimeGoalHandlePtr& goal_handle)
430+
{
431+
int tries = 0;
432+
while (!rt_active_goal_.try_set([&goal_handle](RealtimeGoalHandlePtr& goal) { goal = goal_handle; })) {
433+
if (tries > 9) {
434+
RCLCPP_ERROR(get_node()->get_logger(), "Failed to set active goal.");
435+
return false;
436+
}
437+
rclcpp::sleep_for(std::chrono::milliseconds(50));
438+
tries++;
439+
}
440+
return true;
441+
}
442+
423443
} // namespace ur_controllers
424444

425445
#include "pluginlib/class_list_macros.hpp"

0 commit comments

Comments
 (0)