Skip to content

Commit da44134

Browse files
committed
Added TrackingError.msg
Erased nav_2d_msgs from cmake Added publishing func to controller server Signed-off-by: silanus23 <[email protected]>
1 parent 2926d3b commit da44134

File tree

6 files changed

+95
-5
lines changed

6 files changed

+95
-5
lines changed

nav2_controller/include/nav2_controller/controller_server.hpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,12 @@
2929
#include "tf2_ros/transform_listener.hpp"
3030
#include "nav2_msgs/action/follow_path.hpp"
3131
#include "nav2_msgs/msg/speed_limit.hpp"
32+
#include "nav2_msgs/msg/tracking_error.hpp"
3233
#include "nav2_ros_common/lifecycle_node.hpp"
3334
#include "nav2_ros_common/simple_action_server.hpp"
3435
#include "nav2_util/robot_utils.hpp"
3536
#include "nav2_util/odometry_utils.hpp"
37+
#include "nav2_util/path_utils.hpp"
3638
#include "nav2_util/twist_publisher.hpp"
3739
#include "pluginlib/class_loader.hpp"
3840
#include "pluginlib/class_list_macros.hpp"
@@ -167,6 +169,10 @@ class ControllerServer : public nav2::LifecycleNode
167169
* action server
168170
*/
169171
void updateGlobalPath();
172+
/**
173+
* @brief Calculates and publishes the TrackingError's all components
174+
*/
175+
void publishTrackingState();
170176
/**
171177
* @brief Calls velocity publisher to publish the velocity on "cmd_vel" topic
172178
* @param velocity Twist velocity to be published
@@ -227,6 +233,7 @@ class ControllerServer : public nav2::LifecycleNode
227233
// Dynamic parameters handler
228234
rclcpp::node_interfaces::OnSetParametersCallbackHandle::SharedPtr dyn_params_handler_;
229235
std::mutex dynamic_params_lock_;
236+
std::mutex path_mutex_;
230237

231238
// The controller needs a costmap node
232239
std::shared_ptr<nav2_costmap_2d::Costmap2DROS> costmap_ros_;
@@ -236,7 +243,8 @@ class ControllerServer : public nav2::LifecycleNode
236243
std::unique_ptr<nav2_util::OdomSmoother> odom_sub_;
237244
std::unique_ptr<nav2_util::TwistPublisher> vel_publisher_;
238245
nav2::Subscription<nav2_msgs::msg::SpeedLimit>::SharedPtr speed_limit_sub_;
239-
246+
rclcpp::Publisher<nav2_msgs::msg::TrackingError>::SharedPtr tracking_error_pub_;
247+
240248
// Progress Checker Plugin
241249
pluginlib::ClassLoader<nav2_core::ProgressChecker> progress_checker_loader_;
242250
ProgressCheckerMap progress_checkers_;
@@ -268,6 +276,8 @@ class ControllerServer : public nav2::LifecycleNode
268276
double min_x_velocity_threshold_;
269277
double min_y_velocity_threshold_;
270278
double min_theta_velocity_threshold_;
279+
double search_window_ ;
280+
int start_index_ ;
271281

272282
double failure_tolerance_;
273283
bool use_realtime_priority_;

nav2_controller/src/controller_server.cpp

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ ControllerServer::ControllerServer(const rclcpp::NodeOptions & options)
5555
declare_parameter("min_x_velocity_threshold", rclcpp::ParameterValue(0.0001));
5656
declare_parameter("min_y_velocity_threshold", rclcpp::ParameterValue(0.0001));
5757
declare_parameter("min_theta_velocity_threshold", rclcpp::ParameterValue(0.0001));
58+
declare_parameter("search_window", rclcpp::ParameterValue(5.0));
5859

5960
declare_parameter("speed_limit_topic", rclcpp::ParameterValue("speed_limit"));
6061

@@ -134,6 +135,7 @@ ControllerServer::on_configure(const rclcpp_lifecycle::State & state)
134135
get_parameter("failure_tolerance", failure_tolerance_);
135136
get_parameter("use_realtime_priority", use_realtime_priority_);
136137
get_parameter("publish_zero_velocity", publish_zero_velocity_);
138+
get_parameter("search_window", search_window_);
137139

138140
costmap_ros_->configure();
139141
// Launch a thread to run the costmap node
@@ -225,6 +227,7 @@ ControllerServer::on_configure(const rclcpp_lifecycle::State & state)
225227

226228
odom_sub_ = std::make_unique<nav2_util::OdomSmoother>(node, odom_duration, odom_topic);
227229
vel_publisher_ = std::make_unique<nav2_util::TwistPublisher>(node, "cmd_vel");
230+
tracking_error_pub_ = create_publisher<nav2_msgs::msg::TrackingError>("tracking_error", 10);
228231

229232
double costmap_update_timeout_dbl;
230233
get_parameter("costmap_update_timeout", costmap_update_timeout_dbl);
@@ -500,6 +503,8 @@ void ControllerServer::computeControl()
500503

501504
computeAndPublishVelocity();
502505

506+
publishTrackingState();
507+
503508
if (isGoalReached()) {
504509
RCLCPP_INFO(get_logger(), "Reached the goal!");
505510
break;
@@ -604,16 +609,18 @@ void ControllerServer::setPlannerPath(const nav_msgs::msg::Path & path)
604609
throw nav2_core::InvalidPath("Path is empty.");
605610
}
606611
controllers_[current_controller_]->setPlan(path);
607-
612+
608613
end_pose_ = path.poses.back();
609614
end_pose_.header.frame_id = path.header.frame_id;
610615
goal_checkers_[current_goal_checker_]->reset();
611-
616+
612617
RCLCPP_DEBUG(
613618
get_logger(), "Path end point is (%.2f, %.2f)",
614619
end_pose_.pose.position.x, end_pose_.pose.position.y);
615-
620+
621+
start_index_ = 0;
616622
current_path_ = path;
623+
617624
}
618625

619626
void ControllerServer::computeAndPublishVelocity()
@@ -750,6 +757,42 @@ void ControllerServer::updateGlobalPath()
750757
}
751758
}
752759

760+
void ControllerServer::publishTrackingState()
761+
{
762+
if (current_path_.poses.size() < 2) {
763+
RCLCPP_DEBUG(get_logger(), "Path has fewer than 2 points, cannot compute tracking error.");
764+
return;
765+
}
766+
767+
geometry_msgs::msg::PoseStamped robot_pose;
768+
if (!getRobotPose(robot_pose)) {
769+
RCLCPP_WARN(get_logger(), "Failed to obtain robot pose, skipping tracking error publication.");
770+
return;
771+
}
772+
773+
const double distance_to_goal = nav2_util::geometry_utils::euclidean_distance(robot_pose, end_pose_);
774+
const auto path_search_result = nav2_util::distance_from_path(current_path_, robot_pose.pose, start_index_, search_window_);
775+
const size_t closest_idx = path_search_result.closest_segment_index;
776+
start_index_ = closest_idx;
777+
778+
const auto& segment_start = current_path_.poses[closest_idx];
779+
const auto& segment_end = current_path_.poses[closest_idx + 1];
780+
781+
double cross_product = nav2_util::geometry_utils::cross_product_2d(
782+
robot_pose.pose.position, segment_start.pose,segment_end.pose);
783+
784+
nav2_msgs::msg::TrackingError tracking_error_msg;
785+
tracking_error_msg.header.stamp = now();
786+
tracking_error_msg.header.frame_id = robot_pose.header.frame_id;
787+
tracking_error_msg.tracking_error = path_search_result.distance;
788+
tracking_error_msg.last_index = closest_idx;
789+
tracking_error_msg.cross_product = cross_product;
790+
tracking_error_msg.distance_to_goal = distance_to_goal;
791+
tracking_error_msg.robot_pose = robot_pose;
792+
793+
tracking_error_pub_->publish(tracking_error_msg);
794+
}
795+
753796
void ControllerServer::publishVelocity(const geometry_msgs::msg::TwistStamped & velocity)
754797
{
755798
auto cmd_vel = std::make_unique<geometry_msgs::msg::TwistStamped>(velocity);

nav2_msgs/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ rosidl_generate_interfaces(${PROJECT_NAME}
3737
"msg/RouteNode.msg"
3838
"msg/RouteEdge.msg"
3939
"msg/EdgeCost.msg"
40+
"msg/TrackingError.msg"
4041
"msg/Trajectory.msg"
4142
"msg/TrajectoryPoint.msg"
4243
"srv/GetCosts.srv"

nav2_msgs/msg/TrackingError.msg

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Real-time tracking error for Nav2 controller
2+
3+
std_msgs/Header header
4+
float32 tracking_error
5+
uint32 last_index
6+
float32 cross_product
7+
geometry_msgs/PoseStamped robot_pose
8+
float32 distance_to_goal

nav2_util/include/nav2_util/geometry_utils.hpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,35 @@ inline double distance_to_segment(
228228
return std::hypot(dx_proj, dy_proj);
229229
}
230230

231+
/**
232+
* @brief Computes the 2D cross product between the vector from start to end and the vector from start to point.
233+
* The sign of this calculation's result can be used to determine which side are you on of the track.
234+
*
235+
* See: https://en.wikipedia.org/wiki/Cross_product
236+
*
237+
* @param point The point to check relative to the segment.
238+
* @param start The starting pose of the segment.
239+
* @param end The ending pose of the segment.
240+
* @return The signed 2D cross product value.
241+
*/
242+
inline double cross_product_2d(
243+
const geometry_msgs::msg::Point & point,
244+
const geometry_msgs::msg::Pose & start,
245+
const geometry_msgs::msg::Pose & end)
246+
{
247+
const auto & p = point;
248+
const auto & a = start.position;
249+
const auto & b = end.position;
250+
251+
const double path_vec_x = b.x - a.x;
252+
const double path_vec_y = b.y - a.y;
253+
254+
const double robot_vec_x = p.x - a.x;
255+
const double robot_vec_y = p.y - a.y;
256+
257+
return (path_vec_x * robot_vec_y) - (path_vec_y * robot_vec_x);
258+
}
259+
231260
} // namespace geometry_utils
232261
} // namespace nav2_util
233262

nav2_util/src/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ target_link_libraries(${library_name} PUBLIC
1818
${lifecycle_msgs_TARGETS}
1919
${nav2_msgs_TARGETS}
2020
${nav_msgs_TARGETS}
21-
${nav_2d_msgs_TARGETS}
2221
${rcl_interfaces_TARGETS}
2322
rclcpp::rclcpp
2423
rclcpp_action::rclcpp_action

0 commit comments

Comments
 (0)