Skip to content

Commit cc5fcdd

Browse files
URJalaurfeex
authored andcommitted
Update tool contact controller to use RealtimeThreadSafeBox
1 parent ecb9c04 commit cc5fcdd

File tree

2 files changed

+65
-22
lines changed

2 files changed

+65
-22
lines changed

ur_controllers/include/ur_controllers/tool_contact_controller.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,9 @@
5353
#include <rclcpp_action/server_goal_handle.hpp>
5454
#include <rclcpp/duration.hpp>
5555

56-
#include <realtime_tools/realtime_buffer.hpp>
56+
#include <realtime_tools/realtime_thread_safe_box.hpp>
5757
#include <realtime_tools/realtime_server_goal_handle.hpp>
58+
#include <realtime_tools/lock_free_queue.hpp>
5859

5960
#include <ur_msgs/action/tool_contact.hpp>
6061
#include "ur_controllers/tool_contact_controller_parameters.hpp"
@@ -86,11 +87,12 @@ class ToolContactController : public controller_interface::ControllerInterface
8687
private:
8788
using RealtimeGoalHandle = realtime_tools::RealtimeServerGoalHandle<ur_msgs::action::ToolContact>;
8889
using RealtimeGoalHandlePtr = std::shared_ptr<RealtimeGoalHandle>;
89-
using RealtimeGoalHandleBuffer = realtime_tools::RealtimeBuffer<RealtimeGoalHandlePtr>;
90+
using RealtimeGoalHandleBuffer = realtime_tools::RealtimeThreadSafeBox<RealtimeGoalHandlePtr>;
9091

9192
RealtimeGoalHandleBuffer rt_active_goal_; ///< Currently active action goal, if any.
9293
ur_msgs::action::ToolContact::Feedback::SharedPtr feedback_; ///< preallocated feedback
9394
rclcpp::TimerBase::SharedPtr goal_handle_timer_; ///< Timer to frequently check on the running goal
95+
std::optional<RealtimeGoalHandlePtr> get_rt_buffer();
9496

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

ur_controllers/src/tool_contact_controller.cpp

Lines changed: 61 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -177,12 +177,18 @@ 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 = *rt_active_goal_.readFromRT();
181-
if (active_goal) {
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.");
184+
return controller_interface::CallbackReturn::ERROR;
185+
}
186+
187+
if (active_goal.value()) {
182188
RCLCPP_INFO(get_node()->get_logger(), "Aborting tool contact, as controller has been deactivated.");
183189
// Mark the current goal as abort
184190
auto result = std::make_shared<ur_msgs::action::ToolContact::Result>();
185-
active_goal->setAborted(result);
191+
active_goal.value()->setAborted(result);
186192
should_reset_goal = true;
187193
}
188194
if (tool_contact_active_) {
@@ -210,8 +216,14 @@ rclcpp_action::GoalResponse ToolContactController::goal_received_callback(
210216
return rclcpp_action::GoalResponse::REJECT;
211217
}
212218

213-
const auto active_goal = *rt_active_goal_.readFromNonRT();
214-
if (active_goal) {
219+
const auto active_goal = get_rt_buffer();
220+
221+
if (!active_goal.has_value()) {
222+
RCLCPP_ERROR(get_node()->get_logger(), "Failed to read active goal, rejecting goal.");
223+
return rclcpp_action::GoalResponse::REJECT;
224+
}
225+
226+
if (active_goal.value()) {
215227
RCLCPP_ERROR(get_node()->get_logger(), "Tool contact already active, rejecting goal.");
216228
return rclcpp_action::GoalResponse::REJECT;
217229
}
@@ -226,7 +238,11 @@ void ToolContactController::goal_accepted_callback(
226238
tool_contact_abort_ = false;
227239
RealtimeGoalHandlePtr rt_goal = std::make_shared<RealtimeGoalHandle>(goal_handle);
228240
rt_goal->execute();
229-
rt_active_goal_.writeFromNonRT(rt_goal);
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.");
245+
}
230246
goal_handle_timer_.reset();
231247
auto period = std::chrono::duration_cast<std::chrono::nanoseconds>(
232248
std::chrono::nanoseconds(action_monitor_period_.nanoseconds()));
@@ -236,13 +252,17 @@ void ToolContactController::goal_accepted_callback(
236252

237253
void ToolContactController::action_handler()
238254
{
239-
const auto active_goal = *rt_active_goal_.readFromNonRT();
240-
if (active_goal) {
255+
const auto active_goal = get_rt_buffer();
256+
if (!active_goal.has_value()) {
257+
RCLCPP_ERROR(get_node()->get_logger(), "Failed to read active goal, aborting action handler.");
258+
return;
259+
}
260+
if (active_goal.value()) {
241261
// Allow the goal to handle any actions it needs to perform
242-
active_goal->runNonRealtime();
262+
active_goal.value()->runNonRealtime();
243263
// If one of the goal ending conditions were met, reset our active goal pointer
244264
if (should_reset_goal) {
245-
rt_active_goal_.writeFromNonRT(RealtimeGoalHandlePtr());
265+
rt_active_goal_.try_set([](RealtimeGoalHandlePtr& goal) { goal = RealtimeGoalHandlePtr(); });
246266
should_reset_goal = false;
247267
}
248268
}
@@ -252,13 +272,18 @@ rclcpp_action::CancelResponse ToolContactController::goal_canceled_callback(
252272
const std::shared_ptr<rclcpp_action::ServerGoalHandle<ur_msgs::action::ToolContact>> goal_handle)
253273
{
254274
// Check that cancel request refers to currently active goal (if any)
255-
const auto active_goal = *rt_active_goal_.readFromNonRT();
256-
if (active_goal && active_goal->gh_ == goal_handle) {
275+
const auto active_goal = get_rt_buffer();
276+
if (!active_goal.has_value()) {
277+
RCLCPP_ERROR(get_node()->get_logger(), "Failed to read active goal, rejecting cancel.");
278+
return rclcpp_action::CancelResponse::REJECT;
279+
}
280+
281+
if (active_goal.value() && active_goal.value()->gh_ == goal_handle) {
257282
RCLCPP_INFO(get_node()->get_logger(), "Cancel tool contact requested.");
258283

259284
// Mark the current goal as canceled
260285
auto result = std::make_shared<ur_msgs::action::ToolContact::Result>();
261-
active_goal->setCanceled(result);
286+
active_goal.value()->setCanceled(result);
262287
should_reset_goal = true;
263288
tool_contact_abort_ = true;
264289
tool_contact_enable_ = false;
@@ -282,7 +307,12 @@ controller_interface::return_type ToolContactController::update(const rclcpp::Ti
282307
write_success &= tool_contact_set_state_interface_->get().set_value(TOOL_CONTACT_WAITING_BEGIN);
283308
}
284309

285-
const auto active_goal = *rt_active_goal_.readFromRT();
310+
const auto active_goal = get_rt_buffer();
311+
if (!active_goal.has_value()) {
312+
RCLCPP_ERROR(get_node()->get_logger(), "Failed to read active goal, skipping update cycle.");
313+
return controller_interface::return_type::OK;
314+
}
315+
286316
std::optional<double> state_optional = tool_contact_state_interface_->get().get_optional();
287317

288318
if (!state_optional) {
@@ -311,7 +341,7 @@ controller_interface::return_type ToolContactController::update(const rclcpp::Ti
311341
write_success &= tool_contact_set_state_interface_->get().set_value(TOOL_CONTACT_WAITING_END);
312342
if (active_goal) {
313343
auto result = std::make_shared<ur_msgs::action::ToolContact::Result>();
314-
active_goal->setSucceeded(result);
344+
active_goal.value()->setSucceeded(result);
315345
should_reset_goal = true;
316346
}
317347
} else if (result.value() == 1.0) {
@@ -321,7 +351,7 @@ controller_interface::return_type ToolContactController::update(const rclcpp::Ti
321351
write_success &= tool_contact_set_state_interface_->get().set_value(TOOL_CONTACT_STANDBY);
322352
if (active_goal) {
323353
auto result = std::make_shared<ur_msgs::action::ToolContact::Result>();
324-
active_goal->setAborted(result);
354+
active_goal.value()->setAborted(result);
325355
should_reset_goal = true;
326356
}
327357
}
@@ -335,7 +365,7 @@ controller_interface::return_type ToolContactController::update(const rclcpp::Ti
335365

336366
if (active_goal) {
337367
auto result = std::make_shared<ur_msgs::action::ToolContact::Result>();
338-
active_goal->setAborted(result);
368+
active_goal.value()->setAborted(result);
339369
should_reset_goal = true;
340370
}
341371
} break;
@@ -358,7 +388,7 @@ controller_interface::return_type ToolContactController::update(const rclcpp::Ti
358388

359389
if (active_goal) {
360390
auto result = std::make_shared<ur_msgs::action::ToolContact::Result>();
361-
active_goal->setAborted(result);
391+
active_goal.value()->setAborted(result);
362392
should_reset_goal = true;
363393
}
364394
} break;
@@ -368,8 +398,8 @@ controller_interface::return_type ToolContactController::update(const rclcpp::Ti
368398
default:
369399
break;
370400
}
371-
if (active_goal) {
372-
active_goal->setFeedback(feedback_);
401+
if (active_goal.value()) {
402+
active_goal.value()->setFeedback(feedback_);
373403
}
374404

375405
if (!write_success) {
@@ -379,6 +409,17 @@ controller_interface::return_type ToolContactController::update(const rclcpp::Ti
379409
return controller_interface::return_type::OK;
380410
}
381411

412+
std::optional<ToolContactController::RealtimeGoalHandlePtr> ToolContactController::get_rt_buffer()
413+
{
414+
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;
419+
}
420+
return active_goal;
421+
}
422+
382423
} // namespace ur_controllers
383424

384425
#include "pluginlib/class_list_macros.hpp"

0 commit comments

Comments
 (0)