simple_planner v1.4.0
Loading...
Searching...
No Matches
simple_planner.hpp
Go to the documentation of this file.
1// Copyright Institute for Automotive Engineering (ika), RWTH Aachen University
2// SPDX-License-Identifier: Apache-2.0
3
4#pragma once
5
6#include <map>
7#include <optional>
8
9#include <diagnostic_msgs/msg/diagnostic_status.hpp>
10#include <diagnostic_updater/diagnostic_updater.hpp>
11#include <diagnostic_updater/publisher.hpp>
12
13#include <geometry_msgs/msg/pose.hpp>
14#include <geometry_msgs/msg/twist.hpp>
15
16#include <nav_msgs/msg/occupancy_grid.hpp>
17
18#include <perception_msgs/msg/ego_data.hpp>
19#include <perception_msgs/msg/object_list.hpp>
20#include <perception_msgs_utils/object_access.hpp>
21
22#include <rclcpp/rclcpp.hpp>
23
24#include <std_srvs/srv/set_bool.hpp>
25
26#include <route_planning_msgs/msg/route.hpp>
27#include <route_planning_msgs_utils/route_access.hpp>
28
29#include <tf2_ros/buffer.h>
30#include <tf2_ros/transform_listener.h>
31#include <tf2_geometry_msgs/tf2_geometry_msgs.hpp>
32#include <tf2_route_planning_msgs/tf2_route_planning_msgs.hpp>
33#include <tf2_trajectory_planning_msgs/tf2_trajectory_planning_msgs.hpp>
34
35#include <trajectory_planning_msgs/msg/trajectory.hpp>
36#include <trajectory_planning_msgs_utils/trajectory_access.hpp>
37#include <visualization_msgs/msg/marker_array.hpp>
38
40
41namespace simple_planner {
42
43// only required for parameter handling
44template <typename C>
45struct is_vector : std::false_type {};
46template <typename T, typename A>
47struct is_vector<std::vector<T, A>> : std::true_type {};
48template <typename C>
49inline constexpr bool is_vector_v = is_vector<C>::value;
50
75
77 Eigen::Vector2d position;
78 double s;
79 double v;
80
88 explicit SimplePathPoint(const Eigen::Vector2d& pos, double s = -1.0, double v = -1.0) : position(pos), s(s), v(v) {}
89
93 SimplePathPoint() = default;
94};
95
96struct SimplePath {
97 std_msgs::msg::Header header;
98 std::vector<SimplePathPoint> points;
99};
100
101class SimplePlannerNode : public rclcpp::Node {
102 public:
104
105 private:
106 enum InterpolationType { LINEAR = 0, SPLINE = 1 };
108
111 bool stop_at_end = false;
112 std::string reason_to_stop;
114 uint8_t suggested_turn_signal = route_planning_msgs::msg::LaneElement::SUGGESTED_TURN_SIGNAL_NONE;
115 };
116
117 // Internal object-handling tuning values (fixed, intentionally not exposed as parameters)
118 static constexpr double kObjectCollisionCheckDt = 0.05; // maximum time step for swept collision checks (s)
119 static constexpr double kMinObjectWidth = 0.8; // minimum object width if dimensions are missing/too small (m)
120 static constexpr double kMinObjectLength = 1.2; // minimum object length if dimensions are missing/too small (m)
121
137 template <typename T>
138 void declareAndLoadParameter(const std::string& name,
139 T& param,
140 const std::string& description,
141 const bool add_to_auto_reconfigurable_params = true,
142 const bool is_required = false,
143 const bool read_only = false,
144 const std::optional<double>& from_value = std::nullopt,
145 const std::optional<double>& to_value = std::nullopt,
146 const std::optional<double>& step_value = std::nullopt,
147 const std::string& additional_constraints = "");
148
155 rcl_interfaces::msg::SetParametersResult parametersCallback(const std::vector<rclcpp::Parameter>& parameters);
156
160 void setup();
161
167 void egoDataCallback(const perception_msgs::msg::EgoData::UniquePtr msg);
168
174 void objectListCallback(const perception_msgs::msg::ObjectList::UniquePtr msg);
175
181 void routeCallback(const route_planning_msgs::msg::Route::UniquePtr msg);
182
188 void gridMapCallback(const nav_msgs::msg::OccupancyGrid::UniquePtr msg);
189
191
198 PlannerState determinePlannerState(const rclcpp::Time& stamp);
199
209 static bool isMessageOutdated(const std_msgs::msg::Header& header, double timeout, const rclcpp::Time& stamp);
210
218 trajectory_planning_msgs::msg::Trajectory createTrajectory(PlannerState state, const rclcpp::Time& stamp);
219
226 static trajectory_planning_msgs::msg::Trajectory buildStandstillTrajectory(const std_msgs::msg::Header& target_header);
227
237 trajectory_planning_msgs::msg::Trajectory buildTrajectoryFromSimplePath(const SimplePath& path);
238
244 void clearObjectInteractionMarkers(const std_msgs::msg::Header& target_header);
245
254 void publishObjectInteractionMarkers(const std_msgs::msg::Header& target_header, const std::optional<ConflictSample>& conflict);
255
262 SimplePath buildSafeStopPath(const std_msgs::msg::Header& target_header);
263
270 FollowRoutePlan buildRoutePlan(const std_msgs::msg::Header& target_header);
271
278 bool hasValidGridMap(const rclcpp::Time& stamp) const;
279
292 void applyObjectConstraints(const std_msgs::msg::Header& target_header,
293 const std::vector<SimplePathPoint>& base_path_points,
294 FollowRoutePlan& route_plan);
295
303 void applyGridMapConstraints(const std_msgs::msg::Header& target_header,
304 std::vector<SimplePathPoint>& base_path_points,
305 FollowRoutePlan& route_plan);
306
314 std::optional<double> findFirstGridMapStopS(const std_msgs::msg::Header& target_header,
315 const std::vector<SimplePathPoint>& base_path_points);
316
327 std::vector<ObjectTrajectory> buildObjectTrajectories(const perception_msgs::msg::ObjectList& tf_object_list,
328 const rclcpp::Time& stamp) const;
329
337 std::optional<ConflictSample> firstConflict(const std::vector<SimplePathPoint>& ego_path,
338 const std::vector<ObjectTrajectory>& object_trajectories) const;
339
345 void resetObjectState(const std_msgs::msg::Header& target_header);
346
354 void appendRoutePoints(const route_planning_msgs::msg::Route& tf_route,
355 FollowRoutePlan& route_plan,
356 std::map<uint64_t, uint64_t>& lane_change_indices_map);
357
368 bool tryRegisterLaneChange(const route_planning_msgs::msg::Route& tf_route,
369 size_t route_element_idx,
370 std::map<uint64_t, uint64_t>& lane_change_indices_map,
371 uint8_t& suggested_turn_signal);
372
384 void updateForTrafficLights(const route_planning_msgs::msg::Route& tf_route,
385 size_t route_element_idx,
386 const route_planning_msgs::msg::LaneElement& suggested_lane,
387 const SimplePathPoint& simple_path_point,
388 double t_total,
389 bool& stop_at_end,
390 double& offset_to_stop_line);
391
404 std::vector<SimplePathPoint> mergeLaneChangeSegments(const route_planning_msgs::msg::Route& tf_route,
405 const std::vector<SimplePathPoint>& route_points,
406 const std::map<uint64_t, uint64_t>& lane_change_indices_map);
407
413 void applyIndicatorRequest(uint8_t suggested_turn_signal);
414
420 static void trimPathBehindEgo(SimplePath& path);
421
431 static std::vector<SimplePathPoint> truncatePathAtS(const std::vector<SimplePathPoint>& path, double stop_s);
432
442 std::vector<SimplePathPoint> resamplePath(const std::vector<SimplePathPoint>& path,
443 bool stop_at_end,
444 double offset_to_stop_line = 0.0,
445 const double* speed_cap = nullptr);
446
455 std::vector<SimplePathPoint> generateLaneChangePath(size_t start_idx,
456 size_t turn_idx,
457 const route_planning_msgs::msg::Route& route);
458
464 static void recalculateS(std::vector<SimplePathPoint>& path);
465
474 SimplePath calculateSafeStopAlongEgoHeading(const perception_msgs::msg::EgoData& ego_data,
475 const double safe_stop_distance,
476 const std_msgs::msg::Header& target_header);
477
485 SimplePath calculateSafeStopAlongRoute(const SimplePath& path, const double safe_stop_distance);
486
498 static bool requiresTransform(const std_msgs::msg::Header& source_header, const std_msgs::msg::Header& target_header);
499
507 SimplePath transformPath(const SimplePath& path, const std_msgs::msg::Header& target_header);
508
512 void health(diagnostic_updater::DiagnosticStatusWrapper& stat);
513
517 void setHealth(const unsigned char status,
518 const std::string& msg,
519 const std::map<std::string, std::string>& key_value_pairs = {});
520
527 static std::string plannerStateToString(const PlannerState& state);
528
535 static std::string turnSignalToString(const uint8_t& turn_signal);
536
537 std::unique_ptr<tf2_ros::Buffer> tf2_buffer_;
538 std::shared_ptr<tf2_ros::TransformListener> tf2_listener_;
539
540 rclcpp::Subscription<perception_msgs::msg::EgoData>::SharedPtr sub_egoData_;
541 rclcpp::Subscription<perception_msgs::msg::ObjectList>::SharedPtr sub_object_list_;
542 rclcpp::Subscription<route_planning_msgs::msg::Route>::SharedPtr sub_route_;
543 rclcpp::Subscription<nav_msgs::msg::OccupancyGrid>::SharedPtr sub_grid_map_;
544
545 rclcpp::Publisher<trajectory_planning_msgs::msg::Trajectory>::SharedPtr pub_;
546 rclcpp::Publisher<visualization_msgs::msg::MarkerArray>::SharedPtr object_interaction_marker_pub_;
547
548 rclcpp::TimerBase::SharedPtr publish_timer_;
549 rclcpp::Client<std_srvs::srv::SetBool>::SharedPtr left_turn_indicator_service_client_;
550 rclcpp::Client<std_srvs::srv::SetBool>::SharedPtr right_turn_indicator_service_client_;
551 rclcpp::Client<std_srvs::srv::SetBool>::SharedPtr hazard_lights_service_client_;
552
556 std::vector<std::tuple<std::string, std::function<void(const rclcpp::Parameter&)>>> auto_reconfigurable_params_;
557
561 OnSetParametersCallbackHandle::SharedPtr parameters_callback_;
562
563 // Parameters
564 std::string vehicle_frame_id_ = "base_link";
565 std::string trajectory_frame_id_ = "base_link";
566 std::string fixed_over_time_frame_id_ = "map";
567 double freq_ = 10.0;
568 double route_timeout_ = 1.0;
569 double ego_data_timeout_ = 1.0;
570 double object_timeout_ = 1.0;
571 double grid_map_timeout_ = 1.0;
572 double trajectory_horizon_ = 10.0;
573 int n_states_ = 51;
575 double v_ref_ = 13.89;
576 double a_decel_ = -0.5;
577 double a_max_decel_ = -1.0;
579 bool consider_grid_map_ = false;
588 bool consider_objects_ = true;
598
601
602 perception_msgs::msg::EgoData ego_data_;
603 perception_msgs::msg::ObjectList object_list_;
604 route_planning_msgs::msg::Route route_;
605 nav_msgs::msg::OccupancyGrid grid_map_;
606
607 bool ego_data_init_ = false;
608 bool object_list_init_ = false;
609 bool route_init_ = false;
610 bool grid_map_init_ = false;
611 std::optional<double> safe_stop_distance_;
612 std::optional<double> last_object_speed_cap_;
615 double dt_;
616
620 diagnostic_updater::Updater diagnostic_updater_{this};
621
626 unsigned char status = diagnostic_msgs::msg::DiagnosticStatus::STALE;
627 std::string message;
628 std::map<std::string, std::string> key_value_pairs;
630
631 std::unique_ptr<diagnostic_updater::TopicDiagnostic> ego_data_topic_diagnostic_;
633
634 std::unique_ptr<diagnostic_updater::TopicDiagnostic> object_list_topic_diagnostic_;
636
637 std::unique_ptr<diagnostic_updater::TopicDiagnostic> route_topic_diagnostic_;
639
640 std::unique_ptr<diagnostic_updater::TopicDiagnostic> grid_map_topic_diagnostic_;
642
643 std::unique_ptr<diagnostic_updater::DiagnosedPublisher<trajectory_planning_msgs::msg::Trajectory>> diagnosed_publisher_;
645};
646
647} // namespace simple_planner
void setup()
Sets up subscribers, publishers, etc. to configure the node.
SimplePath buildSafeStopPath(const std_msgs::msg::Header &target_header)
Builds the initial safe-stop path for the current cycle.
std::unique_ptr< diagnostic_updater::TopicDiagnostic > ego_data_topic_diagnostic_
void declareAndLoadParameter(const std::string &name, T &param, const std::string &description, const bool add_to_auto_reconfigurable_params=true, const bool is_required=false, const bool read_only=false, const std::optional< double > &from_value=std::nullopt, const std::optional< double > &to_value=std::nullopt, const std::optional< double > &step_value=std::nullopt, const std::string &additional_constraints="")
Declares a ROS parameter, loads its value and optionally registers it for runtime updates.
Definition utils.hpp:7
static void trimPathBehindEgo(SimplePath &path)
Removes path points that lie behind the ego vehicle in vehicle frame.
void applyGridMapConstraints(const std_msgs::msg::Header &target_header, std::vector< SimplePathPoint > &base_path_points, FollowRoutePlan &route_plan)
Applies occupancy-grid-based stop constraints to the base route path.
std::optional< double > safe_stop_distance_
bool hasValidGridMap(const rclcpp::Time &stamp) const
Checks whether a fresh, structurally valid grid map is currently available.
std::vector< ObjectTrajectory > buildObjectTrajectories(const perception_msgs::msg::ObjectList &tf_object_list, const rclcpp::Time &stamp) const
Reduces the perceived object list (in vehicle frame) to timed bounding-box trajectories.
std::vector< SimplePathPoint > resamplePath(const std::vector< SimplePathPoint > &path, bool stop_at_end, double offset_to_stop_line=0.0, const double *speed_cap=nullptr)
Resamples a path into trajectory time steps and applies optional stopping behavior.
rclcpp::Publisher< trajectory_planning_msgs::msg::Trajectory >::SharedPtr pub_
rclcpp::Client< std_srvs::srv::SetBool >::SharedPtr hazard_lights_service_client_
std::optional< double > findFirstGridMapStopS(const std_msgs::msg::Header &target_header, const std::vector< SimplePathPoint > &base_path_points)
Finds the last safe grid-map sample before the first blocked pose.
static void recalculateS(std::vector< SimplePathPoint > &path)
Recomputes accumulated path distance from point positions.
diagnostic_updater::Updater diagnostic_updater_
Diagnostic updater.
std::shared_ptr< tf2_ros::TransformListener > tf2_listener_
bool tryRegisterLaneChange(const route_planning_msgs::msg::Route &tf_route, size_t route_element_idx, std::map< uint64_t, uint64_t > &lane_change_indices_map, uint8_t &suggested_turn_signal)
Detects and stores the start/end window of a lane change.
std::unique_ptr< tf2_ros::Buffer > tf2_buffer_
rclcpp::Subscription< perception_msgs::msg::ObjectList >::SharedPtr sub_object_list_
void applyObjectConstraints(const std_msgs::msg::Header &target_header, const std::vector< SimplePathPoint > &base_path_points, FollowRoutePlan &route_plan)
Applies trajectory-based object conflict constraints to a follow-route plan.
std::vector< std::tuple< std::string, std::function< void(const rclcpp::Parameter &)> > > auto_reconfigurable_params_
Auto-reconfigurable parameters for dynamic reconfiguration.
std::unique_ptr< diagnostic_updater::TopicDiagnostic > grid_map_topic_diagnostic_
void publishTimerCallback()
This callback is invoked every period seconds by the timer.
TopicDiagnosticConfig grid_map_topic_diagnostic_config_
std::vector< SimplePathPoint > generateLaneChangePath(size_t start_idx, size_t turn_idx, const route_planning_msgs::msg::Route &route)
Generates interpolated points for a lane-change section of the route.
perception_msgs::msg::ObjectList object_list_
static constexpr double kMinObjectLength
std::optional< double > last_object_speed_cap_
TopicDiagnosticConfig ego_data_topic_diagnostic_config_
std::unique_ptr< diagnostic_updater::DiagnosedPublisher< trajectory_planning_msgs::msg::Trajectory > > diagnosed_publisher_
FollowRoutePlan buildRoutePlan(const std_msgs::msg::Header &target_header)
Builds the complete route-following plan including stop and turn information.
void appendRoutePoints(const route_planning_msgs::msg::Route &tf_route, FollowRoutePlan &route_plan, std::map< uint64_t, uint64_t > &lane_change_indices_map)
Appends route-derived path points and stop metadata for the follow-route case.
rcl_interfaces::msg::SetParametersResult parametersCallback(const std::vector< rclcpp::Parameter > &parameters)
Handles reconfiguration when a parameter value is changed.
Definition utils.hpp:79
TopicDiagnosticConfig object_list_topic_diagnostic_config_
void publishObjectInteractionMarkers(const std_msgs::msg::Header &target_header, const std::optional< ConflictSample > &conflict)
Publishes RViz markers for the current object interaction conflict.
void health(diagnostic_updater::DiagnosticStatusWrapper &stat)
Function called by diagnostic updater to populate diagnostics status.
Definition utils.hpp:173
nav_msgs::msg::OccupancyGrid grid_map_
rclcpp::Client< std_srvs::srv::SetBool >::SharedPtr right_turn_indicator_service_client_
static std::vector< SimplePathPoint > truncatePathAtS(const std::vector< SimplePathPoint > &path, double stop_s)
Returns a path ending exactly at the requested accumulated path coordinate.
std::unique_ptr< diagnostic_updater::TopicDiagnostic > object_list_topic_diagnostic_
static std::string plannerStateToString(const PlannerState &state)
Converts a PlannerState enum to a string representation.
Definition utils.hpp:188
rclcpp::Publisher< visualization_msgs::msg::MarkerArray >::SharedPtr object_interaction_marker_pub_
rclcpp::Subscription< perception_msgs::msg::EgoData >::SharedPtr sub_egoData_
static std::string turnSignalToString(const uint8_t &turn_signal)
Converts a turn signal value to a string representation.
Definition utils.hpp:203
std::unique_ptr< diagnostic_updater::TopicDiagnostic > route_topic_diagnostic_
void objectListCallback(const perception_msgs::msg::ObjectList::UniquePtr msg)
Stores the latest perceived object list including object predictions.
rclcpp::TimerBase::SharedPtr publish_timer_
OnSetParametersCallbackHandle::SharedPtr parameters_callback_
Callback handle for dynamic parameter reconfiguration.
void routeCallback(const route_planning_msgs::msg::Route::UniquePtr msg)
Stores the latest route message and extracts the route path.
rclcpp::Subscription< route_planning_msgs::msg::Route >::SharedPtr sub_route_
SimplePath calculateSafeStopAlongEgoHeading(const perception_msgs::msg::EgoData &ego_data, const double safe_stop_distance, const std_msgs::msg::Header &target_header)
Creates a minimal safe-stop path along the current ego heading.
void setHealth(const unsigned char status, const std::string &msg, const std::map< std::string, std::string > &key_value_pairs={})
Sets the health information.
Definition utils.hpp:180
void updateForTrafficLights(const route_planning_msgs::msg::Route &tf_route, size_t route_element_idx, const route_planning_msgs::msg::LaneElement &suggested_lane, const SimplePathPoint &simple_path_point, double t_total, bool &stop_at_end, double &offset_to_stop_line)
Updates stop-at-end and stop-line offset state for traffic-light regulatory elements.
static constexpr double kMinObjectWidth
TopicDiagnosticConfig diagnosed_publisher_config_
struct simple_planner::SimplePlannerNode::DiagnosticStatus health_
TopicDiagnosticConfig route_topic_diagnostic_config_
SimplePath calculateSafeStopAlongRoute(const SimplePath &path, const double safe_stop_distance)
Truncates and resamples an existing path to stop within the safe-stop distance.
void applyIndicatorRequest(uint8_t suggested_turn_signal)
Requests the appropriate indicator state for the current route plan.
void egoDataCallback(const perception_msgs::msg::EgoData::UniquePtr msg)
Stores the latest ego data message.
rclcpp::Client< std_srvs::srv::SetBool >::SharedPtr left_turn_indicator_service_client_
rclcpp::Subscription< nav_msgs::msg::OccupancyGrid >::SharedPtr sub_grid_map_
PlannerState determinePlannerState(const rclcpp::Time &stamp)
Determines the current planner state from input freshness and route availability.
void clearObjectInteractionMarkers(const std_msgs::msg::Header &target_header)
Deletes the currently published object interaction markers.
SimplePath transformPath(const SimplePath &path, const std_msgs::msg::Header &target_header)
Transforms a simple path into the requested target frame and timestamp.
Definition utils.hpp:140
trajectory_planning_msgs::msg::Trajectory createTrajectory(PlannerState state, const rclcpp::Time &stamp)
Creates a trajectory for the already determined planner state.
route_planning_msgs::msg::Route route_
perception_msgs::msg::EgoData ego_data_
std::optional< ConflictSample > firstConflict(const std::vector< SimplePathPoint > &ego_path, const std::vector< ObjectTrajectory > &object_trajectories) const
Returns the first conflict between the (time-sampled) ego path and any object trajectory.
trajectory_planning_msgs::msg::Trajectory buildTrajectoryFromSimplePath(const SimplePath &path)
Builds a trajectory message from a simple path.
static bool requiresTransform(const std_msgs::msg::Header &source_header, const std_msgs::msg::Header &target_header)
Checks whether a transform between two stamped frames is required.
Definition utils.hpp:127
std::vector< SimplePathPoint > mergeLaneChangeSegments(const route_planning_msgs::msg::Route &tf_route, const std::vector< SimplePathPoint > &route_points, const std::map< uint64_t, uint64_t > &lane_change_indices_map)
Merges interpolated lane-change segments into the base route path.
SimplePlannerNode()
Creates a SimplePlannerNode node.
static trajectory_planning_msgs::msg::Trajectory buildStandstillTrajectory(const std_msgs::msg::Header &target_header)
Creates a standstill trajectory for the current planning cycle.
static constexpr double kObjectCollisionCheckDt
void resetObjectState(const std_msgs::msg::Header &target_header)
Resets the remembered object speed cap / hysteresis state and clears interaction markers.
void gridMapCallback(const nav_msgs::msg::OccupancyGrid::UniquePtr msg)
Stores the latest occupancy grid map message.
static bool isMessageOutdated(const std_msgs::msg::Header &header, double timeout, const rclcpp::Time &stamp)
Checks whether an input message is older than the configured timeout.
Namespace for simple_planner package.
constexpr bool is_vector_v
SimplePathPoint(const Eigen::Vector2d &pos, double s=-1.0, double v=-1.0)
Creates a path point from position, path distance, and velocity.
SimplePathPoint()=default
Creates a path point with default-initialized members.
std::vector< SimplePathPoint > points
std_msgs::msg::Header header
Diagnostic status indicating node health.
std::map< std::string, std::string > key_value_pairs
Configuration parameters for topic diagnostics.
double max_acceptable_timestamp_delta
Maximum acceptable difference between message timestamp and receipt time (in seconds)
double min_frequency
Minimum acceptable frequency.
double max_frequency
Maximum acceptable frequency.
double min_acceptable_timestamp_delta
Minimum acceptable difference between message timestamp and receipt time (in seconds)