Skip to content

Commit d64b616

Browse files
Report bt action request error (ros-navigation#6289)
* nav2_msgs: add generic action request error codes Action result definitions used action-specific values for request failures, and several actions lacked the shared request or timeout constants. This prevented BtActionNode from reporting consistent diagnostics. This commit reserves values 1 and 2 for rejected and unsent goals across Nav2 actions and defines the missing timeout values. Signed-off-by: Dylan De Coeyer <dylan.decoeyer@quimesis.be> * nav2_behavior_tree: report generic action request errors Action nodes returned failure without consistently writing diagnostic error codes when a goal was rejected, could not be sent, or timed out. The implementation and tests also evolved across several corrective commits. This commit centralizes request-failure reporting and optional error code fallback in BtActionNode. It updates action nodes to use the shared ports and covers rejected goals, send-goal failures, timeouts, and action-specific error codes. Signed-off-by: Dylan De Coeyer <dylan.decoeyer@quimesis.be> * opennav_docking_bt: use generic action request errors Docking action nodes duplicated the common request-failure handling and error-port declarations from BtActionNode. This commit delegates those responsibilities to the generic BtActionNode implementation. Signed-off-by: Dylan De Coeyer <dylan.decoeyer@quimesis.be> * opennav_docking: stop NodeThread before destroying server The test reset the docking server node while its NodeThread was still active. The executor could then access node resources during teardown, causing a shutdown race and preventing the XML result from being written. This commit leaves node lifetime management to scope teardown, so the NodeThread destructor cancels and joins its executor before the server node is destroyed. Signed-off-by: Dylan De Coeyer <dylan.decoeyer@quimesis.be> --------- Signed-off-by: Dylan De Coeyer <dylan.decoeyer@quimesis.be>
1 parent 33f2b7c commit d64b616

52 files changed

Lines changed: 382 additions & 229 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

nav2_behavior_tree/include/nav2_behavior_tree/bt_action_node.hpp

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <memory>
1919
#include <string>
2020
#include <chrono>
21+
#include <cstdint>
2122

2223
#include "behaviortree_cpp/action_node.h"
2324
#include "behaviortree_cpp/json_export.h"
@@ -40,6 +41,8 @@ template<class ActionT>
4041
class BtActionNode : public BT::ActionNodeBase
4142
{
4243
public:
44+
using ActionResult = typename ActionT::Result;
45+
4346
/**
4447
* @brief A nav2_behavior_tree::BtActionNode constructor
4548
* @param xml_tag_name Name for the XML tag for this node
@@ -73,6 +76,28 @@ class BtActionNode : public BT::ActionNodeBase
7376
goal_ = typename ActionT::Goal();
7477
result_ = typename rclcpp_action::ClientGoalHandle<ActionT>::WrappedResult();
7578

79+
if constexpr (
80+
!requires {ActionT::Result::TIMEOUT;} ||
81+
!requires {ActionT::Result::GOAL_REJECTED;} ||
82+
!requires {ActionT::Result::SEND_GOAL_FAILURE;})
83+
{
84+
if constexpr (requires {ActionT::Result::UNKNOWN;}) {
85+
RCLCPP_WARN(
86+
node_->get_logger(),
87+
"Action type for \"%s\" does not define one or more of the TIMEOUT, "
88+
"GOAL_REJECTED, and SEND_GOAL_FAILURE error codes. UNKNOWN will be "
89+
"used for unavailable errors.",
90+
xml_tag_name.c_str());
91+
} else {
92+
RCLCPP_WARN(
93+
node_->get_logger(),
94+
"Action type for \"%s\" does not define one or more of the TIMEOUT, "
95+
"GOAL_REJECTED, and SEND_GOAL_FAILURE error codes. The error_code_id "
96+
"output will not be set for unavailable errors.",
97+
xml_tag_name.c_str());
98+
}
99+
}
100+
76101
std::string remapped_action_name;
77102
if (getInput("server_name", remapped_action_name)) {
78103
action_name_ = remapped_action_name;
@@ -121,7 +146,9 @@ class BtActionNode : public BT::ActionNodeBase
121146
{
122147
BT::PortsList basic = {
123148
BT::InputPort<std::string>("server_name", "Action server name"),
124-
BT::InputPort<std::chrono::milliseconds>("server_timeout")
149+
BT::InputPort<std::chrono::milliseconds>("server_timeout"),
150+
BT::OutputPort<uint16_t>("error_code_id", "The action error code"),
151+
BT::OutputPort<std::string>("error_msg", "The action error message")
125152
};
126153
basic.insert(addition.begin(), addition.end());
127154

@@ -193,7 +220,40 @@ class BtActionNode : public BT::ActionNodeBase
193220
*/
194221
virtual void on_timeout()
195222
{
196-
return;
223+
if constexpr (requires {ActionT::Result::TIMEOUT;}) {
224+
setOutput("error_code_id", ActionResult::TIMEOUT);
225+
} else if constexpr (requires {ActionT::Result::UNKNOWN;}) {
226+
setOutput("error_code_id", ActionResult::UNKNOWN);
227+
}
228+
setOutput("error_msg", "Behavior Tree action client timed out waiting.");
229+
}
230+
231+
/**
232+
* @brief Function to perform work in a BT Node when the action server rejects a goal
233+
* Such as setting the error code ID status for action clients.
234+
*/
235+
virtual void on_goal_rejected()
236+
{
237+
if constexpr (requires {ActionT::Result::GOAL_REJECTED;}) {
238+
setOutput("error_code_id", ActionResult::GOAL_REJECTED);
239+
} else if constexpr (requires {ActionT::Result::UNKNOWN;}) {
240+
setOutput("error_code_id", ActionResult::UNKNOWN);
241+
}
242+
setOutput("error_msg", "Goal was rejected by the action server.");
243+
}
244+
245+
/**
246+
* @brief Function to perform work when sending a goal to the action server fails
247+
* Such as setting the error code ID status for action clients.
248+
*/
249+
virtual void on_send_goal_failure()
250+
{
251+
if constexpr (requires {ActionT::Result::SEND_GOAL_FAILURE;}) {
252+
setOutput("error_code_id", ActionResult::SEND_GOAL_FAILURE);
253+
} else if constexpr (requires {ActionT::Result::UNKNOWN;}) {
254+
setOutput("error_code_id", ActionResult::UNKNOWN);
255+
}
256+
setOutput("error_msg", "Failed to send goal to the action server.");
197257
}
198258

199259
/**
@@ -285,9 +345,11 @@ class BtActionNode : public BT::ActionNodeBase
285345
}
286346
}
287347
} catch (const std::runtime_error & e) {
288-
if (e.what() == std::string("send_goal failed") ||
289-
e.what() == std::string("Goal was rejected by the action server"))
290-
{
348+
if (e.what() == std::string("Goal was rejected by the action server")) {
349+
on_goal_rejected();
350+
return BT::NodeStatus::FAILURE;
351+
} else if (e.what() == std::string("send_goal failed")) {
352+
on_send_goal_failure();
291353
// Action related failure that should not fail the tree, but the node
292354
return BT::NodeStatus::FAILURE;
293355
} else {

nav2_behavior_tree/include/nav2_behavior_tree/plugins/action/assisted_teleop_action.hpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,6 @@ class AssistedTeleopAction : public BtActionNode<nav2_msgs::action::AssistedTele
7272
*/
7373
BT::NodeStatus on_cancelled() override;
7474

75-
/**
76-
* @brief Function to perform work in a BT Node when the action server times out
77-
* Such as setting the error code ID status to timed out for action clients.
78-
*/
79-
void on_timeout() override;
80-
8175
/**
8276
* @brief Function to read parameters and initialize class variables
8377
*/
@@ -93,10 +87,6 @@ class AssistedTeleopAction : public BtActionNode<nav2_msgs::action::AssistedTele
9387
{
9488
BT::InputPort<double>("time_allowance", 10.0, "Allowed time for running assisted teleop"),
9589
BT::InputPort<bool>("is_recovery", false, "If true the recovery count will be incremented"),
96-
BT::OutputPort<ActionResult::_error_code_type>(
97-
"error_code_id", "The assisted teleop behavior server error code"),
98-
BT::OutputPort<std::string>(
99-
"error_msg", "The assisted teleop behavior server error msg"),
10090
});
10191
}
10292

nav2_behavior_tree/include/nav2_behavior_tree/plugins/action/back_up_action.hpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,6 @@ class BackUpAction : public BtActionNode<nav2_msgs::action::BackUp>
7373
*/
7474
BT::NodeStatus on_cancelled() override;
7575

76-
/**
77-
* @brief Function to perform work in a BT Node when the action server times out
78-
* Such as setting the error code ID status to timed out for action clients.
79-
*/
80-
void on_timeout() override;
81-
8276
/**
8377
* @brief Function to read parameters and initialize class variables
8478
*/
@@ -96,10 +90,6 @@ class BackUpAction : public BtActionNode<nav2_msgs::action::BackUp>
9690
BT::InputPort<double>("backup_speed", 0.025, "Speed at which to backup"),
9791
BT::InputPort<double>("time_allowance", 10.0, "Allowed time for reversing"),
9892
BT::InputPort<bool>("disable_collision_checks", false, "Disable collision checking"),
99-
BT::OutputPort<ActionResult::_error_code_type>(
100-
"error_code_id", "The back up behavior server error code"),
101-
BT::OutputPort<std::string>(
102-
"error_msg", "The back up behavior server error msg"),
10393
});
10494
}
10595
};

nav2_behavior_tree/include/nav2_behavior_tree/plugins/action/compute_and_track_route_action.hpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,6 @@ class ComputeAndTrackRouteAction : public BtActionNode<nav2_msgs::action::Comput
7272
*/
7373
BT::NodeStatus on_cancelled() override;
7474

75-
/**
76-
* @brief Function to perform work in a BT Node when the action server times out
77-
* Such as setting the error code ID status to timed out for action clients.
78-
*/
79-
void on_timeout() override;
80-
8175
/**
8276
* @brief Function to perform some user-defined operation after a timeout
8377
* waiting for a result that hasn't been received yet
@@ -114,10 +108,6 @@ class ComputeAndTrackRouteAction : public BtActionNode<nav2_msgs::action::Comput
114108
BT::OutputPort<builtin_interfaces::msg::Duration>(
115109
"execution_duration",
116110
"Time taken to compute and track route"),
117-
BT::OutputPort<ActionResult::_error_code_type>(
118-
"error_code_id", "The compute route error code"),
119-
BT::OutputPort<std::string>(
120-
"error_msg", "The compute route error msg"),
121111
BT::OutputPort<uint16_t>(
122112
"last_node_id",
123113
"ID of the previous node"),

nav2_behavior_tree/include/nav2_behavior_tree/plugins/action/compute_path_through_poses_action.hpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,6 @@ class ComputePathThroughPosesAction
110110
BT::OutputPort<nav_msgs::msg::Path>("path", "Path created by ComputePathThroughPoses node"),
111111
BT::OutputPort<int>(
112112
"last_reached_index", "Index of the last reachable pose from requested list of poses"),
113-
BT::OutputPort<ActionResult::_error_code_type>(
114-
"error_code_id", "The compute path through poses error code"),
115-
BT::OutputPort<std::string>(
116-
"error_msg", "The compute path through poses error msg"),
117113
});
118114
}
119115
};

nav2_behavior_tree/include/nav2_behavior_tree/plugins/action/compute_path_to_pose_action.hpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,6 @@ class ComputePathToPoseAction : public BtActionNode<nav2_msgs::action::ComputePa
7474
*/
7575
BT::NodeStatus on_cancelled() override;
7676

77-
/**
78-
* @brief Function to perform work in a BT Node when the action server times out
79-
* Such as setting the error code ID status to timed out for action clients.
80-
*/
81-
void on_timeout() override;
82-
8377
/**
8478
* \brief Override required by the a BT action. Cancel the action and set the path output
8579
*/
@@ -111,10 +105,6 @@ class ComputePathToPoseAction : public BtActionNode<nav2_msgs::action::ComputePa
111105
"planner_id", "",
112106
"Mapped name to the planner plugin type to use"),
113107
BT::OutputPort<nav_msgs::msg::Path>("path", "Path created by ComputePathToPose node"),
114-
BT::OutputPort<ActionResult::_error_code_type>(
115-
"error_code_id", "The compute path to pose error code"),
116-
BT::OutputPort<std::string>(
117-
"error_msg", "The compute path to pose error msg"),
118108
});
119109
}
120110
};

nav2_behavior_tree/include/nav2_behavior_tree/plugins/action/compute_route_action.hpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,6 @@ class ComputeRouteAction : public BtActionNode<nav2_msgs::action::ComputeRoute>
7272
*/
7373
BT::NodeStatus on_cancelled() override;
7474

75-
/**
76-
* @brief Function to perform work in a BT Node when the action server times out
77-
* Such as setting the error code ID status to timed out for action clients.
78-
*/
79-
void on_timeout() override;
80-
8175
/**
8276
* \brief Override required by the a BT action. Cancel the action and set the path output
8377
*/
@@ -114,10 +108,6 @@ class ComputeRouteAction : public BtActionNode<nav2_msgs::action::ComputeRoute>
114108
"planning_time",
115109
"Time taken to compute route"),
116110
BT::OutputPort<nav_msgs::msg::Path>("path", "Path created by ComputeRoute node"),
117-
BT::OutputPort<ActionResult::_error_code_type>(
118-
"error_code_id", "The compute route error code"),
119-
BT::OutputPort<std::string>(
120-
"error_msg", "The compute route error msg"),
121111
});
122112
}
123113
};

nav2_behavior_tree/include/nav2_behavior_tree/plugins/action/drive_on_heading_action.hpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,6 @@ class DriveOnHeadingAction : public BtActionNode<nav2_msgs::action::DriveOnHeadi
6969
BT::InputPort<double>("speed", 0.025, "Speed at which to travel"),
7070
BT::InputPort<double>("time_allowance", 10.0, "Allowed time for driving on heading"),
7171
BT::InputPort<bool>("disable_collision_checks", false, "Disable collision checking"),
72-
BT::OutputPort<Action::Result::_error_code_type>(
73-
"error_code_id", "The drive on heading behavior server error code"),
74-
BT::OutputPort<std::string>(
75-
"error_msg", "The drive on heading behavior server error msg"),
7672
});
7773
}
7874

@@ -95,12 +91,6 @@ class DriveOnHeadingAction : public BtActionNode<nav2_msgs::action::DriveOnHeadi
9591
* @brief Function to perform some user-defined operation upon cancellation of the action
9692
*/
9793
BT::NodeStatus on_cancelled() override;
98-
99-
/**
100-
* @brief Function to perform work in a BT Node when the action server times out
101-
* Such as setting the error code ID status to timed out for action clients.
102-
*/
103-
void on_timeout() override;
10494
};
10595

10696
} // namespace nav2_behavior_tree

nav2_behavior_tree/include/nav2_behavior_tree/plugins/action/follow_object_action.hpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,6 @@ class FollowObjectAction
9090

9191
BT::OutputPort<ActionResult::_total_elapsed_time_type>(
9292
"total_elapsed_time", "Total elapsed time"),
93-
BT::OutputPort<ActionResult::_error_code_type>(
94-
"error_code_id", "Error code"),
95-
BT::OutputPort<std::string>(
96-
"error_msg", "Error message"),
9793
});
9894
}
9995
};

nav2_behavior_tree/include/nav2_behavior_tree/plugins/action/follow_path_action.hpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,6 @@ class FollowPathAction : public BtActionNode<nav2_msgs::action::FollowPath>
111111
BT::InputPort<std::string>("path_handler_id", ""),
112112
BT::OutputPort<nav2_msgs::msg::TrackingFeedback>("tracking_feedback",
113113
"Tracking feedback from controller server"),
114-
BT::OutputPort<ActionResult::_error_code_type>(
115-
"error_code_id", "The follow path error code"),
116-
BT::OutputPort<std::string>(
117-
"error_msg", "The follow path error msg"),
118114
});
119115
}
120116
};

0 commit comments

Comments
 (0)