@@ -65,7 +65,7 @@ controller_interface::CallbackReturn PassthroughTrajectoryController::on_init()
6565 passthrough_params_ = passthrough_param_listener_->get_params ();
6666 current_index_ = 0 ;
6767 auto joint_names = passthrough_params_.joints ;
68- joint_names_.writeFromNonRT (joint_names);
68+ joint_names_.try_set (joint_names);
6969 number_of_joints_ = joint_names.size ();
7070 state_interface_types_ = passthrough_params_.state_interfaces ;
7171 scaling_factor_ = 1.0 ;
@@ -83,7 +83,12 @@ PassthroughTrajectoryController::on_configure(const rclcpp_lifecycle::State& pre
8383
8484 joint_state_interface_names_.reserve (number_of_joints_ * state_interface_types_.size ());
8585
86- auto joint_names_internal = joint_names_.readFromRT ();
86+ auto joint_names_internal = joint_names_.try_get ();
87+ if (!joint_names_internal) {
88+ RCLCPP_ERROR (get_node ()->get_logger (), " Joint names could not be read, cannot configure controller." );
89+ return controller_interface::CallbackReturn::ERROR;
90+ }
91+
8792 for (const auto & joint_name : *joint_names_internal) {
8893 for (const auto & interface_type : state_interface_types_) {
8994 joint_state_interface_names_.emplace_back (joint_name + " /" + interface_type);
@@ -228,12 +233,22 @@ controller_interface::CallbackReturn PassthroughTrajectoryController::on_deactiv
228233 return controller_interface::CallbackReturn::ERROR;
229234 }
230235 if (trajectory_active_) {
231- const auto active_goal = *rt_active_goal_.readFromRT ();
236+ RealtimeGoalHandlePtr active_goal = nullptr ;
237+ bool success = rt_active_goal_.try_get ([&active_goal](const RealtimeGoalHandlePtr& goal) { active_goal = goal; });
238+ if (!success) {
239+ RCLCPP_ERROR (get_node ()->get_logger (), " Could not read active goal from realtime buffer, deactivation of "
240+ " controller failed." );
241+ return controller_interface::CallbackReturn::ERROR;
242+ }
232243 std::shared_ptr<control_msgs::action::FollowJointTrajectory::Result> result =
233244 std::make_shared<control_msgs::action::FollowJointTrajectory::Result>();
234245 result->set__error_string (" Aborting current goal, since the controller is being deactivated." );
235246 active_goal->setAborted (result);
236- rt_active_goal_.writeFromNonRT (RealtimeGoalHandlePtr ());
247+ success = rt_active_goal_.try_set ([](RealtimeGoalHandlePtr& goal) { goal = RealtimeGoalHandlePtr (); });
248+ if (!success) {
249+ RCLCPP_ERROR (get_node ()->get_logger (), " Failed to set active goal, deactivation of controller failed." );
250+ return controller_interface::CallbackReturn::ERROR;
251+ }
237252 end_goal ();
238253 }
239254 return CallbackReturn::SUCCESS;
@@ -242,7 +257,13 @@ controller_interface::CallbackReturn PassthroughTrajectoryController::on_deactiv
242257controller_interface::return_type PassthroughTrajectoryController::update (const rclcpp::Time& /* time*/ ,
243258 const rclcpp::Duration& period)
244259{
245- const auto active_goal = *rt_active_goal_.readFromRT ();
260+ RealtimeGoalHandlePtr active_goal = nullptr ;
261+ const bool read_success =
262+ rt_active_goal_.try_get ([&active_goal](const RealtimeGoalHandlePtr& goal) { active_goal = goal; });
263+ if (!read_success) {
264+ RCLCPP_ERROR (get_node ()->get_logger (), " Could not read active goal from realtime buffer, skipping cycle." );
265+ return controller_interface::return_type::OK;
266+ }
246267
247268 const auto current_transfer_state = transfer_command_interface_->get ().get_optional ().value_or (TRANSFER_STATE_IDLE);
248269
@@ -272,8 +293,18 @@ controller_interface::return_type PassthroughTrajectoryController::update(const
272293 write_success &=
273294 trajectory_size_command_interface_->get ().set_value (static_cast <double >(active_joint_traj_.points .size ()));
274295 }
275- auto active_goal_time_tol = goal_time_tolerance_.readFromRT ();
276- auto joint_mapping = joint_trajectory_mapping_.readFromRT ();
296+
297+ auto active_goal_time_tol = goal_time_tolerance_.try_get ();
298+ if (!active_goal_time_tol) {
299+ RCLCPP_ERROR (get_node ()->get_logger (), " Could not read goal time tolerance, skipping cycle." );
300+ return controller_interface::return_type::OK;
301+ }
302+
303+ auto joint_mapping = joint_trajectory_mapping_.try_get ();
304+ if (!joint_mapping) {
305+ RCLCPP_ERROR (get_node ()->get_logger (), " Could not read joint trajectory mapping, skipping cycle." );
306+ return controller_interface::return_type::OK;
307+ }
277308
278309 // Write a new point to the command interface, if the previous point has been read by the hardware interface.
279310 if (current_transfer_state == TRANSFER_STATE_WAITING_FOR_POINT) {
@@ -283,7 +314,12 @@ controller_interface::return_type PassthroughTrajectoryController::update(const
283314 duration_to_double (active_joint_traj_.points [current_index_].time_from_start ));
284315
285316 // Write the positions for each joint of the robot
286- auto joint_names_internal = joint_names_.readFromRT ();
317+ auto joint_names_internal = joint_names_.try_get ();
318+ if (!joint_names_internal) {
319+ RCLCPP_ERROR (get_node ()->get_logger (), " Could not read joint names, skipping cycle." );
320+ return controller_interface::return_type::OK;
321+ }
322+
287323 // We've added the joint interfaces matching the order of the joint names so we can safely access
288324 // them by the index.
289325 for (size_t i = 0 ; i < number_of_joints_; i++) {
@@ -422,7 +458,12 @@ bool PassthroughTrajectoryController::check_goal_tolerances(
422458 std::shared_ptr<const control_msgs::action::FollowJointTrajectory::Goal> goal)
423459{
424460 auto & tolerances = goal->goal_tolerance ;
425- auto joint_names_internal = joint_names_.readFromRT ();
461+ auto joint_names_internal = joint_names_.try_get ();
462+ if (!joint_names_internal) {
463+ RCLCPP_ERROR (get_node ()->get_logger (), " Joint names could not be read, cannot check tolerances." );
464+ return false ;
465+ }
466+
426467 if (!tolerances.empty ()) {
427468 for (auto & tol : tolerances) {
428469 auto found_it = std::find (joint_names_internal->begin (), joint_names_internal->end (), tol.name );
@@ -526,14 +567,26 @@ rclcpp_action::CancelResponse PassthroughTrajectoryController::goal_cancelled_ca
526567 const std::shared_ptr<rclcpp_action::ServerGoalHandle<control_msgs::action::FollowJointTrajectory>> goal_handle)
527568{
528569 // Check that cancel request refers to currently active goal (if any)
529- const auto active_goal = *rt_active_goal_.readFromNonRT ();
570+ RealtimeGoalHandlePtr active_goal = nullptr ;
571+ while (!rt_active_goal_.try_get ([&active_goal](const RealtimeGoalHandlePtr& goal) { active_goal = goal; })) {
572+ // Wait until we can read the active goal from the realtime buffer
573+ RCLCPP_WARN (get_node ()->get_logger (), " Waiting for active goal to be set, retrying cancel request." );
574+ rclcpp::sleep_for (std::chrono::milliseconds (50 ));
575+ }
576+
530577 if (active_goal && active_goal->gh_ == goal_handle) {
531578 RCLCPP_INFO (get_node ()->get_logger (), " Cancelling active trajectory requested." );
532579
533580 // Mark the current goal as canceled
534581 auto result = std::make_shared<FollowJTrajAction::Result>();
535582 active_goal->setCanceled (result);
536- rt_active_goal_.writeFromNonRT (RealtimeGoalHandlePtr ());
583+
584+ while (!rt_active_goal_.try_set ([](RealtimeGoalHandlePtr& goal) { goal = RealtimeGoalHandlePtr (); })) {
585+ // Wait until we can set the active goal to nullptr
586+ RCLCPP_WARN (get_node ()->get_logger (), " Waiting for active goal to be set, retrying cancel request." );
587+ rclcpp::sleep_for (std::chrono::milliseconds (50 ));
588+ }
589+
537590 trajectory_active_ = false ;
538591 }
539592 return rclcpp_action::CancelResponse::ACCEPT;
@@ -548,13 +601,21 @@ void PassthroughTrajectoryController::goal_accepted_callback(
548601 current_index_ = 0 ;
549602
550603 // TODO(fexner): Merge goal tolerances with default tolerances
551-
552- joint_trajectory_mapping_.writeFromNonRT (create_joint_mapping (goal_handle->get_goal ()->trajectory .joint_names ));
604+ bool write_success =
605+ joint_trajectory_mapping_.try_set (create_joint_mapping (goal_handle->get_goal ()->trajectory .joint_names ));
606+ if (!write_success) {
607+ RCLCPP_ERROR (get_node ()->get_logger (), " Failed to set joint trajectory mapping." );
608+ return ;
609+ }
553610
554611 // sort goal tolerances to match internal joint order
555612 std::vector<control_msgs::msg::JointTolerance> goal_tolerances;
556613 if (!goal_handle->get_goal ()->goal_tolerance .empty ()) {
557- auto joint_names_internal = joint_names_.readFromRT ();
614+ auto joint_names_internal = joint_names_.try_get ();
615+ if (!joint_names_internal) {
616+ RCLCPP_ERROR (get_node ()->get_logger (), " Joint names could not be read, cannot set goal tolerances." );
617+ return ;
618+ }
558619 std::stringstream ss;
559620 ss << " Using goal tolerances\n " ;
560621 for (auto & joint_name : *joint_names_internal) {
@@ -569,8 +630,17 @@ void PassthroughTrajectoryController::goal_accepted_callback(
569630 }
570631 RCLCPP_INFO_STREAM (get_node ()->get_logger (), ss.str ());
571632 }
572- goal_tolerance_.writeFromNonRT (goal_tolerances);
573- goal_time_tolerance_.writeFromNonRT (goal_handle->get_goal ()->goal_time_tolerance );
633+ write_success = goal_tolerance_.try_set (goal_tolerances);
634+ if (!write_success) {
635+ RCLCPP_ERROR (get_node ()->get_logger (), " Failed to set goal tolerances." );
636+ return ;
637+ }
638+
639+ write_success = goal_time_tolerance_.try_set (goal_handle->get_goal ()->goal_time_tolerance );
640+ if (!write_success) {
641+ RCLCPP_ERROR (get_node ()->get_logger (), " Failed to set goal time tolerance." );
642+ return ;
643+ }
574644 RCLCPP_INFO_STREAM (get_node ()->get_logger (),
575645 " Goal time tolerance: " << duration_to_double (goal_handle->get_goal ()->goal_time_tolerance )
576646 << " sec" );
@@ -581,7 +651,11 @@ void PassthroughTrajectoryController::goal_accepted_callback(
581651 //
582652 RealtimeGoalHandlePtr rt_goal = std::make_shared<RealtimeGoalHandle>(goal_handle);
583653 rt_goal->execute ();
584- rt_active_goal_.writeFromNonRT (rt_goal);
654+ bool write_success;
655+ write_success = rt_active_goal_.try_set ([&rt_goal](RealtimeGoalHandlePtr& goal) { goal = rt_goal; });
656+ if (!write_success) {
657+ RCLCPP_ERROR (get_node ()->get_logger (), " Failed to set active goal." );
658+ }
585659 goal_handle_timer_.reset ();
586660 goal_handle_timer_ = get_node ()->create_wall_timer (action_monitor_period_.to_chrono <std::chrono::nanoseconds>(),
587661 std::bind (&RealtimeGoalHandle::runNonRealtime, rt_goal));
@@ -591,9 +665,22 @@ void PassthroughTrajectoryController::goal_accepted_callback(
591665
592666bool PassthroughTrajectoryController::check_goal_tolerance ()
593667{
594- auto goal_tolerance = goal_tolerance_.readFromRT ();
595- auto joint_mapping = joint_trajectory_mapping_.readFromRT ();
596- auto joint_names_internal = joint_names_.readFromRT ();
668+ auto goal_tolerance = goal_tolerance_.try_get ();
669+ if (!goal_tolerance) {
670+ RCLCPP_ERROR (get_node ()->get_logger (), " Could not get goal tolerance, cannot check goal tolerance." );
671+ return false ;
672+ }
673+ auto joint_mapping = joint_trajectory_mapping_.try_get ();
674+ if (!joint_mapping) {
675+ RCLCPP_ERROR (get_node ()->get_logger (), " Could not get joint mapping, cannot check goal tolerance." );
676+ return false ;
677+ }
678+ auto joint_names_internal = joint_names_.try_get ();
679+ if (!joint_names_internal) {
680+ RCLCPP_ERROR (get_node ()->get_logger (), " Could not get joint names, cannot check goal tolerance." );
681+ return false ;
682+ }
683+
597684 if (goal_tolerance->empty ()) {
598685 return true ;
599686 }
@@ -650,7 +737,11 @@ std::unordered_map<std::string, size_t>
650737PassthroughTrajectoryController::create_joint_mapping (const std::vector<std::string>& joint_names) const
651738{
652739 std::unordered_map<std::string, size_t > joint_mapping;
653- auto joint_names_internal = joint_names_.readFromNonRT ();
740+ auto joint_names_internal = joint_names_.try_get ();
741+ if (!joint_names_internal) {
742+ RCLCPP_ERROR (get_node ()->get_logger (), " Could not get joint names, cannot create joint mapping." );
743+ }
744+
654745 for (auto & joint_name : *joint_names_internal) {
655746 auto found_it = std::find (joint_names.begin (), joint_names.end (), joint_name);
656747 if (found_it != joint_names.end ()) {
0 commit comments