Carma-platform v4.11.0
CARMA Platform is built on robot operating system (ROS) and utilizes open source software (OSS) that enables Cooperative Driving Automation (CDA) features to allow Automated Driving Systems to interact and cooperate with infrastructure and other vehicles through communication.
stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPlugin Class Reference

Class containing primary business logic for the Stop Controlled Intersection Tactical Plugin. More...

#include <stop_controlled_intersection_plugin.hpp>

Inheritance diagram for stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPlugin:
Inheritance graph
Collaboration diagram for stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPlugin:
Collaboration graph

Public Member Functions

 StopControlledIntersectionTacticalPlugin (const rclcpp::NodeOptions &options)
 
std::vector< PointSpeedPairmaneuvers_to_points (const std::vector< carma_planning_msgs::msg::Maneuver > &maneuvers, const carma_wm::WorldModelConstPtr &wm, const carma_planning_msgs::msg::VehicleState &state)
 Converts a set of requested stop controlled intersection maneuvers to point speed limit pairs. More...
 
std::vector< PointSpeedPaircreate_case_one_speed_profile (const carma_wm::WorldModelConstPtr &wm, const carma_planning_msgs::msg::Maneuver &maneuver, std::vector< lanelet::BasicPoint2d > &route_geometry_points, double starting_speed, const carma_planning_msgs::msg::VehicleState &states)
 Creates a speed profile according to case one of the stop controlled intersection, where the vehicle accelerates and then decelerates to a stop. More...
 
std::vector< PointSpeedPaircreate_case_two_speed_profile (const carma_wm::WorldModelConstPtr &wm, const carma_planning_msgs::msg::Maneuver &maneuver, std::vector< lanelet::BasicPoint2d > &route_geometry_points, double starting_speed)
 Creates a speed profile according to case two of the stop controlled intersection, where the vehicle first accelerates then cruises and finally decelerates to a stop. More...
 
std::vector< PointSpeedPaircreate_case_three_speed_profile (const carma_wm::WorldModelConstPtr &wm, const carma_planning_msgs::msg::Maneuver &maneuver, std::vector< lanelet::BasicPoint2d > &route_geometry_points, double starting_speed)
 Creates a speed profile according to case three of the stop controlled intersection, where the vehicle continuously decelerates to a stop. More...
 
std::vector< carma_planning_msgs::msg::TrajectoryPlanPoint > compose_trajectory_from_centerline (const std::vector< PointSpeedPair > &points, const carma_planning_msgs::msg::VehicleState &state, const rclcpp::Time &state_time)
 Method converts a list of lanelet centerline points and current vehicle state into a usable list of trajectory points for trajectory planning. More...
 
carma_ros2_utils::CallbackReturn on_configure_plugin () override
 Method which is triggered when this plugin is moved from the UNCONFIGURED to INACTIVE states. This method should be used to load parameters and is required to be implemented. More...
 
bool get_availability ()
 Get the availability status of this plugin based on the current operating environment. Method must be overriden by extending classes. More...
 
std::string get_version_id ()
 Returns the version id of this plugin. More...
 
rcl_interfaces::msg::SetParametersResult parameter_update_callback (const std::vector< rclcpp::Parameter > &parameters)
 
void plan_trajectory_callback (std::shared_ptr< rmw_request_id_t >, carma_planning_msgs::srv::PlanTrajectory::Request::SharedPtr req, carma_planning_msgs::srv::PlanTrajectory::Response::SharedPtr resp) override
 Extending class provided callback which should return a planned trajectory based on the provided trajectory planning request. More...
 
- Public Member Functions inherited from carma_guidance_plugins::TacticalPlugin
 TacticalPlugin (const rclcpp::NodeOptions &)
 TacticalPlugin constructor. More...
 
virtual ~TacticalPlugin ()=default
 Virtual destructor for safe deletion. More...
 
virtual void plan_trajectory_callback (std::shared_ptr< rmw_request_id_t > srv_header, carma_planning_msgs::srv::PlanTrajectory::Request::SharedPtr req, carma_planning_msgs::srv::PlanTrajectory::Response::SharedPtr resp)=0
 Extending class provided callback which should return a planned trajectory based on the provided trajectory planning request. More...
 
std::string get_capability () override
 Get the capability string representing this plugins capabilities Method must be overriden by extending classes. Expectation is that abstract plugin type parent classes will provide a default implementation. More...
 
uint8_t get_type () override final
 Returns the type of this plugin according to the carma_planning_msgs::Plugin type enum. Extending classes for the specific type should override this method. More...
 
carma_ros2_utils::CallbackReturn handle_on_configure (const rclcpp_lifecycle::State &) override final
 
carma_ros2_utils::CallbackReturn handle_on_activate (const rclcpp_lifecycle::State &) override final
 
carma_ros2_utils::CallbackReturn handle_on_deactivate (const rclcpp_lifecycle::State &) override final
 
carma_ros2_utils::CallbackReturn handle_on_cleanup (const rclcpp_lifecycle::State &) override final
 
carma_ros2_utils::CallbackReturn handle_on_shutdown (const rclcpp_lifecycle::State &) override final
 
carma_ros2_utils::CallbackReturn handle_on_error (const rclcpp_lifecycle::State &, const std::string &exception_string) override final
 
- Public Member Functions inherited from carma_guidance_plugins::PluginBaseNode
 PluginBaseNode (const rclcpp::NodeOptions &)
 PluginBaseNode constructor. More...
 
virtual ~PluginBaseNode ()=default
 Virtual destructor for safe deletion. More...
 
virtual std::shared_ptr< carma_wm::WMListenerget_world_model_listener () final
 Method to return the default world model listener provided as a convience by this base class If this method or get_world_model() are not called then the world model remains uninitialized and will not create unnecessary subscriptions. More...
 
virtual carma_wm::WorldModelConstPtr get_world_model () final
 Method to return the default world model provided as a convience by this base class If this method or get_world_model_listener() are not called then the world model remains uninitialized and will not create unnecessary subscriptions. More...
 
virtual bool get_activation_status () final
 Returns the activation status of this plugin. The plugins API callbacks will only be triggered when this method returns true. More...
 
virtual uint8_t get_type ()
 Returns the type of this plugin according to the carma_planning_msgs::Plugin type enum. Extending classes for the specific type should override this method. More...
 
std::string get_plugin_name_and_ns () const
 Return the name of this plugin with namespace. NOTE: If only the name of the plugin is required, use get_plugin_name() More...
 
std::string get_plugin_name () const
 Return the name of this plugin. More...
 
virtual bool get_availability ()=0
 Get the availability status of this plugin based on the current operating environment. Method must be overriden by extending classes. More...
 
virtual std::string get_capability ()=0
 Get the capability string representing this plugins capabilities Method must be overriden by extending classes. Expectation is that abstract plugin type parent classes will provide a default implementation. More...
 
virtual std::string get_version_id ()=0
 Returns the version id of this plugin. More...
 
virtual carma_ros2_utils::CallbackReturn on_configure_plugin ()=0
 Method which is triggered when this plugin is moved from the UNCONFIGURED to INACTIVE states. This method should be used to load parameters and is required to be implemented. More...
 
virtual carma_ros2_utils::CallbackReturn on_activate_plugin ()
 Method which is triggered when this plugin is moved from the INACTIVE to ACTIVE states. This method should be used to prepare for future callbacks for plugin's capabilites. More...
 
virtual carma_ros2_utils::CallbackReturn on_deactivate_plugin ()
 Method which is triggered when this plugin is moved from the ACTIVE to INACTIVE states. This method should be used to disable any functionality which should cease execution when plugin is inactive. More...
 
virtual carma_ros2_utils::CallbackReturn on_cleanup_plugin ()
 Method which is triggered when this plugin is moved from the INACTIVE to UNCONFIGURED states. This method should be used to fully reset the plugin such that a future call to on_configure_plugin would leave the plugin in a fresh state as though just launched. More...
 
virtual carma_ros2_utils::CallbackReturn on_shutdown_plugin ()
 Method which is triggered when this plugin is moved from any state to FINALIZED This method should be used to generate any shutdown logs or final cleanup. More...
 
virtual carma_ros2_utils::CallbackReturn on_error_plugin (const std::string &exception_string)
 Method which is triggered when an unhandled exception occurs in this plugin This method should be used to cleanup such that the plugin could be moved to UNCONFIGURED state if possible. More...
 
carma_ros2_utils::CallbackReturn handle_on_configure (const rclcpp_lifecycle::State &) override
 
carma_ros2_utils::CallbackReturn handle_on_activate (const rclcpp_lifecycle::State &) override
 
carma_ros2_utils::CallbackReturn handle_on_deactivate (const rclcpp_lifecycle::State &) override
 
carma_ros2_utils::CallbackReturn handle_on_cleanup (const rclcpp_lifecycle::State &) override
 
carma_ros2_utils::CallbackReturn handle_on_shutdown (const rclcpp_lifecycle::State &) override
 
carma_ros2_utils::CallbackReturn handle_on_error (const rclcpp_lifecycle::State &, const std::string &exception_string) override
 
 FRIEND_TEST (carma_guidance_plugins_test, connections_test)
 

Private Member Functions

 FRIEND_TEST (StopControlledIntersectionTacticalPlugin, TestSCIPlanning_case_one)
 
 FRIEND_TEST (StopControlledIntersectionTacticalPlugin, TestSCIPlanning_case_two)
 
 FRIEND_TEST (StopControlledIntersectionTacticalPlugin, TestSCIPlanning_case_three)
 

Private Attributes

carma_wm::WorldModelConstPtr wm_
 
StopControlledIntersectionTacticalPluginConfig config_
 
std::string stop_controlled_intersection_strategy_ = "Carma/stop_controlled_intersection"
 
double epsilon_ = 0.001
 

Detailed Description

Class containing primary business logic for the Stop Controlled Intersection Tactical Plugin.

Definition at line 63 of file stop_controlled_intersection_plugin.hpp.

Constructor & Destructor Documentation

◆ StopControlledIntersectionTacticalPlugin()

stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPlugin::StopControlledIntersectionTacticalPlugin ( const rclcpp::NodeOptions &  options)
explicit

Definition at line 51 of file stop_controlled_intersection_tactical_plugin.cpp.

52 : carma_guidance_plugins::TacticalPlugin(options), config_(StopControlledIntersectionTacticalPluginConfig())
53{
54 basic_autonomy::set_logger(get_logger().get_child("basic_autonomy"));
55 // Declare parameters
56 config_.trajectory_time_length = declare_parameter<double>("trajectory_time_length", config_.trajectory_time_length);
57 config_.curve_resample_step_size = declare_parameter<double>("curve_resample_step_size", config_.curve_resample_step_size);
58 config_.centerline_sampling_spacing = declare_parameter<double>("centerline_sampling_spacing", config_.centerline_sampling_spacing);
59 config_.curvature_moving_average_window_size = declare_parameter<int>("curvature_moving_average_window_size", config_.curvature_moving_average_window_size);
60 config_.lateral_accel_limit = declare_parameter<double>("lateral_accel_limit", config_.lateral_accel_limit);
61 config_.speed_moving_average_window_size = declare_parameter<int>("speed_moving_average_window_size", config_.speed_moving_average_window_size);
62 config_.back_distance = declare_parameter<double>("back_distance", config_.back_distance);
63}
TacticalPlugin base class which can be extended by user provided plugins which wish to implement the ...
void set_logger(rclcpp::Logger logger)
Replace the module-level logger used by all basic_autonomy functions.
Definition: log.cpp:33
rclcpp::Logger get_logger()
Return the module-level logger used by all basic_autonomy functions.
Definition: log.cpp:32

References stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::back_distance, stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::centerline_sampling_spacing, config_, stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::curvature_moving_average_window_size, stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::curve_resample_step_size, basic_autonomy::get_logger(), stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::lateral_accel_limit, basic_autonomy::set_logger(), stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::speed_moving_average_window_size, and stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::trajectory_time_length.

Here is the call graph for this function:

Member Function Documentation

◆ compose_trajectory_from_centerline()

std::vector< carma_planning_msgs::msg::TrajectoryPlanPoint > stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPlugin::compose_trajectory_from_centerline ( const std::vector< PointSpeedPair > &  points,
const carma_planning_msgs::msg::VehicleState &  state,
const rclcpp::Time &  state_time 
)

Method converts a list of lanelet centerline points and current vehicle state into a usable list of trajectory points for trajectory planning.

Parameters
pointsThe set of points that define the current lane the vehicle is in and are defined based on the request planning maneuvers. These points must be in the same lane as the vehicle and must extend in front of it though it is fine if they also extend behind it.
stateThe current state of the vehicle
state_timeThe abosolute time which the provided vehicle state corresponds to
Returns
A list of trajectory points to send to the carma planning stack

Definition at line 478 of file stop_controlled_intersection_tactical_plugin.cpp.

479 {
480
481 std::vector<carma_planning_msgs::msg::TrajectoryPlanPoint> trajectory;
482 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "VehicleState: "
483 << " x: " << state.x_pos_global << " y: " << state.y_pos_global << " yaw: " << state.orientation
484 << " speed: " << state.longitudinal_vel);
485
486 int nearest_pt_index = basic_autonomy::waypoint_generation::get_nearest_point_index(points, state);
487 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Nearest pt index: "<<nearest_pt_index);
488 std::vector<PointSpeedPair> future_points(points.begin() + nearest_pt_index + 1, points.end()); //Points in front of current vehicle position
489 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Future points size: "<<future_points.size());
491 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Got time bound points with size:" << time_bound_points.size());
492
493 //Attach past points
494 std::vector<PointSpeedPair> back_and_future = attach_past_points(points, time_bound_points, nearest_pt_index, config_.back_distance);
495 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Got back_and_future points with size: "<<back_and_future.size());
496
497 std::vector<double> speed_limits;
498 std::vector<lanelet::BasicPoint2d> curve_points;
499 split_point_speed_pairs(time_bound_points, &curve_points, &speed_limits);
500
501 std::unique_ptr<basic_autonomy::smoothing::SplineI> fit_curve = basic_autonomy::waypoint_generation::compute_fit(curve_points); //Compute splines based on curve points
502 if(!fit_curve)
503 {
504 throw std::invalid_argument("Could not fit a spline curve along the trajectory!");
505 }
506
507 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Got fit");
508 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Speed_limits.size(): "<<speed_limits.size());
509
510 std::vector<lanelet::BasicPoint2d> all_sampling_points;
511 all_sampling_points.reserve(1 + curve_points.size() * 2);
512
513 std::vector<double> distributed_speed_limits;
514 distributed_speed_limits.reserve(1+ curve_points.size() * 2);
515
516 //Compute total length of the trajectory to get correct number of points
517 // we expect using curve resample step size
518 std::vector<double> downtracks_raw = carma_wm::geometry::compute_arc_lengths(curve_points);
519
520 auto total_step_along_curve = static_cast<int>(downtracks_raw.back() / config_.curve_resample_step_size);
521
522 int current_speed_index = 0;
523 size_t total_point_size = curve_points.size();
524
525 double step_threshold_for_next_speed = (double)total_step_along_curve / (double)total_point_size;
526 double scaled_steps_along_curve = 0.0; // from 0 (start) to 1 (end) for the whole trajectory
527 std::vector<double> better_curvature;
528 better_curvature.reserve(1 + curve_points.size() * 2);
529
530 for (size_t steps_along_curve = 0; steps_along_curve < total_step_along_curve; steps_along_curve++) // Resample curve at tighter resolution
531 {
532 lanelet::BasicPoint2d p = (*fit_curve)(scaled_steps_along_curve);
533 all_sampling_points.push_back(p);
534 double c = basic_autonomy::waypoint_generation::compute_curvature_at((*fit_curve), scaled_steps_along_curve);
535 better_curvature.push_back(c);
536
537 if((double) steps_along_curve > step_threshold_for_next_speed)
538 {
539 step_threshold_for_next_speed += (double)total_step_along_curve / (double)total_point_size;
540 current_speed_index++;
541 }
542 distributed_speed_limits.push_back(speed_limits[current_speed_index]); //Identify speed limits for resampled points
543 scaled_steps_along_curve += 1.0 / total_step_along_curve; //adding steps_along_curve_step_size
544 }
545
546 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Got sampled points with size:" << all_sampling_points.size());
547
548 std::vector<double> final_yaw_values = carma_wm::geometry::compute_tangent_orientations(all_sampling_points);
549
550 std::vector<double> curvatures = basic_autonomy::smoothing::moving_average_filter(better_curvature, config_.curvature_moving_average_window_size, false);
551 std::vector<double> ideal_speeds =
552 trajectory_utils::constrained_speeds_for_curvatures(curvatures, config_.lateral_accel_limit);
553
554 std::vector<double> constrained_speed_limits = basic_autonomy::waypoint_generation::apply_speed_limits(ideal_speeds, distributed_speed_limits); //Speed min(ideal, calculated)
555 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Processed all points in computed fit");
556 std::vector<double> final_actual_speeds = constrained_speed_limits;
557
558 if (all_sampling_points.empty())
559 {
560 RCLCPP_WARN_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "No trajectory points could be generated");
561 return {};
562 }
563
564 //Drop Past points
565 nearest_pt_index = basic_autonomy::waypoint_generation::get_nearest_index_by_downtrack(all_sampling_points, wm_, state);
566 std::vector<lanelet::BasicPoint2d> future_basic_points(all_sampling_points.begin() + nearest_pt_index + 1,
567 all_sampling_points.end());
568 std::vector<double> future_speeds(final_actual_speeds.begin() + nearest_pt_index + 1,
569 final_actual_speeds.end());
570 std::vector<double> future_yaw(final_yaw_values.begin() + nearest_pt_index + 1,
571 final_yaw_values.end());
572
573 // Add current vehicle point to front of the trajectory
574 lanelet::BasicPoint2d cur_veh_point(state.x_pos_global, state.y_pos_global);
575
576 future_basic_points.insert(future_basic_points.begin(),
577 cur_veh_point); // Add current vehicle position to front of sample points
578 future_speeds.insert(future_speeds.begin(), state.longitudinal_vel);
579 future_yaw.insert(future_yaw.begin(), state.orientation);
580
581 // Compute points to local downtracks
582 std::vector<double> downtracks = carma_wm::geometry::compute_arc_lengths(future_basic_points);
583
585
586 // Convert speeds to times
587 std::vector<double> times;
588
589 //Force last point speed to 0.0 if close to end
590 if(lanelet::geometry::distance2d(future_basic_points.back(), points.back().point) < epsilon_){
591 final_actual_speeds.back() = 0.0;
592 }
593
594 trajectory_utils::conversions::speed_to_time(downtracks, final_actual_speeds, &times);
595
596 // Build trajectory points
597 std::vector<carma_planning_msgs::msg::TrajectoryPlanPoint> traj_points =
598 basic_autonomy::waypoint_generation::trajectory_from_points_times_orientations(future_basic_points, times, future_yaw, state_time, "default");
599
600 return traj_points;
601}
std::vector< double > moving_average_filter(const std::vector< double > input, int window_size, bool ignore_first_point=true)
Extremely simplie moving average filter.
Definition: filters.cpp:24
void split_point_speed_pairs(const std::vector< PointSpeedPair > &points, std::vector< lanelet::BasicPoint2d > *basic_points, std::vector< double > *speeds)
Helper method to split a list of PointSpeedPair into separate point and speed lists.
int get_nearest_point_index(const std::vector< lanelet::BasicPoint2d > &points, const carma_planning_msgs::msg::VehicleState &state)
Returns the nearest point (in terms of cartesian 2d distance) to the provided vehicle pose in the pro...
std::unique_ptr< basic_autonomy::smoothing::SplineI > compute_fit(const std::vector< lanelet::BasicPoint2d > &basic_points)
Computes a spline based on the provided points.
int get_nearest_index_by_downtrack(const std::vector< lanelet::BasicPoint2d > &points, const carma_wm::WorldModelConstPtr &wm, double target_downtrack)
Returns the nearest "less than" point to the provided vehicle pose in the provided list by utilizing ...
std::vector< double > apply_speed_limits(const std::vector< double > speeds, const std::vector< double > speed_limits)
Applies the provided speed limits to the provided speeds such that each element is capped at its corr...
std::vector< carma_planning_msgs::msg::TrajectoryPlanPoint > trajectory_from_points_times_orientations(const std::vector< lanelet::BasicPoint2d > &points, const std::vector< double > &times, const std::vector< double > &yaws, rclcpp::Time startTime, const std::string &desired_controller_plugin)
Method combines input points, times, orientations, and an absolute start time to form a valid carma p...
double compute_curvature_at(const basic_autonomy::smoothing::SplineI &fit_curve, double step_along_the_curve)
Given the curvature fit, computes the curvature at the given step along the curve.
std::vector< PointSpeedPair > constrain_to_time_boundary(const std::vector< PointSpeedPair > &points, double time_span)
Reduces the input points to only those points that fit within the provided time boundary.
std::vector< PointSpeedPair > attach_past_points(const std::vector< PointSpeedPair > &points_set, std::vector< PointSpeedPair > future_points, const int nearest_pt_index, double back_distance)
Attaches back_distance length of points behind the future points.
std::vector< double > compute_tangent_orientations(const lanelet::BasicLineString2d &centerline)
Compute an approximate orientation for the vehicle at each point along the provided centerline.
Definition: Geometry.cpp:565
std::vector< double > compute_arc_lengths(const std::vector< lanelet::BasicPoint2d > &data)
Compute the arc length at each point around the curve.
Definition: Geometry.cpp:498

References basic_autonomy::waypoint_generation::apply_speed_limits(), basic_autonomy::waypoint_generation::attach_past_points(), stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::back_distance, process_traj_logs::c, carma_wm::geometry::compute_arc_lengths(), basic_autonomy::waypoint_generation::compute_curvature_at(), basic_autonomy::waypoint_generation::compute_fit(), carma_wm::geometry::compute_tangent_orientations(), config_, basic_autonomy::waypoint_generation::constrain_to_time_boundary(), stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::curvature_moving_average_window_size, stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::curve_resample_step_size, epsilon_, basic_autonomy::get_logger(), basic_autonomy::waypoint_generation::get_nearest_index_by_downtrack(), basic_autonomy::waypoint_generation::get_nearest_point_index(), stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::lateral_accel_limit, basic_autonomy::smoothing::moving_average_filter(), stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::speed_moving_average_window_size, basic_autonomy::waypoint_generation::split_point_speed_pairs(), basic_autonomy::waypoint_generation::trajectory_from_points_times_orientations(), stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::trajectory_time_length, and wm_.

Referenced by plan_trajectory_callback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ create_case_one_speed_profile()

std::vector< PointSpeedPair > stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPlugin::create_case_one_speed_profile ( const carma_wm::WorldModelConstPtr wm,
const carma_planning_msgs::msg::Maneuver &  maneuver,
std::vector< lanelet::BasicPoint2d > &  route_geometry_points,
double  starting_speed,
const carma_planning_msgs::msg::VehicleState &  states 
)

Creates a speed profile according to case one of the stop controlled intersection, where the vehicle accelerates and then decelerates to a stop.

Parameters
wmPointer to intialized world model for semantic map access
maneuversThe maneuver to being planned for. Maneuver meta-dara parameters are used to create the trajectory profile.
route_geometry_pointsThe geometry points along the route which are associated with a speed in this method.
starting_speedThe current speed of the vehicle at the time of the trajectory planning request
Returns
List of centerline points paired with target speeds

Definition at line 233 of file stop_controlled_intersection_tactical_plugin.cpp.

234 {
235
236 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Planning for Case One");
237 //Derive meta data values from maneuver message - Using order in sci_strategic_plugin
238 double a_acc = GET_MANEUVER_PROPERTY(maneuver, parameters.float_valued_meta_data[0]);
239 double a_dec = GET_MANEUVER_PROPERTY(maneuver, parameters.float_valued_meta_data[1]); //a_dec is a -ve value
240 double t_acc = GET_MANEUVER_PROPERTY(maneuver, parameters.float_valued_meta_data[2]);
241 double t_dec = GET_MANEUVER_PROPERTY(maneuver, parameters.float_valued_meta_data[3]);
242 double speed_before_decel = GET_MANEUVER_PROPERTY(maneuver, parameters.float_valued_meta_data[4]);
243 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "a_acc received: "<< a_acc);
244 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "a_dec received: "<< a_dec);
245 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "t_acc received: "<< t_acc);
246 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "t_dec received: "<< t_dec);
247 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "speed before decel received: "<< speed_before_decel);
248
249 //Derive start and end dist from maneuver
250 double start_dist = GET_MANEUVER_PROPERTY(maneuver, start_dist);
251 double end_dist = GET_MANEUVER_PROPERTY(maneuver, end_dist);
252
253 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Maneuver starting downtrack: "<< start_dist);
254 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Maneuver ending downtrack: "<< end_dist);
255 //Checking state against start_dist and adjust profile
256 lanelet::BasicPoint2d state_point(state.x_pos_global, state.y_pos_global);
257 double route_starting_downtrack = wm->routeTrackPos(state_point).downtrack; //Starting downtrack based on geometry points
258 double dist_acc; //Distance for which acceleration lasts
259
260 if(route_starting_downtrack < start_dist){
261 //Update parameters
262 //Keeping the deceleration part the same
263 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Starting distance is less than maneuver start, updating parameters");
264 double dist_decel = pow(speed_before_decel, 2)/(2*std::abs(a_dec));
265
266 dist_acc = end_dist - dist_decel;
267 a_acc = (pow(speed_before_decel, 2) - pow(starting_speed,2))/(2*dist_acc);
268 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Updated a_acc: "<< a_acc);
269 }
270 else{
271 //Use parameters from maneuver message
272 dist_acc = (pow(speed_before_decel, 2) - pow(starting_speed, 2))/(2*a_acc);
273 }
274
275 std::vector<PointSpeedPair> points_and_target_speeds;
277 first_point.point = state_point;
278 first_point.speed = starting_speed;
279 points_and_target_speeds.push_back(first_point);
280
281 lanelet::BasicPoint2d prev_point = state_point;
282 double total_dist_covered = 0; //Starting dist for maneuver treated as 0.0
283
284 for(size_t i = 1; i < route_geometry_points.size(); i++){
285 lanelet::BasicPoint2d current_point = route_geometry_points[i];
286 double delta_d = lanelet::geometry::distance2d(prev_point, current_point);
287 total_dist_covered += delta_d;
288 //Find speed at dist covered
289 double speed_i;
290 if(total_dist_covered <= dist_acc){
291 //Acceleration part
292 speed_i = sqrt(pow(starting_speed,2) + 2*a_acc*total_dist_covered);
293 }
294 else{
295 //Deceleration part
296 speed_i = sqrt(std::max(pow(speed_before_decel,2) + 2*a_dec*(total_dist_covered - dist_acc),0.0)); //std::max to ensure negative value is not sqrt
297 if(speed_i < epsilon_){
298 speed_i = 0.0;
299 }
300 }
301
303 if(speed_i < epsilon_){
304 p.point = prev_point;
305 p.speed = 0.0;
306 }
307 else{
308 p.point = route_geometry_points[i];
309 p.speed = speed_i;
310 prev_point = current_point; //Advance prev point if speed changes
311 }
312 points_and_target_speeds.push_back(p);
313
314 }
315
316 return points_and_target_speeds;
317
318}
#define GET_MANEUVER_PROPERTY(mvr, property)
Macro definition to enable easier access to fields shared across the maneuver types.
list first_point
Definition: process_bag.py:52
basic_autonomy::waypoint_generation::PointSpeedPair PointSpeedPair

References epsilon_, process_bag::first_point, basic_autonomy::get_logger(), GET_MANEUVER_PROPERTY, process_bag::i, basic_autonomy::waypoint_generation::PointSpeedPair::point, and basic_autonomy::waypoint_generation::PointSpeedPair::speed.

Referenced by maneuvers_to_points().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ create_case_three_speed_profile()

std::vector< PointSpeedPair > stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPlugin::create_case_three_speed_profile ( const carma_wm::WorldModelConstPtr wm,
const carma_planning_msgs::msg::Maneuver &  maneuver,
std::vector< lanelet::BasicPoint2d > &  route_geometry_points,
double  starting_speed 
)

Creates a speed profile according to case three of the stop controlled intersection, where the vehicle continuously decelerates to a stop.

Parameters
wmPointer to intialized world model for semantic map access
maneuversThe maneuver to being planned for. Maneuver meta-dara parameters are used to create the trajectory profile.
route_geometry_pointsThe geometry points along the route which are associated with a speed in this method.
starting_speedThe current speed of the vehicle at the time of the trajectory planning request
Returns
List of centerline points paired with speed limits

Definition at line 421 of file stop_controlled_intersection_tactical_plugin.cpp.

422 {
423 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Planning for Case three");
424 //Derive meta data values from maneuver message - Using order in sci_strategic_plugin
425 double a_dec = GET_MANEUVER_PROPERTY(maneuver, parameters.float_valued_meta_data[0]);
426
427 //Derive start and end dist from maneuver
428 double start_dist = GET_MANEUVER_PROPERTY(maneuver, start_dist);
429 double end_dist = GET_MANEUVER_PROPERTY(maneuver, end_dist);
430 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Maneuver starting downtrack: "<< start_dist);
431 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Maneuver ending downtrack: "<< end_dist);
432
433 //Checking route geometry start against start_dist and adjust profile
434 double route_starting_downtrack = wm->routeTrackPos(route_geometry_points[0]).downtrack; //Starting downtrack based on geometry points
435
436 if(route_starting_downtrack < start_dist){
437 //update parameter
438 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Starting distance is less than maneuver start, updating parameters");
439 a_dec = pow(starting_speed, 2)/(2*(end_dist - route_starting_downtrack));
440 }
441
442 std::vector<PointSpeedPair> points_and_target_speeds;
444 first_point.point = route_geometry_points[0];
445 first_point.speed = starting_speed;
446 points_and_target_speeds.push_back(first_point);
447
448 lanelet::BasicPoint2d prev_point = route_geometry_points[0];
449 double total_dist_covered = 0; //Starting dist for maneuver treated as 0.0
450
451 for(size_t i = 0;i < route_geometry_points.size(); i++){
452 lanelet::BasicPoint2d current_point = route_geometry_points[i];
453 double delta_d = lanelet::geometry::distance2d(prev_point, current_point);
454 total_dist_covered +=delta_d;
455 //Find speed at dist covered
456 double speed_i = sqrt(std::max(pow(starting_speed,2) + 2 * a_dec * total_dist_covered, 0.0)); //std::max to ensure negative value is not sqrt
457
459
460 if(speed_i < epsilon_){
461 p.point = prev_point;
462 p.speed = 0.0;
463 }
464 else{
465 p.point = route_geometry_points[i];
466 p.speed = speed_i;
467 prev_point = current_point; //Advance prev point if speed changes
468 }
469
470 points_and_target_speeds.push_back(p);
471
472
473 }
474
475 return points_and_target_speeds;
476}

References epsilon_, process_bag::first_point, basic_autonomy::get_logger(), GET_MANEUVER_PROPERTY, process_bag::i, basic_autonomy::waypoint_generation::PointSpeedPair::point, and basic_autonomy::waypoint_generation::PointSpeedPair::speed.

Referenced by maneuvers_to_points().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ create_case_two_speed_profile()

std::vector< PointSpeedPair > stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPlugin::create_case_two_speed_profile ( const carma_wm::WorldModelConstPtr wm,
const carma_planning_msgs::msg::Maneuver &  maneuver,
std::vector< lanelet::BasicPoint2d > &  route_geometry_points,
double  starting_speed 
)

Creates a speed profile according to case two of the stop controlled intersection, where the vehicle first accelerates then cruises and finally decelerates to a stop.

Parameters
wmPointer to intialized world model for semantic map access
maneuversThe maneuver to being planned for. Maneuver meta-dara parameters are used to create the trajectory profile.
route_geometry_pointsThe geometry points along the route which are associated with a speed in this method.
starting_speedThe current speed of the vehicle at the time of the trajectory planning request
Returns
List of centerline points paired with speed limits

Definition at line 320 of file stop_controlled_intersection_tactical_plugin.cpp.

321 {
322 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Planning for Case Two");
323 //Derive meta data values from maneuver message - Using order in sci_strategic_plugin
324 double a_acc = GET_MANEUVER_PROPERTY(maneuver, parameters.float_valued_meta_data[0]);
325 double a_dec = GET_MANEUVER_PROPERTY(maneuver, parameters.float_valued_meta_data[1]); //a_dec is a -ve value
326 double t_acc = GET_MANEUVER_PROPERTY(maneuver, parameters.float_valued_meta_data[2]);
327 double t_dec = GET_MANEUVER_PROPERTY(maneuver, parameters.float_valued_meta_data[3]);
328 double t_cruise = GET_MANEUVER_PROPERTY(maneuver, parameters.float_valued_meta_data[4]);
329 double speed_before_decel = GET_MANEUVER_PROPERTY(maneuver, parameters.float_valued_meta_data[5]);
330
331 //Derive start and end dist from maneuver
332 double start_dist = GET_MANEUVER_PROPERTY(maneuver, start_dist);
333 double end_dist = GET_MANEUVER_PROPERTY(maneuver, end_dist);
334 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Maneuver starting downtrack: "<< start_dist);
335 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Maneuver ending downtrack: "<< end_dist);
336
337 //Checking route geometry start against start_dist and adjust profile
338 double route_starting_downtrack = wm->routeTrackPos(route_geometry_points[0]).downtrack; //Starting downtrack based on geometry points
339 double dist_acc; //Distance over which acceleration happens
340 double dist_cruise; //Distance over which cruising happens
341 double dist_decel; //Distance over which deceleration happens
342
343 if(route_starting_downtrack < start_dist){
344 //update parameters
345 //Keeping acceleration and deceleration part same as planned in strategic plugin
346 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Starting distance is less than maneuver start, updating parameters");
347 dist_acc = starting_speed*t_acc + 0.5 * a_acc * pow(t_acc,2);
348 dist_decel = speed_before_decel*t_dec + 0.5 * a_dec * pow(t_dec,2);
349 dist_cruise = end_dist - route_starting_downtrack - (dist_acc + dist_decel);
350 }
351 else{
352 //Use maneuver parameters to create speed profile
353 dist_acc = starting_speed*t_acc + 0.5 * a_acc * pow(t_acc,2);
354 dist_cruise = speed_before_decel*t_cruise;
355 dist_decel = speed_before_decel*t_dec + 0.5 * a_dec * pow(t_dec,2);
356 }
357
358 //Check calculated total dist against maneuver limits
359 double total_distance_needed = dist_acc + dist_cruise + dist_decel;
360 if(total_distance_needed - (end_dist - start_dist) > epsilon_ ){
361 //Requested maneuver needs to be modified to meet start and end dist req
362 //Sacrifice on cruising and then acceleration if needed
363 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Updating maneuver to meet start and end dist req.");
364 double delta_total_dist = total_distance_needed - (end_dist - start_dist);
365 dist_cruise -= delta_total_dist;
366 if(dist_cruise < 0){
367 dist_acc += dist_cruise;
368 dist_cruise = 0;
369 }
370 //Not considering dist_acc < 0 after this.
371 }
372
373 std::vector<PointSpeedPair> points_and_target_speeds;
375 first_point.point = route_geometry_points[0];
376 first_point.speed = starting_speed;
377 points_and_target_speeds.push_back(first_point);
378
379 lanelet::BasicPoint2d prev_point = route_geometry_points.front();
380 double total_dist_planned = 0; //Starting dist for maneuver treated as 0.0
381 double prev_speed = starting_speed;
382 for(auto route_point : route_geometry_points){
383 lanelet::BasicPoint2d current_point = route_point;
384 double delta_d = lanelet::geometry::distance2d(prev_point, current_point);
385 total_dist_planned += delta_d;
386
387 //Find speed at dist covered
388 double speed_i;
389 if(total_dist_planned < dist_acc){
390 //Acceleration part
391 speed_i = sqrt(pow(starting_speed,2) + 2*a_acc*total_dist_planned);
392 }
393 else if(dist_cruise > 0 && total_dist_planned >= dist_acc && total_dist_planned <= (dist_acc + dist_cruise)){
394 //Cruising part
395 speed_i = prev_speed;
396 }
397 else{
398 //Deceleration part
399 speed_i = sqrt(std::max(pow(speed_before_decel,2) + 2*a_dec*(total_dist_planned - dist_acc - dist_cruise),0.0));//std::max to ensure negative value is not sqrt
400 }
401
403 if(speed_i < epsilon_){
404 p.point = prev_point;
405 p.speed = 0.0;
406 }
407 else{
408 p.point = route_point;
409 p.speed = std::min(speed_i,speed_before_decel);
410 prev_point = current_point; //Advance prev point if speed changes
411 }
412 points_and_target_speeds.push_back(p);
413
414 prev_speed = speed_i;
415 }
416
417 return points_and_target_speeds;
418
419}

References epsilon_, process_bag::first_point, basic_autonomy::get_logger(), GET_MANEUVER_PROPERTY, basic_autonomy::waypoint_generation::PointSpeedPair::point, and basic_autonomy::waypoint_generation::PointSpeedPair::speed.

Referenced by maneuvers_to_points().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ FRIEND_TEST() [1/3]

stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPlugin::FRIEND_TEST ( StopControlledIntersectionTacticalPlugin  ,
TestSCIPlanning_case_one   
)
private

◆ FRIEND_TEST() [2/3]

stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPlugin::FRIEND_TEST ( StopControlledIntersectionTacticalPlugin  ,
TestSCIPlanning_case_three   
)
private

◆ FRIEND_TEST() [3/3]

stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPlugin::FRIEND_TEST ( StopControlledIntersectionTacticalPlugin  ,
TestSCIPlanning_case_two   
)
private

◆ get_availability()

bool stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPlugin::get_availability ( )
virtual

Get the availability status of this plugin based on the current operating environment. Method must be overriden by extending classes.

Returns
This method should return true if the plugin's current understanding of the world means it would be capable of planning or executing its capability.

Implements carma_guidance_plugins::PluginBaseNode.

Definition at line 603 of file stop_controlled_intersection_tactical_plugin.cpp.

604{
605 return true;
606}

◆ get_version_id()

std::string stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPlugin::get_version_id ( )
virtual

Returns the version id of this plugin.

Returns
The version id represented as a string

Implements carma_guidance_plugins::PluginBaseNode.

Definition at line 608 of file stop_controlled_intersection_tactical_plugin.cpp.

609{
610 return "v1.0";
611}

◆ maneuvers_to_points()

std::vector< PointSpeedPair > stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPlugin::maneuvers_to_points ( const std::vector< carma_planning_msgs::msg::Maneuver > &  maneuvers,
const carma_wm::WorldModelConstPtr wm,
const carma_planning_msgs::msg::VehicleState &  state 
)

Converts a set of requested stop controlled intersection maneuvers to point speed limit pairs.

Parameters
maneuversThe list of maneuvers to convert
wmPointer to intialized world model for semantic map access
stateThe current state of the vehicle
Returns
List of centerline points paired with target speeds

Definition at line 171 of file stop_controlled_intersection_tactical_plugin.cpp.

173{
174 std::vector<PointSpeedPair> points_and_target_speeds;
175 std::unordered_set<lanelet::Id> visited_lanelets;
176
177 lanelet::BasicPoint2d veh_pos(state.x_pos_global, state.y_pos_global);
178 double max_starting_downtrack = wm_->routeTrackPos(veh_pos).downtrack; //The vehicle position
179 double starting_speed = state.longitudinal_vel;
180
181 bool first = true;
182 double starting_downtrack;
183 for (const auto& maneuver : maneuvers)
184 {
185 if(maneuver.type != carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING && maneuver.type != carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_STRAIGHT && maneuver.type != carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_LEFT_TURN
186 && maneuver.type !=carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_RIGHT_TURN ){
187 throw std::invalid_argument("Stop Controlled Intersection Tactical Plugin does not support this maneuver type");
188 }
189
190 if(first)
191 {
192 starting_downtrack = GET_MANEUVER_PROPERTY(maneuver, start_dist);
193 if (starting_downtrack > max_starting_downtrack)
194 {
195 starting_downtrack = max_starting_downtrack;
196 }
197 first = false;
198 }
199
200 // Sample the lanelet centerline at fixed increments.
201 // std::min call here is a guard against starting_downtrack being within 1m of the maneuver end_dist
202 // in this case the sampleRoutePoints method will return a single point allowing execution to continue
203 std::vector<lanelet::BasicPoint2d> route_points = wm->sampleRoutePoints(
204 std::min(starting_downtrack + config_.centerline_sampling_spacing, GET_MANEUVER_PROPERTY(maneuver,end_dist)),
206
207 route_points.insert(route_points.begin(), veh_pos);
208 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Route geometery points size: "<<route_points.size());
209 //get case num from maneuver parameters
210 if(GET_MANEUVER_PROPERTY(maneuver,parameters.int_valued_meta_data).empty()){
211 throw std::invalid_argument("No case number specified for stop controlled intersection maneuver");
212 }
213
214 int case_num = GET_MANEUVER_PROPERTY(maneuver,parameters.int_valued_meta_data[0]);
215 if(case_num == 1){
216 points_and_target_speeds = create_case_one_speed_profile(wm, maneuver, route_points, starting_speed, state);
217 }
218 else if(case_num == 2){
219 points_and_target_speeds = create_case_two_speed_profile(wm, maneuver, route_points, starting_speed);
220 }
221 else if(case_num == 3)
222 {
223 points_and_target_speeds = create_case_three_speed_profile(wm, maneuver, route_points, starting_speed);
224 }
225 else{
226 throw std::invalid_argument("The stop controlled intersection tactical plugin doesn't handle the case number requested");
227 }
228 }
229
230 return points_and_target_speeds;
231}
std::vector< PointSpeedPair > create_case_two_speed_profile(const carma_wm::WorldModelConstPtr &wm, const carma_planning_msgs::msg::Maneuver &maneuver, std::vector< lanelet::BasicPoint2d > &route_geometry_points, double starting_speed)
Creates a speed profile according to case two of the stop controlled intersection,...
std::vector< PointSpeedPair > create_case_one_speed_profile(const carma_wm::WorldModelConstPtr &wm, const carma_planning_msgs::msg::Maneuver &maneuver, std::vector< lanelet::BasicPoint2d > &route_geometry_points, double starting_speed, const carma_planning_msgs::msg::VehicleState &states)
Creates a speed profile according to case one of the stop controlled intersection,...
std::vector< PointSpeedPair > create_case_three_speed_profile(const carma_wm::WorldModelConstPtr &wm, const carma_planning_msgs::msg::Maneuver &maneuver, std::vector< lanelet::BasicPoint2d > &route_geometry_points, double starting_speed)
Creates a speed profile according to case three of the stop controlled intersection,...

References stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::centerline_sampling_spacing, config_, create_case_one_speed_profile(), create_case_three_speed_profile(), create_case_two_speed_profile(), basic_autonomy::get_logger(), GET_MANEUVER_PROPERTY, and wm_.

Referenced by plan_trajectory_callback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_configure_plugin()

carma_ros2_utils::CallbackReturn stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPlugin::on_configure_plugin ( )
overridevirtual

Method which is triggered when this plugin is moved from the UNCONFIGURED to INACTIVE states. This method should be used to load parameters and is required to be implemented.

Returns
SUCCESS, FAILURE, or ERROR. Transition to INACTIVE will only complete on SUCCESS.

Implements carma_guidance_plugins::PluginBaseNode.

Definition at line 87 of file stop_controlled_intersection_tactical_plugin.cpp.

88{
89 config_ = StopControlledIntersectionTacticalPluginConfig();
90
91 // Declare parameters
92 get_parameter<double>("trajectory_time_length", config_.trajectory_time_length);
93 get_parameter<double>("curve_resample_step_size", config_.curve_resample_step_size);
94 get_parameter<double>("centerline_sampling_spacing", config_.centerline_sampling_spacing);
95 get_parameter<int>("curvature_moving_average_window_size", config_.curvature_moving_average_window_size);
96 get_parameter<double>("lateral_accel_limit", config_.lateral_accel_limit);
97 get_parameter<int>("speed_moving_average_window_size", config_.speed_moving_average_window_size);
98 get_parameter<double>("back_distance", config_.back_distance);
99
100 // Register runtime parameter update callback
101 add_on_set_parameters_callback(std::bind(&StopControlledIntersectionTacticalPlugin::parameter_update_callback, this, std_ph::_1));
102
103 RCLCPP_INFO_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"),"Done loading parameters: " << config_);
104
105 // set world model pointer
107
108 // Return success if everything initialized successfully
109 return CallbackReturn::SUCCESS;
110}
virtual carma_wm::WorldModelConstPtr get_world_model() final
Method to return the default world model provided as a convience by this base class If this method or...
rcl_interfaces::msg::SetParametersResult parameter_update_callback(const std::vector< rclcpp::Parameter > &parameters)

References stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::back_distance, stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::centerline_sampling_spacing, config_, stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::curvature_moving_average_window_size, stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::curve_resample_step_size, basic_autonomy::get_logger(), carma_guidance_plugins::PluginBaseNode::get_world_model(), stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::lateral_accel_limit, parameter_update_callback(), stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::speed_moving_average_window_size, stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::trajectory_time_length, and wm_.

Here is the call graph for this function:

◆ parameter_update_callback()

rcl_interfaces::msg::SetParametersResult stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPlugin::parameter_update_callback ( const std::vector< rclcpp::Parameter > &  parameters)

Definition at line 65 of file stop_controlled_intersection_tactical_plugin.cpp.

66{
67 auto error_double = update_params<double>({
68 {"trajectory_time_length", config_.trajectory_time_length},
69 {"curve_resample_step_size", config_.curve_resample_step_size},
70 {"centerline_sampling_spacing", config_.centerline_sampling_spacing},
71 {"lateral_accel_limit", config_.lateral_accel_limit},
72 {"back_distance", config_.back_distance}
73 }, parameters);
74
75 auto error_int = update_params<int>({
76 {"curvature_moving_average_window_size", config_.curvature_moving_average_window_size},
77 {"speed_moving_average_window_size", config_.speed_moving_average_window_size}
78 }, parameters);
79
80 rcl_interfaces::msg::SetParametersResult result;
81
82 result.successful = !error_double && !error_int;
83
84 return result;
85}

References stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::back_distance, stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::centerline_sampling_spacing, config_, stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::curvature_moving_average_window_size, stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::curve_resample_step_size, stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::lateral_accel_limit, stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::speed_moving_average_window_size, and stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPluginConfig::trajectory_time_length.

Referenced by on_configure_plugin().

Here is the caller graph for this function:

◆ plan_trajectory_callback()

void stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPlugin::plan_trajectory_callback ( std::shared_ptr< rmw_request_id_t >  srv_header,
carma_planning_msgs::srv::PlanTrajectory::Request::SharedPtr  req,
carma_planning_msgs::srv::PlanTrajectory::Response::SharedPtr  resp 
)
overridevirtual

Extending class provided callback which should return a planned trajectory based on the provided trajectory planning request.

Parameters
srv_headerRCL header for services calls. Can usually be ignored by implementers.
reqThe service request containing the maneuvers to plan trajectories for and current vehicle state
respThe response containing the planned trajectory

Implements carma_guidance_plugins::TacticalPlugin.

Definition at line 112 of file stop_controlled_intersection_tactical_plugin.cpp.

116{
117 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Starting stop controlled intersection trajectory planning");
118
119 if(req->maneuver_index_to_plan >= req->maneuver_plan.maneuvers.size())
120 {
121 throw std::invalid_argument(
122 "Stop Control Intersection Plugin asked to plan invalid maneuver index: " + std::to_string(req->maneuver_index_to_plan) +
123 " for plan of size: " + std::to_string(req->maneuver_plan.maneuvers.size()));
124 }
125 std::vector<carma_planning_msgs::msg::Maneuver> maneuver_plan;
126 for(size_t i = req->maneuver_index_to_plan; i < req->maneuver_plan.maneuvers.size(); i++){
127
128 if((req->maneuver_plan.maneuvers[i].type == carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING || req->maneuver_plan.maneuvers[i].type == carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_STRAIGHT
129 || req->maneuver_plan.maneuvers[i].type == carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_LEFT_TURN || req->maneuver_plan.maneuvers[i].type ==carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_RIGHT_TURN)
130 && GET_MANEUVER_PROPERTY(req->maneuver_plan.maneuvers[i], parameters.string_valued_meta_data.front()) == stop_controlled_intersection_strategy_)
131 {
132 maneuver_plan.push_back(req->maneuver_plan.maneuvers[i]);
133 resp->related_maneuvers.push_back(req->maneuver_plan.maneuvers[i].type);
134 }
135 else
136 {
137 break;
138 }
139 }
140
141 lanelet::BasicPoint2d veh_pos(req->vehicle_state.x_pos_global, req->vehicle_state.y_pos_global);
142 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Planning state x:"<<req->vehicle_state.x_pos_global <<" , y: " << req->vehicle_state.y_pos_global);
143
144 double current_downtrack = wm_->routeTrackPos(veh_pos).downtrack;
145 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Current_downtrack"<< current_downtrack);
146
147 std::vector<PointSpeedPair> points_and_target_speeds = maneuvers_to_points( maneuver_plan, wm_, req->vehicle_state);
148 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Maneuver to points size:"<< points_and_target_speeds.size());
149 // RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_controlled_intersection_tactical_plugin"), "Printing points: ");
150 // TODO: add print logic
151 carma_planning_msgs::msg::TrajectoryPlan trajectory;
152 trajectory.header.frame_id = "map";
153 trajectory.header.stamp = req->header.stamp;
154 trajectory.trajectory_id = boost::uuids::to_string(boost::uuids::random_generator()());
155
156 //Add compose trajectory from centerline
157 trajectory.trajectory_points = compose_trajectory_from_centerline(points_and_target_speeds, req->vehicle_state, req->header.stamp);
158 trajectory.initial_longitudinal_velocity = req->vehicle_state.longitudinal_vel;
159
160 // Set the planning plugin field name
161 for (auto& p : trajectory.trajectory_points) {
162 p.planner_plugin_name = get_plugin_name();
163 // p.controller_plugin_name = "PurePursuit";
164 }
165
166 resp->trajectory_plan = trajectory;
167
168 resp->maneuver_status.push_back(carma_planning_msgs::srv::PlanTrajectory::Response::MANEUVER_IN_PROGRESS);
169}
std::string get_plugin_name() const
Return the name of this plugin.
std::vector< PointSpeedPair > maneuvers_to_points(const std::vector< carma_planning_msgs::msg::Maneuver > &maneuvers, const carma_wm::WorldModelConstPtr &wm, const carma_planning_msgs::msg::VehicleState &state)
Converts a set of requested stop controlled intersection maneuvers to point speed limit pairs.
std::vector< carma_planning_msgs::msg::TrajectoryPlanPoint > compose_trajectory_from_centerline(const std::vector< PointSpeedPair > &points, const carma_planning_msgs::msg::VehicleState &state, const rclcpp::Time &state_time)
Method converts a list of lanelet centerline points and current vehicle state into a usable list of t...
auto to_string(const UtmZone &zone) -> std::string
Definition: utm_zone.cpp:21

References compose_trajectory_from_centerline(), basic_autonomy::get_logger(), GET_MANEUVER_PROPERTY, carma_guidance_plugins::PluginBaseNode::get_plugin_name(), process_bag::i, maneuvers_to_points(), stop_controlled_intersection_strategy_, carma_cooperative_perception::to_string(), and wm_.

Here is the call graph for this function:

Member Data Documentation

◆ config_

StopControlledIntersectionTacticalPluginConfig stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPlugin::config_
private

◆ epsilon_

double stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPlugin::epsilon_ = 0.001
private

◆ stop_controlled_intersection_strategy_

std::string stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPlugin::stop_controlled_intersection_strategy_ = "Carma/stop_controlled_intersection"
private

Definition at line 160 of file stop_controlled_intersection_plugin.hpp.

Referenced by plan_trajectory_callback().

◆ wm_

carma_wm::WorldModelConstPtr stop_controlled_intersection_tactical_plugin::StopControlledIntersectionTacticalPlugin::wm_
private

The documentation for this class was generated from the following files: