@@ -177,12 +177,18 @@ controller_interface::CallbackReturn
177177ToolContactController::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
237253void 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