Carma-platform v4.2.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.
lci_strategic_plugin::LCIStrategicPlugin Class Reference

#include <lci_strategic_plugin.hpp>

Inheritance diagram for lci_strategic_plugin::LCIStrategicPlugin:
Inheritance graph
Collaboration diagram for lci_strategic_plugin::LCIStrategicPlugin:
Collaboration graph

Classes

struct  VehicleState
 Struct representing a vehicle state for the purposes of planning. More...
 

Public Member Functions

 LCIStrategicPlugin (const rclcpp::NodeOptions &)
 Default constructor for RouteFollowingPlugin class. More...
 
void plan_maneuvers_callback (std::shared_ptr< rmw_request_id_t > srv_header, carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp)
 Service callback for arbitrator maneuver planning. More...
 
rcl_interfaces::msg::SetParametersResult parameter_update_callback (const std::vector< rclcpp::Parameter > &parameters)
 Callback for dynamic parameter updates. More...
 
carma_ros2_utils::CallbackReturn on_configure_plugin ()
 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...
 
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...
 
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...
 
void lookupFrontBumperTransform ()
 Lookup transfrom from front bumper to base link. More...
 
void mobilityOperationCb (carma_v2x_msgs::msg::MobilityOperation::UniquePtr msg)
 callback function for mobility operation More...
 
void BSMCb (carma_v2x_msgs::msg::BSM::UniquePtr msg)
 BSM callback function. More...
 
void parseStrategyParams (const std::string &strategy_params)
 parse strategy parameters More...
 
carma_v2x_msgs::msg::MobilityOperation generateMobilityOperation ()
 Generates Mobility Operation messages. More...
 
TurnDirection getTurnDirectionAtIntersection (std::vector< lanelet::ConstLanelet > lanelets_list)
 Determine the turn direction at intersection. More...
 
void publishMobilityOperation ()
 Publish mobility operation at a fixed rate. More...
 
void publishTrajectorySmoothingInfo ()
 Publish trajectory smoothing info at a fixed rate. More...
 
- Public Member Functions inherited from carma_guidance_plugins::StrategicPlugin
 StrategicPlugin (const rclcpp::NodeOptions &)
 StrategicPlugin constructor. More...
 
virtual ~StrategicPlugin ()=default
 Virtual destructor for safe deletion. More...
 
virtual void plan_maneuvers_callback (std::shared_ptr< rmw_request_id_t > srv_header, carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::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

void planWhenUNAVAILABLE (carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, const VehicleState &current_state, const lanelet::CarmaTrafficSignalPtr &traffic_light, const lanelet::ConstLanelet &entry_lanelet, const lanelet::ConstLanelet &exit_lanelet, const lanelet::ConstLanelet &current_lanelet)
 Method for performing maneuver planning when the current plugin state is TransitState::UNAVAILABLE Therefor no maneuvers are planned but the system checks for the precense of traffic lights ahead of it. More...
 
void planWhenAPPROACHING (carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, const VehicleState &current_state, const lanelet::CarmaTrafficSignalPtr &traffic_light, const lanelet::ConstLanelet &entry_lanelet, const lanelet::ConstLanelet &exit_lanelet, const lanelet::ConstLanelet &current_lanelet)
 Method for performing maneuver planning when the current plugin state is TransitState::APPROACHING Therefore the planned maneuvers deal with approaching a traffic light. More...
 
void planWhenWAITING (carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, const VehicleState &current_state, const lanelet::CarmaTrafficSignalPtr &traffic_light, const lanelet::ConstLanelet &entry_lanelet, const lanelet::ConstLanelet &exit_lanelet, const lanelet::ConstLanelet &current_lanelet)
 Method for performing maneuver planning when the current plugin state is TransitState::WAITING Therefor the planned maneuvers deal with waiting at a red light. More...
 
void planWhenDEPARTING (carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, const VehicleState &current_state, double intersection_end_downtrack, double intersection_speed_limit)
 Method for performing maneuver planning when the current plugin state is TransitState::DEPARTING Therefor the planned maneuvers deal with the transit of the intersection once the stop bar has been crossed. More...
 
boost::optional< bool > canArriveAtGreenWithCertainty (const rclcpp::Time &light_arrival_time_by_algo, const lanelet::CarmaTrafficSignalPtr &traffic_light, bool check_late, bool check_early) const
 Return true if the car can arrive at given arrival time within green light time buffer. More...
 
carma_planning_msgs::msg::Maneuver composeTrajectorySmoothingManeuverMessage (double start_dist, double end_dist, const std::vector< lanelet::ConstLanelet > &crossed_lanelets, double start_speed, double target_speed, rclcpp::Time start_time, rclcpp::Time end_time, const TrajectoryParams &tsp) const
 Compose a trajectory smoothing maneuver msg (sent as transit maneuver message) More...
 
carma_planning_msgs::msg::Maneuver composeStopAndWaitManeuverMessage (double current_dist, double end_dist, double start_speed, const lanelet::Id &starting_lane_id, const lanelet::Id &ending_lane_id, rclcpp::Time start_time, rclcpp::Time end_time, double stopping_accel) const
 Compose a stop and wait maneuver message based on input params. More...
 
carma_planning_msgs::msg::Maneuver composeIntersectionTransitMessage (double start_dist, double end_dist, double start_speed, double target_speed, rclcpp::Time start_time, rclcpp::Time end_time, const lanelet::Id &starting_lane_id, const lanelet::Id &ending_lane_id) const
 Compose a intersection transit maneuver message based on input params. More...
 
void handleStopping (carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, const VehicleState &current_state, const lanelet::CarmaTrafficSignalPtr &traffic_light, const lanelet::ConstLanelet &entry_lanelet, const lanelet::ConstLanelet &exit_lanelet, const lanelet::ConstLanelet &current_lanelet, double traffic_light_down_track, bool is_emergency=false)
 This function returns stopping maneuver if the vehicle is able to stop at red and in safe stopping distance. Given the initial speed, ending speed (which is 0), and remaining_downtrack, this function checks if calculated remaining_time falls on RED. More...
 
void handleGreenSignalScenario (carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, const VehicleState &current_state, double current_state_speed, const lanelet::CarmaTrafficSignalPtr &traffic_light, const lanelet::ConstLanelet &entry_lanelet, const lanelet::ConstLanelet &exit_lanelet, double traffic_light_down_track, const TrajectoryParams &ts_params, bool is_certainty_check_optional)
 This function returns valid maneuvers if the vehicle is able to utilize trajectory smoothing parameters to go through the intersection with certainty It utilizes canMakeWithCertainty function to determine if it is able to make it. Corresponds to TSCase 1-7. More...
 
void handleCruisingUntilStop (carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, const VehicleState &current_state, double current_state_speed, const lanelet::CarmaTrafficSignalPtr &traffic_light, double traffic_light_down_track, const TrajectoryParams &ts_params)
 This function returns valid maneuvers if the vehicle is able to utilize trajectory smoothing parameters to go through the intersection with certainty It utilizes canMakeWithCertainty function to determine if it is able to make it. Corresponds to TSCase 1-7. More...
 
void handleFailureCase (carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, const VehicleState &current_state, double current_state_speed, double speed_limit, double remaining_time, lanelet::Id exit_lanelet_id, const lanelet::CarmaTrafficSignalPtr &traffic_light, double traffic_light_down_track, const TrajectoryParams &ts_params)
 When the vehicle is not able to successfully run the algorithm or not able to stop, this function modifies departure speed as close as possible to the original using max comfortable accelerations with given distance. More...
 
TrajectoryParams handleFailureCaseHelper (const lanelet::CarmaTrafficSignalPtr &traffic_light, double current_time, double starting_speed, double departure_speed, double speed_limit, double remaining_downtrack, double traffic_light_downtrack)
 Helper function to handleFailureCase that modifies ts_params to desired new parameters. See handleFailureCase. More...
 
bool supportedLightState (lanelet::CarmaTrafficSignalState state) const
 Helper method to evaluate if the given traffic light state is supported by this plugin. More...
 
bool validLightState (const boost::optional< std::pair< boost::posix_time::ptime, lanelet::CarmaTrafficSignalState > > &optional_state, const rclcpp::Time &source_time) const
 Helper method that checks both if the input optional light state is set and if the state it contains is supported via supportedLightState. More...
 
VehicleState extractInitialState (carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req) const
 Helper method to extract the initial vehicle state from the planning request method based on if the prior_plan was set or not. More...
 
std::vector< lanelet::ConstLanelet > getLaneletsBetweenWithException (double start_downtrack, double end_downtrack, bool shortest_path_only=false, bool bounds_inclusive=true) const
 Helper method which calls carma_wm::WorldModel::getLaneletsBetween(start_downtrack, end_downtrack, shortest_path_only, bounds_inclusive) and throws and exception if the returned list of lanelets is empty. See the referenced method for additional details on parameters. More...
 
std::tuple< rclcpp::Time, bool, bool > get_final_entry_time_and_conditions (const VehicleState &current_state, const rclcpp::Time &earliest_entry_time, lanelet::CarmaTrafficSignalPtr traffic_light)
 Get the final entry time from either vehicle's own internal ET calculation (TSMO UC2) or from carma-street (TSMO UC3) This function also applies necessary green_buffer to adjust the ET. More...
 
std::optional< rclcpp::Time > get_nearest_green_entry_time (const rclcpp::Time &current_time, const rclcpp::Time &earliest_entry_time, const lanelet::CarmaTrafficSignalPtr &signal, double minimum_required_green_time=0.0) const
 Provides the scheduled entry time for the vehicle in the future. This scheduled time is the earliest possible entry time that is during green phase and after timestamps both that is kinematically possible and required times for vehicle in front to pass through first Returns std::nullopt if no valid green entry time found. More...
 
rclcpp::Time get_eet_or_tbd (const rclcpp::Time &earliest_entry_time, const lanelet::CarmaTrafficSignalPtr &signal) const
 Returns the later of earliest_entry_time or the end of the available signal states in the traffic_signal. More...
 
rclcpp::Duration get_earliest_entry_time (double remaining_distance, double free_flow_speed, double current_speed, double departure_speed, double max_accel, double max_decel) const
 Gets the earliest entry time into the intersection that is kinematically possible for the vehicle. Designed to get it for motion that has maximum one acceleration, deceleration, or cruise segments until destination. More...
 
double get_trajectory_smoothing_activation_distance (double time_remaining_at_free_flow, double full_cycle_duration, double current_speed, double speed_limit, double departure_speed, double max_accel, double max_decel) const
 Gets maximum distance (nearest downtrack) the trajectory smoothing algorithm makes difference than simple lane following within half of one full fixed cycle time boundary compared to free flow arrival time. More...
 
double get_distance_to_accel_or_decel_twice (double free_flow_speed, double current_speed, double departure_speed, double max_accel, double max_decel) const
 Get required distance to accel then decel, or vise versa - each at least once - to reach departure_speed with given speed and acceleration parameters. More...
 
double get_inflection_speed_value (double x, double x1, double x2, double free_flow_speed, double current_speed, double departure_speed, double max_accel, double max_decel) const
 Get the speed between the acceleration and deceleration pieces. More...
 
double get_distance_to_accel_or_decel_once (double current_speed, double departure_speed, double max_accel, double max_decel) const
 Get required distance to accel or decel to reach departure_speed with given speed and acceleration parameters. More...
 
double estimate_distance_to_stop (double v, double a) const
 Helper method to use basic kinematics to compute an estimated stopping distance from from the inputs. More...
 
double estimate_time_to_stop (double d, double v) const
 Helper method to use basic kinematics to compute an estimated stopping time from from the inputs. More...
 
double findSpeedLimit (const lanelet::ConstLanelet &llt) const
 Given a Lanelet, find it's associated Speed Limit. More...
 
double calc_estimated_entry_time_left (double entry_dist, double current_speed, double departure_speed) const
 calculate the time vehicle will enter to intersection with optimal deceleration More...
 
BoundaryDistances get_delta_x (double v0, double v1, double v_max, double v_min, double a_max, double a_min)
 Get boundary distances used to compare against current state in order to create trajectory smoothing parameters. More...
 
std::vector< TrajectoryParamsget_boundary_traj_params (double t, double v0, double v1, double v_max, double v_min, double a_max, double a_min, double x0, double x_end, double dx, BoundaryDistances boundary_distances)
 Get all possible trajectory smoothing parameters for each segments. Later this will be used to generate a single trajectory. More...
 
void print_params (TrajectoryParams params)
 Helper method to print TrajectoryParams. More...
 
void print_boundary_distances (BoundaryDistances delta_xs)
 Helper method to print TrajectoryParams. More...
 
TrajectoryParams ts_case1 (double t, double et, double v0, double v1, double v_max, double a_max, double a_min, double x0, double x_end, double dx)
 Trajectory Smoothing Algorithm 8 cases. TSMO UC2, UC3 algorithm equations. More...
 
TrajectoryParams ts_case2 (double t, double et, double v0, double v1, double a_max, double a_min, double x0, double x_end, double dx)
 
TrajectoryParams ts_case3 (double t, double et, double v0, double v1, double a_max, double a_min, double x0, double x_end, double dx)
 
TrajectoryParams ts_case4 (double t, double et, double v0, double v1, double v_min, double a_max, double a_min, double x0, double x_end, double dx)
 
TrajectoryParams ts_case5 (double t, double et, double v0, double a_max, double a_min, double x0, double x_end, double dx)
 
TrajectoryParams ts_case6 (double t, double et, double v0, double v_min, double a_min, double x0, double x_end, double dx, double dx3, TrajectoryParams traj6)
 
TrajectoryParams ts_case7 (double t, double et, double v0, double v_min, double a_min, double x0, double x_end, double dx)
 
TrajectoryParams ts_case8 (double dx, double dx5, TrajectoryParams traj8)
 
TrajectoryParams boundary_accel_or_decel_incomplete_upper (double t, double v0, double v1, double a_max, double a_min, double x0, double x_end, double dx)
 
TrajectoryParams boundary_accel_nocruise_notmaxspeed_decel (double t, double v0, double v1, double a_max, double a_min, double x0, double x_end, double dx)
 
TrajectoryParams boundary_accel_cruise_maxspeed_decel (double t, double v0, double v1, double v_max, double a_max, double a_min, double x0, double x_end, double dx)
 
TrajectoryParams boundary_accel_nocruise_maxspeed_decel (double t, double v0, double v1, double v_max, double a_max, double a_min, double x0, double x_end, double dx)
 
TrajectoryParams boundary_accel_or_decel_complete_upper (double t, double v0, double v1, double x0, double x_end, double dx)
 
TrajectoryParams boundary_decel_nocruise_notminspeed_accel (double t, double v0, double v1, double v_min, double a_max, double a_min, double x0, double x_end, double dx)
 
TrajectoryParams boundary_decel_nocruise_minspeed_accel_incomplete (double t, double v0, double v_min, double a_max, double a_min, double x0, double x_end, double dx)
 
TrajectoryParams boundary_decel_nocruise_minspeed_accel_complete (double t, double v0, double v1, double v_max, double v_min, double a_max, double a_min, double x0, double x_end, double dx)
 
TrajectoryParams boundary_decel_cruise_minspeed_accel (double t, double v0, double v1, double v_min, double a_max, double a_min, double x0, double x_end, double dx)
 
TrajectoryParams boundary_decel_cruise_minspeed (double t, double v0, double v_min, double a_min, double x0, double x_end, double dx)
 
TrajectoryParams boundary_decel_incomplete_lower (double t, double v0, double a_min, double x0, double x_end, double dx)
 
TrajectoryParams boundary_decel_cruise_minspeed_decel (double t, double v0, double v_min, double a_min, double x0, double x_end, double dx)
 
TrajectoryParams get_ts_case (double t, double et, double v0, double v1, double v_max, double v_min, double a_max, double a_min, double x0, double x_end, double dx, BoundaryDistances boundary_distances, std::vector< TrajectoryParams > params)
 
 FRIEND_TEST (LCIStrategicTestFixture, getDiscoveryMsg)
 
 FRIEND_TEST (LCIStrategicTestFixture, supportedLightState)
 
 FRIEND_TEST (LCIStrategicTestFixture, estimate_distance_to_stop)
 
 FRIEND_TEST (LCIStrategicTestFixture, estimate_time_to_stop)
 
 FRIEND_TEST (LCIStrategicTestFixture, extractInitialState)
 
 FRIEND_TEST (LCIStrategicTestFixture, DISABLED_extractInitialState)
 
 FRIEND_TEST (LCIStrategicTestFixture, validLightState)
 
 FRIEND_TEST (LCIStrategicTestFixture, getLaneletsBetweenWithException)
 
 FRIEND_TEST (LCIStrategicTestFixture, composeStopAndWaitManeuverMessage)
 
 FRIEND_TEST (LCIStrategicTestFixture, composeIntersectionTransitMessage)
 
 FRIEND_TEST (LCIStrategicTestFixture, composeTrajectorySmoothingManeuverMessage)
 
 FRIEND_TEST (LCIStrategicTestFixture, handleFailureCaseHelper)
 
 FRIEND_TEST (LCIStrategicTestFixture, planWhenETInTBD)
 
 FRIEND_TEST (LCIStrategicTestFixture, calc_estimated_entry_time_left)
 
 FRIEND_TEST (LCIStrategicTestFixture, get_distance_to_accel_or_decel_twice)
 
 FRIEND_TEST (LCIStrategicTestFixture, get_distance_to_accel_or_decel_once)
 
 FRIEND_TEST (LCIStrategicTestFixture, get_nearest_green_entry_time)
 
 FRIEND_TEST (LCIStrategicTestFixture, get_eet_or_tbd)
 
 FRIEND_TEST (LCIStrategicTestFixture, get_earliest_entry_time)
 
 FRIEND_TEST (LCIStrategicTestFixture, handleFailureCase)
 
 FRIEND_TEST (LCIStrategicTestFixture, handleStopping)
 
 FRIEND_TEST (LCIStrategicTestFixture, planManeuverCb)
 
 FRIEND_TEST (LCIStrategicTestFixture, DISABLED_planManeuverCb)
 
 FRIEND_TEST (LCIStrategicPluginTest, parseStrategyParamstest)
 
 FRIEND_TEST (LCIStrategicPluginTest, moboperationcbtest)
 
 FRIEND_TEST (LCIStrategicTestFixture, findSpeedLimit)
 
 FRIEND_TEST (LCIStrategicTestFixture, DISABLED_planWhenETInTBD)
 

Private Attributes

unsigned long long street_msg_timestamp_ = 0
 
unsigned long long scheduled_enter_time_ = 0
 
std::string previous_strategy_params_ = ""
 
std::string upcoming_id_ = ""
 
std::string bsm_id_ = "default_bsm_id"
 
uint8_t bsm_msg_count_ = 0
 
uint16_t bsm_sec_mark_ = 0
 
double max_comfort_accel_ = 2.0
 
double max_comfort_decel_ = -2.0
 
double max_comfort_decel_norm_ = -1 * max_comfort_decel_
 
double emergency_decel_norm_ = -2 * max_comfort_decel_
 
boost::optional< rclcpp::Time > nearest_green_entry_time_cached_
 
TSCase last_case_num_ = TSCase::UNAVAILABLE
 Useful metrics for LCI Plugin. More...
 
double distance_remaining_to_tf_ = 0.0
 
double earliest_entry_time_ = 0.0
 
double scheduled_entry_time_ = 0.0
 
TurnDirection intersection_turn_direction_ = TurnDirection::Straight
 
bool approaching_light_controlled_intersection_ = false
 
LCIStrategicPluginConfig config_
 Config containing configurable algorithm parameters. More...
 
LCIStrategicStateTransitionTable transition_table_
 State Machine Transition table. More...
 
boost::optional< double > intersection_speed_
 Cache variables for storing the current intersection state between state machine transitions. More...
 
boost::optional< double > intersection_end_downtrack_
 
std::string light_controlled_intersection_strategy_ = "Carma/signalized_intersection"
 
tf2_ros::Buffer tf2_buffer_
 
std::unique_ptr< tf2_ros::TransformListener > tf2_listener_
 
tf2::Stamped< tf2::Transform > frontbumper_transform_
 
double length_to_front_bumper_ = 3.0
 
double epsilon_ = 0.001
 
double accel_epsilon_ = 0.0001
 
carma_wm::WorldModelConstPtr wm_
 World Model pointer. More...
 
rclcpp::TimerBase::SharedPtr mob_op_pub_timer_
 
rclcpp::TimerBase::SharedPtr ts_info_pub_timer_
 
carma_ros2_utils::SubPtr< carma_v2x_msgs::msg::MobilityOperation > mob_operation_sub_
 
carma_ros2_utils::SubPtr< carma_v2x_msgs::msg::BSM > bsm_sub_
 
carma_ros2_utils::PubPtr< carma_v2x_msgs::msg::MobilityOperation > mobility_operation_pub_
 
carma_ros2_utils::PubPtr< std_msgs::msg::Int8 > case_pub_
 
carma_ros2_utils::PubPtr< std_msgs::msg::Float64 > tf_distance_pub_
 
carma_ros2_utils::PubPtr< std_msgs::msg::Float64 > earliest_et_pub_
 
carma_ros2_utils::PubPtr< std_msgs::msg::Float64 > et_pub_
 

Detailed Description

Definition at line 112 of file lci_strategic_plugin.hpp.

Constructor & Destructor Documentation

◆ LCIStrategicPlugin()

lci_strategic_plugin::LCIStrategicPlugin::LCIStrategicPlugin ( const rclcpp::NodeOptions &  options)
explicit

Default constructor for RouteFollowingPlugin class.

Definition at line 42 of file lci_strategic_plugin.cpp.

43 : carma_guidance_plugins::StrategicPlugin(options), tf2_buffer_(this->get_clock())
44{
45 config_ = LCIStrategicPluginConfig();
46
47 config_.vehicle_accel_limit = declare_parameter<double>("vehicle_acceleration_limit", config_.vehicle_accel_limit);
48 config_.vehicle_decel_limit = declare_parameter<double>("vehicle_deceleration_limit", config_.vehicle_decel_limit);
49 config_.vehicle_decel_limit_multiplier = declare_parameter<double>("vehicle_decel_limit_multiplier", config_.vehicle_decel_limit_multiplier);
50 config_.vehicle_accel_limit_multiplier = declare_parameter<double>("vehicle_accel_limit_multiplier", config_.vehicle_accel_limit_multiplier);
51 config_.min_approach_distance = declare_parameter<double>("min_approach_distance", config_.min_approach_distance);
52 config_.trajectory_smoothing_activation_distance = declare_parameter<double>("trajectory_smoothing_activation_distance", config_.trajectory_smoothing_activation_distance);
53 config_.stopping_location_buffer = declare_parameter<double>("stopping_location_buffer", config_.stopping_location_buffer);
54 config_.green_light_time_buffer = declare_parameter<double>("green_light_time_buffer", config_.green_light_time_buffer);
55 config_.algo_minimum_speed = declare_parameter<double>("algo_minimum_speed", config_.algo_minimum_speed);
56 config_.deceleration_fraction = declare_parameter<double>("deceleration_fraction", config_.deceleration_fraction);
57 config_.desired_distance_to_stop_buffer = declare_parameter<double>("desired_distance_to_stop_buffer", config_.desired_distance_to_stop_buffer);
58 config_.min_maneuver_planning_period = declare_parameter<double>("min_maneuver_planning_period", config_.min_maneuver_planning_period);
59 config_.strategic_plugin_name = declare_parameter<std::string>("strategic_plugin_name", config_.strategic_plugin_name);
60 config_.lane_following_plugin_name = declare_parameter<std::string>("lane_following_plugin_name", config_.lane_following_plugin_name);
61 config_.stop_and_wait_plugin_name = declare_parameter<std::string>("stop_and_wait_plugin_name", config_.stop_and_wait_plugin_name);
62 config_.intersection_transit_plugin_name = declare_parameter<std::string>("intersection_transit_plugin_name", config_.intersection_transit_plugin_name);
63 config_.enable_carma_streets_connection = declare_parameter<bool>("enable_carma_streets_connection",config_.enable_carma_streets_connection);
64 config_.mobility_rate = declare_parameter<double>("mobility_rate", config_.mobility_rate);
65 config_.vehicle_id = declare_parameter<std::string>("vehicle_id", config_.vehicle_id);
66
71};
StrategicPlugin base class which can be extended by user provided plugins which wish to implement the...
LCIStrategicPluginConfig config_
Config containing configurable algorithm parameters.
bool enable_carma_streets_connection
Bool: Enable carma streets connection.
std::string vehicle_id
License plate of the vehicle.
double trajectory_smoothing_activation_distance
Downtrack distance until nearest intersection where the Trajectory Smoothing algorithm should activat...
double algo_minimum_speed
Minimum allowable speed TS algorithm in m/s.
double vehicle_accel_limit_multiplier
A multiplier to apply to the maximum allowable vehicle acceleration limit so we plan under our capabi...
double min_maneuver_planning_period
The minimum period in seconds which a maneuver plan must cover if the plugin wishes to control the wh...
double green_light_time_buffer
A buffer in seconds around the green phase which will reduce the phase length such that vehicle still...
std::string stop_and_wait_plugin_name
The name of the plugin to use for stop and wait trajectory planning.
double stopping_location_buffer
A buffer infront of the stopping location which will still be considered a valid stop....
double vehicle_decel_limit
The maximum allowable vehicle deceleration limit in m/s.
double vehicle_decel_limit_multiplier
A multiplier to apply to the maximum allowable vehicle deceleration limit so we plan under our capabi...
double min_approach_distance
The minimum distance in meters that the vehicle can be at before requiring a transition to the APPROA...
double vehicle_accel_limit
The maximum allowable vehicle acceleration limit in m/s.
std::string strategic_plugin_name
The name to use for this plugin during comminications with the arbitrator.
double mobility_rate
Double: Mobility operation rate.
double desired_distance_to_stop_buffer
Double: Desired distance to stop buffer in meters.

References lci_strategic_plugin::LCIStrategicPluginConfig::algo_minimum_speed, config_, lci_strategic_plugin::LCIStrategicPluginConfig::deceleration_fraction, lci_strategic_plugin::LCIStrategicPluginConfig::desired_distance_to_stop_buffer, emergency_decel_norm_, lci_strategic_plugin::LCIStrategicPluginConfig::enable_carma_streets_connection, lci_strategic_plugin::LCIStrategicPluginConfig::green_light_time_buffer, lci_strategic_plugin::LCIStrategicPluginConfig::intersection_transit_plugin_name, lci_strategic_plugin::LCIStrategicPluginConfig::lane_following_plugin_name, max_comfort_accel_, max_comfort_decel_, max_comfort_decel_norm_, lci_strategic_plugin::LCIStrategicPluginConfig::min_approach_distance, lci_strategic_plugin::LCIStrategicPluginConfig::min_maneuver_planning_period, lci_strategic_plugin::LCIStrategicPluginConfig::mobility_rate, lci_strategic_plugin::LCIStrategicPluginConfig::stop_and_wait_plugin_name, lci_strategic_plugin::LCIStrategicPluginConfig::stopping_location_buffer, lci_strategic_plugin::LCIStrategicPluginConfig::strategic_plugin_name, lci_strategic_plugin::LCIStrategicPluginConfig::trajectory_smoothing_activation_distance, lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_accel_limit, lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_accel_limit_multiplier, lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_decel_limit, lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_decel_limit_multiplier, and lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_id.

Member Function Documentation

◆ boundary_accel_cruise_maxspeed_decel()

TrajectoryParams lci_strategic_plugin::LCIStrategicPlugin::boundary_accel_cruise_maxspeed_decel ( double  t,
double  v0,
double  v1,
double  v_max,
double  a_max,
double  a_min,
double  x0,
double  x_end,
double  dx 
)
private

Definition at line 1049 of file lci_strategic_plugin_algo.cpp.

1050{
1051 double t_end = t + (dx / v_max) + (pow(v_max - v0, 2) / (2 * a_max * v_max)) - (pow(v1 - v_max, 2) / (2 * a_min * v_max));
1052
1053 TrajectoryParams traj;
1054
1055 traj.t0_ = t;
1056 traj.v0_ = v0;
1057 traj.x0_ = x0;
1058
1059 traj.v1_ = v_max;
1060 traj.a1_ = a_max;
1061 traj.t1_ = traj.t0_ + ((traj.v1_ - traj.v0_) / traj.a1_);
1062 traj.x1_ = traj.x0_ + ((pow(traj.v1_, 2) - pow(traj.v0_, 2)) / (2 * traj.a1_));
1063
1064 traj.v2_ = v_max;
1065 traj.a2_ = 0;
1066 traj.t2_ = t_end - ((v1 - v_max) / a_min);
1067 traj.x2_ = x_end - ((pow(v1, 2) - pow(v_max, 2)) / (2 * a_min));
1068
1069 traj.t3_ = t_end;
1070 traj.a3_ = a_min;
1071 traj.v3_ = v1;
1072 traj.x3_ = x_end;
1073
1074 return traj;
1075}

References lci_strategic_plugin::TrajectoryParams::a1_, lci_strategic_plugin::TrajectoryParams::a2_, lci_strategic_plugin::TrajectoryParams::a3_, lci_strategic_plugin::TrajectoryParams::t0_, lci_strategic_plugin::TrajectoryParams::t1_, lci_strategic_plugin::TrajectoryParams::t2_, lci_strategic_plugin::TrajectoryParams::t3_, lci_strategic_plugin::TrajectoryParams::v0_, lci_strategic_plugin::TrajectoryParams::v1_, lci_strategic_plugin::TrajectoryParams::v2_, lci_strategic_plugin::TrajectoryParams::v3_, lci_strategic_plugin::TrajectoryParams::x0_, lci_strategic_plugin::TrajectoryParams::x1_, lci_strategic_plugin::TrajectoryParams::x2_, and lci_strategic_plugin::TrajectoryParams::x3_.

Referenced by get_boundary_traj_params().

Here is the caller graph for this function:

◆ boundary_accel_nocruise_maxspeed_decel()

TrajectoryParams lci_strategic_plugin::LCIStrategicPlugin::boundary_accel_nocruise_maxspeed_decel ( double  t,
double  v0,
double  v1,
double  v_max,
double  a_max,
double  a_min,
double  x0,
double  x_end,
double  dx 
)
private

Definition at line 1077 of file lci_strategic_plugin_algo.cpp.

1078{
1079 double nom = (v_max - v0) + ((a_max / a_min) * (v1 - v_max));
1080 double den = (pow(v_max, 2) - pow(v0, 2)) + ((a_max / a_min) * (pow(v1, 2) - pow(v_max, 2)));
1081
1082 if (den <= epsilon_ && den >= -epsilon_)
1083 throw std::invalid_argument("boundary_accel_nocruise_maxspeed_decel: Received den near zero..." + std::to_string(den));
1084
1085 double t_end = t + (2 * dx * nom / den);
1086
1087 TrajectoryParams traj;
1088
1089 traj.t0_ = t;
1090 traj.v0_ = v0;
1091 traj.x0_ = x0;
1092
1093 double dt = t_end - t;
1094 double tc = 0;
1095
1096 traj.v1_ = v_max;
1097
1098 if (dt - tc <= epsilon_ && dt - tc >= -epsilon_)
1099 throw std::invalid_argument("boundary_accel_nocruise_maxspeed_decel: Received dt - tc near zero..." + std::to_string(dt - tc));
1100
1101 traj.a1_ = (((1 - (a_max / a_min)) * v_max) + ((a_max / a_min) * v1) - v0) / (dt - tc);
1102
1103 if (traj.a1_ <= accel_epsilon_ && traj.a1_ >= -accel_epsilon_)
1104 {
1105 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "boundary_accel_nocruise_maxspeed_decel: Received traj.a1_ near zero...");
1106 traj.t1_ = traj.t0_ + (dt * (a_max / (a_min + a_max)));
1107 traj.x1_ = traj.x0_ + (v_max * (traj.t1_ - traj.t0_));
1108 }
1109 else
1110 {
1111 traj.t1_ = traj.t0_ + ((traj.v1_ - traj.v0_) / traj.a1_);
1112 traj.x1_ = traj.x0_ + ((pow(traj.v1_, 2) - pow(traj.v0_, 2)) / (2 * traj.a1_));
1113 }
1114
1115 traj.t2_ = t_end;
1116 traj.a2_ = ((((a_min / a_max) - 1) * v_max) + v1 - ((a_min / a_max) * v0)) / (dt - tc);
1117 traj.v2_ = v1;
1118 traj.x2_ = x_end;
1119
1120 traj.t3_ = traj.t2_;
1121 traj.a3_ = 0;
1122 traj.v3_ = traj.v2_;
1123 traj.x3_ = traj.x2_;
1124
1125 return traj;
1126}
auto to_string(const UtmZone &zone) -> std::string
Definition: utm_zone.cpp:21

References accel_epsilon_, epsilon_, lci_strategic_plugin::TrajectoryParams::t0_, and carma_cooperative_perception::to_string().

Referenced by get_boundary_traj_params().

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

◆ boundary_accel_nocruise_notmaxspeed_decel()

TrajectoryParams lci_strategic_plugin::LCIStrategicPlugin::boundary_accel_nocruise_notmaxspeed_decel ( double  t,
double  v0,
double  v1,
double  a_max,
double  a_min,
double  x0,
double  x_end,
double  dx 
)
private

Definition at line 1017 of file lci_strategic_plugin_algo.cpp.

1018{
1019
1020 double v_hat = sqrt(((2 * dx * a_max * a_min) + (a_min * pow(v0, 2)) - (a_max * pow(v1, 2))) / (a_min - a_max));
1021 double t_end = t + ((v_hat * (a_min - a_max)) - (v0 * a_min) + (v1 * a_max)) / (a_max * a_min);
1022
1023 TrajectoryParams traj;
1024
1025 traj.t0_ = t;
1026 traj.v0_ = v0;
1027 traj.x0_ = x0;
1028
1029 traj.v1_ = v_hat;
1030 traj.a1_ = a_max;
1031 traj.t1_ = traj.t0_ + ((traj.v1_ - traj.v0_) / traj.a1_);
1032
1033 traj.x1_ = traj.x0_ + ((pow(traj.v1_, 2) - pow(traj.v0_, 2)) / (2 * traj.a1_));
1034
1035 traj.t2_ = t_end;
1036 traj.a2_ = a_min;
1037 traj.v2_ = v1;
1038 traj.x2_ = x_end;
1039
1040 traj.t3_ = traj.t2_;
1041 traj.a3_ = 0;
1042 traj.v3_ = traj.v2_;
1043 traj.x3_ = traj.x2_;
1044
1045 return traj;
1046
1047}

References lci_strategic_plugin::TrajectoryParams::a1_, lci_strategic_plugin::TrajectoryParams::a2_, lci_strategic_plugin::TrajectoryParams::a3_, lci_strategic_plugin::TrajectoryParams::t0_, lci_strategic_plugin::TrajectoryParams::t1_, lci_strategic_plugin::TrajectoryParams::t2_, lci_strategic_plugin::TrajectoryParams::t3_, lci_strategic_plugin::TrajectoryParams::v0_, lci_strategic_plugin::TrajectoryParams::v1_, lci_strategic_plugin::TrajectoryParams::v2_, lci_strategic_plugin::TrajectoryParams::v3_, lci_strategic_plugin::TrajectoryParams::x0_, lci_strategic_plugin::TrajectoryParams::x1_, lci_strategic_plugin::TrajectoryParams::x2_, and lci_strategic_plugin::TrajectoryParams::x3_.

Referenced by get_boundary_traj_params().

Here is the caller graph for this function:

◆ boundary_accel_or_decel_complete_upper()

TrajectoryParams lci_strategic_plugin::LCIStrategicPlugin::boundary_accel_or_decel_complete_upper ( double  t,
double  v0,
double  v1,
double  x0,
double  x_end,
double  dx 
)
private

Definition at line 1128 of file lci_strategic_plugin_algo.cpp.

1129{
1130 if (v0 + v1 <= epsilon_ && v0 + v1 >= -epsilon_)
1131 throw std::invalid_argument("boundary_accel_or_decel_complete_upper: Received v0 + v1 near zero..." + std::to_string(v0 + v1));
1132
1133 double t_end = t + ((2 * dx) / (v0 + v1));
1134
1135 TrajectoryParams traj;
1136
1137 traj.t0_ = t;
1138 traj.v0_ = v0;
1139 traj.x0_ = x0;
1140
1141 traj.t1_ = t_end;
1142
1143 if (dx <= epsilon_ && dx >= -epsilon_)
1144 throw std::invalid_argument("boundary_accel_or_decel_complete_upper: Received dx near zero..." + std::to_string(dx));
1145
1146 traj.a1_ = (pow(v1, 2) - pow(v0, 2)) / (2 * dx);
1147 traj.v1_ = v1;
1148 traj.x1_ = x_end;
1149
1150 traj.t2_ = traj.t1_;
1151 traj.a2_ = 0;
1152 traj.v2_ = traj.v1_;
1153 traj.x2_ = traj.x1_;
1154
1155 traj.t3_ = traj.t1_;
1156 traj.a3_ = 0;
1157 traj.v3_ = traj.v1_;
1158 traj.x3_ = traj.x1_;
1159
1160 return traj;
1161}

References epsilon_, lci_strategic_plugin::TrajectoryParams::t0_, and carma_cooperative_perception::to_string().

Referenced by get_boundary_traj_params().

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

◆ boundary_accel_or_decel_incomplete_upper()

TrajectoryParams lci_strategic_plugin::LCIStrategicPlugin::boundary_accel_or_decel_incomplete_upper ( double  t,
double  v0,
double  v1,
double  a_max,
double  a_min,
double  x0,
double  x_end,
double  dx 
)
private

Definition at line 974 of file lci_strategic_plugin_algo.cpp.

975{
976 double t_end;
977
978 if (v0 <= v1 + epsilon_)
979 t_end = t + (sqrt(pow(v0, 2) + (2 * a_max * dx)) - v0)/a_max;
980 else
981 t_end = t + (sqrt(pow(v0, 2) + (2 * a_min * dx)) - v0) / a_min;
982
983 TrajectoryParams traj;
984
985 traj.t0_ = t;
986 traj.v0_ = v0;
987 traj.x0_ = x0;
988
989 traj.t1_ = t_end;
990
991 if (v0 <= v1 + epsilon_)
992 {
993 traj.a1_ = a_max;
994 traj.v1_ = sqrt(pow(v0, 2) + (2 * a_max * dx));
995 }
996 else
997 {
998 traj.a1_ = a_min;
999 traj.v1_ = sqrt(pow(v0, 2) + (2 * a_min * dx));
1000 }
1001
1002 traj.x1_ = x_end;
1003
1004 traj.t2_ = traj.t1_;
1005 traj.a2_ = 0;
1006 traj.v2_ = traj.v1_;
1007 traj.x2_ = traj.x1_;
1008
1009 traj.t3_ = traj.t1_;
1010 traj.a3_ = 0;
1011 traj.v3_ = traj.v1_;
1012 traj.x3_ = traj.x1_;
1013
1014 return traj;
1015}

References epsilon_, and lci_strategic_plugin::TrajectoryParams::t0_.

Referenced by get_boundary_traj_params().

Here is the caller graph for this function:

◆ boundary_decel_cruise_minspeed()

TrajectoryParams lci_strategic_plugin::LCIStrategicPlugin::boundary_decel_cruise_minspeed ( double  t,
double  v0,
double  v_min,
double  a_min,
double  x0,
double  x_end,
double  dx 
)
private

Definition at line 1289 of file lci_strategic_plugin_algo.cpp.

1290{
1291 double t_end = t + (dx / v_min) + (pow(v_min - v0, 2) / (2 * a_min * v_min));
1292
1293 TrajectoryParams traj;
1294
1295 traj.t0_ = t;
1296 traj.v0_ = v0;
1297 traj.x0_ = x0;
1298
1299 traj.v1_ = v_min;
1300 traj.a1_ = a_min;
1301 traj.t1_ = traj.t0_ + ((traj.v1_ - traj.v0_) / traj.a1_);
1302 traj.x1_ = traj.x0_ + ((pow(traj.v1_, 2) - pow(traj.v0_, 2)) / (2 * traj.a1_));
1303
1304 traj.v2_ = v_min;
1305 traj.a2_ = 0;
1306 traj.t2_ = t_end;
1307 traj.x2_ = x_end;
1308
1309 traj.t3_ = traj.t2_;
1310 traj.a3_ = traj.a2_;
1311 traj.v3_ = traj.v2_;
1312 traj.x3_ = traj.x2_;
1313
1314 return traj;
1315}

References lci_strategic_plugin::TrajectoryParams::a1_, lci_strategic_plugin::TrajectoryParams::a2_, lci_strategic_plugin::TrajectoryParams::a3_, lci_strategic_plugin::TrajectoryParams::t0_, lci_strategic_plugin::TrajectoryParams::t1_, lci_strategic_plugin::TrajectoryParams::t2_, lci_strategic_plugin::TrajectoryParams::t3_, lci_strategic_plugin::TrajectoryParams::v0_, lci_strategic_plugin::TrajectoryParams::v1_, lci_strategic_plugin::TrajectoryParams::v2_, lci_strategic_plugin::TrajectoryParams::v3_, lci_strategic_plugin::TrajectoryParams::x0_, lci_strategic_plugin::TrajectoryParams::x1_, lci_strategic_plugin::TrajectoryParams::x2_, and lci_strategic_plugin::TrajectoryParams::x3_.

Referenced by get_boundary_traj_params().

Here is the caller graph for this function:

◆ boundary_decel_cruise_minspeed_accel()

TrajectoryParams lci_strategic_plugin::LCIStrategicPlugin::boundary_decel_cruise_minspeed_accel ( double  t,
double  v0,
double  v1,
double  v_min,
double  a_max,
double  a_min,
double  x0,
double  x_end,
double  dx 
)
private

Definition at line 1261 of file lci_strategic_plugin_algo.cpp.

1262{
1263 double t_end = t + (dx / v_min) + ((pow(v_min - v0, 2)) / (2 * a_min * v_min)) - ((pow(v1 - v_min, 2)) / (2 * a_max * v_min));
1264
1265 TrajectoryParams traj;
1266
1267 traj.t0_ = t;
1268 traj.v0_ = v0;
1269 traj.x0_ = x0;
1270
1271 traj.v1_ = v_min;
1272 traj.a1_ = a_min;
1273 traj.t1_ = traj.t0_ + ((traj.v1_ - traj.v0_) / traj.a1_);
1274 traj.x1_ = traj.x0_ + ((pow(traj.v1_, 2) - pow(traj.v0_, 2)) / (2 * traj.a1_));
1275
1276 traj.v2_ = v_min;
1277 traj.a2_ = 0;
1278 traj.t2_ = t_end - ((v1 - v_min) / a_max);
1279 traj.x2_ = x_end - ((pow(v1, 2) - pow(v_min, 2)) / (2 * a_max));
1280
1281 traj.t3_ = t_end;
1282 traj.a3_ = a_max;
1283 traj.v3_ = v1;
1284 traj.x3_ = x_end;
1285
1286 return traj;
1287}

References lci_strategic_plugin::TrajectoryParams::a1_, lci_strategic_plugin::TrajectoryParams::a2_, lci_strategic_plugin::TrajectoryParams::a3_, lci_strategic_plugin::TrajectoryParams::t0_, lci_strategic_plugin::TrajectoryParams::t1_, lci_strategic_plugin::TrajectoryParams::t2_, lci_strategic_plugin::TrajectoryParams::t3_, lci_strategic_plugin::TrajectoryParams::v0_, lci_strategic_plugin::TrajectoryParams::v1_, lci_strategic_plugin::TrajectoryParams::v2_, lci_strategic_plugin::TrajectoryParams::v3_, lci_strategic_plugin::TrajectoryParams::x0_, lci_strategic_plugin::TrajectoryParams::x1_, lci_strategic_plugin::TrajectoryParams::x2_, and lci_strategic_plugin::TrajectoryParams::x3_.

Referenced by get_boundary_traj_params().

Here is the caller graph for this function:

◆ boundary_decel_cruise_minspeed_decel()

TrajectoryParams lci_strategic_plugin::LCIStrategicPlugin::boundary_decel_cruise_minspeed_decel ( double  t,
double  v0,
double  v_min,
double  a_min,
double  x0,
double  x_end,
double  dx 
)
private

Definition at line 1343 of file lci_strategic_plugin_algo.cpp.

1344{
1345 double t_end = t + (dx / v_min) + (v0 * (v0 - (2 * v_min)) / (2 * a_min * v_min));
1346
1347 TrajectoryParams traj;
1348
1349 traj.t0_ = t;
1350 traj.v0_ = v0;
1351 traj.x0_ = x0;
1352
1353 traj.v1_ = v_min;
1354 traj.a1_ = a_min;
1355 traj.t1_ = traj.t0_ + ((traj.v1_ - traj.v0_) / traj.a1_);
1356 traj.x1_ = traj.x0_ + ((pow(traj.v1_, 2) - pow(traj.v0_, 2)) / (2 * traj.a1_));
1357
1358 traj.a2_ = 0;
1359 traj.v2_ = v_min;
1360 traj.t2_ = t_end - ((0 - traj.v2_) / a_min);
1361 traj.x2_ = x_end - ((0 - pow(traj.v2_, 2)) / (2 * a_min));
1362
1363 traj.t3_ = t_end;
1364 traj.a3_ = a_min;
1365 traj.v3_ = 0;
1366 traj.x3_ = x_end;
1367
1368 return traj;
1369}

References lci_strategic_plugin::TrajectoryParams::a1_, lci_strategic_plugin::TrajectoryParams::a2_, lci_strategic_plugin::TrajectoryParams::a3_, lci_strategic_plugin::TrajectoryParams::t0_, lci_strategic_plugin::TrajectoryParams::t1_, lci_strategic_plugin::TrajectoryParams::t2_, lci_strategic_plugin::TrajectoryParams::t3_, lci_strategic_plugin::TrajectoryParams::v0_, lci_strategic_plugin::TrajectoryParams::v1_, lci_strategic_plugin::TrajectoryParams::v2_, lci_strategic_plugin::TrajectoryParams::v3_, lci_strategic_plugin::TrajectoryParams::x0_, lci_strategic_plugin::TrajectoryParams::x1_, lci_strategic_plugin::TrajectoryParams::x2_, and lci_strategic_plugin::TrajectoryParams::x3_.

Referenced by get_boundary_traj_params().

Here is the caller graph for this function:

◆ boundary_decel_incomplete_lower()

TrajectoryParams lci_strategic_plugin::LCIStrategicPlugin::boundary_decel_incomplete_lower ( double  t,
double  v0,
double  a_min,
double  x0,
double  x_end,
double  dx 
)
private

Definition at line 1316 of file lci_strategic_plugin_algo.cpp.

1317{
1318 double t_end = t + (sqrt(pow(v0, 2) + (2 * a_min * dx)) - v0) / a_min;
1319
1320 TrajectoryParams traj;
1321
1322 traj.t0_ = t;
1323 traj.v0_ = v0;
1324 traj.x0_ = x0;
1325
1326 traj.t1_ = t_end;
1327 traj.v1_ = sqrt(pow(v0, 2) + (2 * a_min * dx));
1328 traj.a1_ = a_min;
1329 traj.x1_ = x_end;
1330
1331 traj.t2_ = traj.t1_;
1332 traj.a2_ = 0;
1333 traj.v2_ = traj.v1_;
1334 traj.x2_ = traj.x1_;
1335
1336 traj.t3_ = traj.t1_;
1337 traj.a3_ = 0;
1338 traj.v3_ = traj.v1_;
1339 traj.x3_ = traj.x1_;
1340
1341 return traj;
1342}

References lci_strategic_plugin::TrajectoryParams::t0_.

Referenced by get_boundary_traj_params().

Here is the caller graph for this function:

◆ boundary_decel_nocruise_minspeed_accel_complete()

TrajectoryParams lci_strategic_plugin::LCIStrategicPlugin::boundary_decel_nocruise_minspeed_accel_complete ( double  t,
double  v0,
double  v1,
double  v_max,
double  v_min,
double  a_max,
double  a_min,
double  x0,
double  x_end,
double  dx 
)
private

Definition at line 1222 of file lci_strategic_plugin_algo.cpp.

1223{
1224 double nom = (v1 - v_min) + ((a_max / a_min) * (v_min - v0));
1225 double den = (pow(v1, 2) - pow(v_min, 2)) + ((a_max / a_min) * (pow(v_min, 2) - pow(v0, 2)));
1226
1227 if (den <= epsilon_ && den >= -epsilon_)
1228 throw std::invalid_argument("boundary_decel_nocruise_minspeed_accel_complete: Received den near zero..." + std::to_string(den));
1229
1230 double t_end = t + (2 * dx * nom / den);
1231 TrajectoryParams traj;
1232
1233 traj.t0_ = t;
1234 traj.v0_ = v0;
1235 traj.x0_ = x0;
1236
1237 double dt = t_end - t;
1238 double tc = 0;
1239
1240 traj.v1_ = v_min;
1241
1242 if (dt - tc <= epsilon_ && dt - tc >= -epsilon_)
1243 throw std::invalid_argument("boundary_decel_nocruise_minspeed_accel_complete: Received dt - tc near zero..." + std::to_string(dt - tc));
1244
1245 traj.a1_ = (((1 - (a_min / a_max)) * v_min) + ((a_min / a_max) * v1) - v0) / (dt - tc);
1246 traj.t1_ = traj.t0_ + ((traj.v1_ - traj.v0_) / traj.a1_);
1247 traj.x1_ = traj.x0_ + ((pow(traj.v1_, 2) - pow(traj.v0_, 2)) / (2 * traj.a1_));
1248
1249 traj.t2_ = t_end;
1250 traj.a2_ = ((((a_max / a_min) - 1) * v_min) + v1 - ((a_max / a_min) * v0)) / (dt - tc);
1251 traj.v2_ = v1;
1252 traj.x2_ = x_end;
1253
1254 traj.t3_ = traj.t2_;
1255 traj.a3_ = 0;
1256 traj.v3_ = traj.v2_;
1257 traj.x3_ = traj.x2_;
1258
1259 return traj;
1260}

References epsilon_, lci_strategic_plugin::TrajectoryParams::t0_, and carma_cooperative_perception::to_string().

Referenced by get_boundary_traj_params().

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

◆ boundary_decel_nocruise_minspeed_accel_incomplete()

TrajectoryParams lci_strategic_plugin::LCIStrategicPlugin::boundary_decel_nocruise_minspeed_accel_incomplete ( double  t,
double  v0,
double  v_min,
double  a_max,
double  a_min,
double  x0,
double  x_end,
double  dx 
)
private

Definition at line 1192 of file lci_strategic_plugin_algo.cpp.

1193{
1194 double sqr = sqrt((2 * a_max * dx) - ((pow(v_min, 2) - pow(v0, 2)) * (a_max / a_min)) + pow(v_min, 2));
1195
1196 double t_end = t + ((sqr - v_min) / a_max) + ((v_min - v0) / a_min);
1197
1198 TrajectoryParams traj;
1199
1200 traj.t0_ = t;
1201 traj.v0_ = v0;
1202 traj.x0_ = x0;
1203
1204 traj.v1_ = v_min;
1205 traj.a1_ = a_min;
1206 traj.t1_ = traj.t0_ + (traj.v1_ - traj.v0_) / a_min;
1207 traj.x1_ = traj.x0_ + (pow(traj.v1_, 2) - pow(traj.v0_, 2)) / (2 * a_min);
1208
1209 traj.t2_ = t_end;
1210 traj.a2_ = a_max;
1211 traj.v2_ = (traj.a2_ * (traj.t2_ - traj.t1_)) + traj.v1_;
1212 traj.x2_ = x_end;
1213
1214 traj.t3_ = traj.t2_;
1215 traj.a3_ = 0;
1216 traj.v3_ = traj.v2_;
1217 traj.x3_ = traj.x2_;
1218
1219 return traj;
1220}

References lci_strategic_plugin::TrajectoryParams::a1_, lci_strategic_plugin::TrajectoryParams::a2_, lci_strategic_plugin::TrajectoryParams::a3_, lci_strategic_plugin::TrajectoryParams::t0_, lci_strategic_plugin::TrajectoryParams::t1_, lci_strategic_plugin::TrajectoryParams::t2_, lci_strategic_plugin::TrajectoryParams::t3_, lci_strategic_plugin::TrajectoryParams::v0_, lci_strategic_plugin::TrajectoryParams::v1_, lci_strategic_plugin::TrajectoryParams::v2_, lci_strategic_plugin::TrajectoryParams::v3_, lci_strategic_plugin::TrajectoryParams::x0_, lci_strategic_plugin::TrajectoryParams::x1_, lci_strategic_plugin::TrajectoryParams::x2_, and lci_strategic_plugin::TrajectoryParams::x3_.

Referenced by get_boundary_traj_params().

Here is the caller graph for this function:

◆ boundary_decel_nocruise_notminspeed_accel()

TrajectoryParams lci_strategic_plugin::LCIStrategicPlugin::boundary_decel_nocruise_notminspeed_accel ( double  t,
double  v0,
double  v1,
double  v_min,
double  a_max,
double  a_min,
double  x0,
double  x_end,
double  dx 
)
private

Definition at line 1163 of file lci_strategic_plugin_algo.cpp.

1164{
1165 double v_hat = sqrt(((2 * dx * a_max * a_min) + (a_max * pow(v0, 2)) - (a_min * pow(v1, 2))) / (a_max - a_min));
1166 double t_end = t + ((v_hat * (a_max - a_min)) - (v0 * a_max) + (v1 * a_min)) / (a_max * a_min);
1167
1168 TrajectoryParams traj;
1169
1170 traj.t0_ = t;
1171 traj.v0_ = v0;
1172 traj.x0_ = x0;
1173
1174 traj.v1_ = v_hat;
1175 traj.a1_ = a_min;
1176 traj.t1_ = traj.t0_ + ((traj.v1_ - traj.v0_) / traj.a1_);
1177 traj.x1_ = traj.x0_ + ((pow(traj.v1_, 2) - pow(traj.v0_, 2)) / (2 * traj.a1_));
1178
1179 traj.t2_ = t_end;
1180 traj.a2_ = a_max;
1181 traj.v2_ = v1;
1182 traj.x2_ = x_end;
1183
1184 traj.t3_ = traj.t2_;
1185 traj.a3_ = 0;
1186 traj.v3_ = traj.v2_;
1187 traj.x3_ = traj.x2_;
1188
1189 return traj;
1190}

References lci_strategic_plugin::TrajectoryParams::a1_, lci_strategic_plugin::TrajectoryParams::a2_, lci_strategic_plugin::TrajectoryParams::a3_, lci_strategic_plugin::TrajectoryParams::t0_, lci_strategic_plugin::TrajectoryParams::t1_, lci_strategic_plugin::TrajectoryParams::t2_, lci_strategic_plugin::TrajectoryParams::t3_, lci_strategic_plugin::TrajectoryParams::v0_, lci_strategic_plugin::TrajectoryParams::v1_, lci_strategic_plugin::TrajectoryParams::v2_, lci_strategic_plugin::TrajectoryParams::v3_, lci_strategic_plugin::TrajectoryParams::x0_, lci_strategic_plugin::TrajectoryParams::x1_, lci_strategic_plugin::TrajectoryParams::x2_, and lci_strategic_plugin::TrajectoryParams::x3_.

Referenced by get_boundary_traj_params().

Here is the caller graph for this function:

◆ BSMCb()

void lci_strategic_plugin::LCIStrategicPlugin::BSMCb ( carma_v2x_msgs::msg::BSM::UniquePtr  msg)

BSM callback function.

Definition at line 1170 of file lci_strategic_plugin.cpp.

1171{
1172 std::vector<uint8_t> bsm_id_vec = msg->core_data.id;
1173 bsm_id_ = BSMHelper::BSMHelper::bsmIDtoString(bsm_id_vec);
1174 bsm_msg_count_ = msg->core_data.msg_count;
1175 bsm_sec_mark_ = msg->core_data.sec_mark;
1176}

References bsm_id_, bsm_msg_count_, and bsm_sec_mark_.

Referenced by on_configure_plugin().

Here is the caller graph for this function:

◆ calc_estimated_entry_time_left()

double lci_strategic_plugin::LCIStrategicPlugin::calc_estimated_entry_time_left ( double  entry_dist,
double  current_speed,
double  departure_speed 
) const
private

calculate the time vehicle will enter to intersection with optimal deceleration

Parameters
entry_distdistance to stop line
current_speedcurrent speed of vehicle
departure_speedspeed to get into the intersection
Returns
the time vehicle will stop with optimal decelarion

Definition at line 442 of file lci_strategic_plugin_algo.cpp.

443{
444 double t_entry = 0;
445 // t = 2 * d / (v_i + v_f)
446 // from TSMO USE CASE 2 Algorithm Doc - Figure 4. Equation: Estimation of t*_nt
447 t_entry = 2*entry_dist/(current_speed + departure_speed);
448 return t_entry;
449}

◆ canArriveAtGreenWithCertainty()

boost::optional< bool > lci_strategic_plugin::LCIStrategicPlugin::canArriveAtGreenWithCertainty ( const rclcpp::Time &  light_arrival_time_by_algo,
const lanelet::CarmaTrafficSignalPtr &  traffic_light,
bool  check_late = true,
bool  check_early = true 
) const
private

Return true if the car can arrive at given arrival time within green light time buffer.

Parameters
light_arrival_time_by_algoROS time at green where vehicle arrives
traffic_lightTraffic signal to check time against
check_latecheck late arrival, default true
check_earlycheck early arrival, default true
Returns
true (bool optional) if can make it at both bounds of error time.

NOTE: internally uses config_.green_light_time_buffer NOTE: boost::none optional if any of the light state was invalid

Definition at line 298 of file lci_strategic_plugin.cpp.

299{
300 rclcpp::Time early_arrival_time_by_algo =
301 light_arrival_time_by_algo - rclcpp::Duration(config_.green_light_time_buffer * 1e9);
302
303 rclcpp::Time late_arrival_time_by_algo =
304 light_arrival_time_by_algo + rclcpp::Duration(config_.green_light_time_buffer * 1e9);
305
306 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "light_arrival_time_by_algo: " << std::to_string(light_arrival_time_by_algo.seconds()));
307 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "early_arrival_time_by_algo: " << std::to_string(early_arrival_time_by_algo.seconds()));
308 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "late_arrival_time_by_algo: " << std::to_string(late_arrival_time_by_algo.seconds()));
309
310 auto early_arrival_state_by_algo_optional = traffic_light->predictState(lanelet::time::timeFromSec(early_arrival_time_by_algo.seconds()));
311
312 if (!validLightState(early_arrival_state_by_algo_optional, early_arrival_time_by_algo))
313 return boost::none;
314
315 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "early_arrival_state_by_algo: " << early_arrival_state_by_algo_optional.get().second);
316
317 auto late_arrival_state_by_algo_optional = traffic_light->predictState(lanelet::time::timeFromSec(late_arrival_time_by_algo.seconds()));
318
319 if (!validLightState(late_arrival_state_by_algo_optional, late_arrival_time_by_algo))
320 return boost::none;
321
322 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "late_arrival_state_by_algo: " << late_arrival_state_by_algo_optional.get().second);
323
324 bool can_make_early_arrival = true;
325 bool can_make_late_arrival = true;
326
327 if (check_early)
328 can_make_early_arrival = (early_arrival_state_by_algo_optional.get().second == lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED);
329
330 if (check_late)
331 can_make_late_arrival = (late_arrival_state_by_algo_optional.get().second == lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED);
332
333 // We will cross the light on the green phase even if we arrive early or late
334 if (can_make_early_arrival && can_make_late_arrival) // Green light
335 return true;
336 else
337 return false;
338
339}
bool validLightState(const boost::optional< std::pair< boost::posix_time::ptime, lanelet::CarmaTrafficSignalState > > &optional_state, const rclcpp::Time &source_time) const
Helper method that checks both if the input optional light state is set and if the state it contains ...

References config_, lci_strategic_plugin::LCIStrategicPluginConfig::green_light_time_buffer, carma_cooperative_perception::to_string(), and validLightState().

Referenced by handleGreenSignalScenario(), and planWhenWAITING().

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

◆ composeIntersectionTransitMessage()

carma_planning_msgs::msg::Maneuver lci_strategic_plugin::LCIStrategicPlugin::composeIntersectionTransitMessage ( double  start_dist,
double  end_dist,
double  start_speed,
double  target_speed,
rclcpp::Time  start_time,
rclcpp::Time  end_time,
const lanelet::Id &  starting_lane_id,
const lanelet::Id &  ending_lane_id 
) const
private

Compose a intersection transit maneuver message based on input params.

Parameters
start_distStart downtrack distance of the current maneuver
end_distEnd downtrack distance of the current maneuver
start_speedStart speed of the current maneuver
target_speedTarget speed pf the current maneuver, usually it is the lanelet speed limit
start_timeThe starting time of the maneuver
end_timeThe ending time of the maneuver
starting_lane_idThe starting lanelet id of this maneuver
ending_lane_idThe ending lanelet id of this maneuver
Returns
A intersection transit maneuver maneuver message which is ready to be published

Definition at line 1505 of file lci_strategic_plugin.cpp.

1510{
1511 carma_planning_msgs::msg::Maneuver maneuver_msg;
1512 maneuver_msg.type = carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_STRAIGHT;
1513 maneuver_msg.intersection_transit_straight_maneuver.parameters.negotiation_type =
1514 carma_planning_msgs::msg::ManeuverParameters::NO_NEGOTIATION;
1515 maneuver_msg.intersection_transit_straight_maneuver.parameters.presence_vector =
1516 carma_planning_msgs::msg::ManeuverParameters::HAS_TACTICAL_PLUGIN;
1517 maneuver_msg.intersection_transit_straight_maneuver.parameters.planning_tactical_plugin =
1519 maneuver_msg.intersection_transit_straight_maneuver.parameters.planning_strategic_plugin =
1521 maneuver_msg.intersection_transit_straight_maneuver.start_dist = start_dist;
1522 maneuver_msg.intersection_transit_straight_maneuver.start_speed = start_speed;
1523 maneuver_msg.intersection_transit_straight_maneuver.start_time = start_time;
1524 maneuver_msg.intersection_transit_straight_maneuver.end_dist = end_dist;
1525 maneuver_msg.intersection_transit_straight_maneuver.end_speed = target_speed;
1526 maneuver_msg.intersection_transit_straight_maneuver.end_time = end_time;
1527 maneuver_msg.intersection_transit_straight_maneuver.starting_lane_id = std::to_string(starting_lane_id);
1528 maneuver_msg.intersection_transit_straight_maneuver.ending_lane_id = std::to_string(ending_lane_id);
1529
1530 // Start time and end time for maneuver are assigned in updateTimeProgress
1531
1532 RCLCPP_INFO_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Creating IntersectionTransitManeuver start dist: " << start_dist << " end dist: " << end_dist
1533 << " From lanelet: " << starting_lane_id
1534 << " to lanelet: " << ending_lane_id
1535 << " From start_time: " << std::to_string(start_time.seconds())
1536 << " to end_time: " << std::to_string(end_time.seconds()));
1537
1538 return maneuver_msg;
1539}

References config_, lci_strategic_plugin::LCIStrategicPluginConfig::intersection_transit_plugin_name, lci_strategic_plugin::LCIStrategicPluginConfig::strategic_plugin_name, and carma_cooperative_perception::to_string().

Referenced by handleFailureCase(), handleGreenSignalScenario(), and planWhenDEPARTING().

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

◆ composeStopAndWaitManeuverMessage()

carma_planning_msgs::msg::Maneuver lci_strategic_plugin::LCIStrategicPlugin::composeStopAndWaitManeuverMessage ( double  current_dist,
double  end_dist,
double  start_speed,
const lanelet::Id &  starting_lane_id,
const lanelet::Id &  ending_lane_id,
rclcpp::Time  start_time,
rclcpp::Time  end_time,
double  stopping_accel 
) const
private

Compose a stop and wait maneuver message based on input params.

Parameters
current_distStart downtrack distance of the current maneuver
end_distEnd downtrack distance of the current maneuver
start_speedStart speed of the current maneuver
starting_lane_idThe starting lanelet id of this maneuver
ending_lane_idThe ending lanelet id of this maneuver
start_timeThe starting time of the maneuver
end_timeThe ending time of the maneuver
stopping_accelAcceleration used for calculating the stopping distance
Returns
A stop and wait maneuver message which is ready to be published

Definition at line 1472 of file lci_strategic_plugin.cpp.

1477{
1478 carma_planning_msgs::msg::Maneuver maneuver_msg;
1479 maneuver_msg.type = carma_planning_msgs::msg::Maneuver::STOP_AND_WAIT;
1480 maneuver_msg.stop_and_wait_maneuver.parameters.negotiation_type = carma_planning_msgs::msg::ManeuverParameters::NO_NEGOTIATION;
1481 maneuver_msg.stop_and_wait_maneuver.parameters.presence_vector =
1482 carma_planning_msgs::msg::ManeuverParameters::HAS_TACTICAL_PLUGIN | carma_planning_msgs::msg::ManeuverParameters::HAS_FLOAT_META_DATA;
1483 maneuver_msg.stop_and_wait_maneuver.parameters.planning_tactical_plugin = config_.stop_and_wait_plugin_name;
1484 maneuver_msg.stop_and_wait_maneuver.parameters.planning_strategic_plugin = config_.strategic_plugin_name;
1485 maneuver_msg.stop_and_wait_maneuver.start_dist = current_dist;
1486 maneuver_msg.stop_and_wait_maneuver.end_dist = end_dist;
1487 maneuver_msg.stop_and_wait_maneuver.start_speed = start_speed;
1488 maneuver_msg.stop_and_wait_maneuver.start_time = start_time;
1489 maneuver_msg.stop_and_wait_maneuver.end_time = end_time;
1490 maneuver_msg.stop_and_wait_maneuver.starting_lane_id = std::to_string(starting_lane_id);
1491 maneuver_msg.stop_and_wait_maneuver.ending_lane_id = std::to_string(ending_lane_id);
1492
1493 // Set the meta data for the stop location buffer
1494 maneuver_msg.stop_and_wait_maneuver.parameters.float_valued_meta_data.push_back(config_.stopping_location_buffer);
1495 maneuver_msg.stop_and_wait_maneuver.parameters.float_valued_meta_data.push_back(stopping_accel);
1496
1497 RCLCPP_INFO_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Creating stop and wait start dist: " << current_dist << " end dist: " << end_dist
1498 << " start_time: " << std::to_string(start_time.seconds())
1499 << " end_time: " << std::to_string(end_time.seconds())
1500 << " stopping_accel: " << stopping_accel);
1501
1502 return maneuver_msg;
1503}

References config_, lci_strategic_plugin::LCIStrategicPluginConfig::stop_and_wait_plugin_name, lci_strategic_plugin::LCIStrategicPluginConfig::stopping_location_buffer, lci_strategic_plugin::LCIStrategicPluginConfig::strategic_plugin_name, and carma_cooperative_perception::to_string().

Referenced by handleCruisingUntilStop(), handleStopping(), and planWhenWAITING().

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

◆ composeTrajectorySmoothingManeuverMessage()

carma_planning_msgs::msg::Maneuver lci_strategic_plugin::LCIStrategicPlugin::composeTrajectorySmoothingManeuverMessage ( double  start_dist,
double  end_dist,
const std::vector< lanelet::ConstLanelet > &  crossed_lanelets,
double  start_speed,
double  target_speed,
rclcpp::Time  start_time,
rclcpp::Time  end_time,
const TrajectoryParams tsp 
) const
private

Compose a trajectory smoothing maneuver msg (sent as transit maneuver message)

Parameters
start_distStart downtrack distance of the current maneuver
end_distEnd downtrack distance of the current maneuver
start_speedStart speed of the current maneuver
target_speedTarget speed pf the current maneuver, usually it is the lanelet speed limit
start_timeThe starting time of the maneuver
end_timeThe ending time of the maneuver
tspTrajectory Smoothing parameters needed to modify speed profile
Returns
A transift maneuver message specifically designed for light controlled intersection tactical plugin

Definition at line 1421 of file lci_strategic_plugin.cpp.

1424{
1425 carma_planning_msgs::msg::Maneuver maneuver_msg;
1426 maneuver_msg.type = carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING;
1427 maneuver_msg.lane_following_maneuver.parameters.negotiation_type =
1428 carma_planning_msgs::msg::ManeuverParameters::NO_NEGOTIATION;
1429 maneuver_msg.lane_following_maneuver.parameters.presence_vector =
1430 carma_planning_msgs::msg::ManeuverParameters::HAS_TACTICAL_PLUGIN | carma_planning_msgs::msg::ManeuverParameters::HAS_FLOAT_META_DATA | carma_planning_msgs::msg::ManeuverParameters::HAS_INT_META_DATA;
1431 maneuver_msg.lane_following_maneuver.parameters.planning_tactical_plugin =
1433 maneuver_msg.lane_following_maneuver.parameters.planning_strategic_plugin =
1435 maneuver_msg.lane_following_maneuver.start_dist = start_dist;
1436 maneuver_msg.lane_following_maneuver.start_speed = start_speed;
1437 maneuver_msg.lane_following_maneuver.start_time = start_time;
1438 maneuver_msg.lane_following_maneuver.end_dist = end_dist;
1439 maneuver_msg.lane_following_maneuver.end_speed = target_speed;
1440 maneuver_msg.lane_following_maneuver.end_time = end_time;
1441
1442 maneuver_msg.lane_following_maneuver.parameters.string_valued_meta_data.push_back(light_controlled_intersection_strategy_);
1443
1444 maneuver_msg.lane_following_maneuver.parameters.float_valued_meta_data.push_back(tsp.a1_);
1445 maneuver_msg.lane_following_maneuver.parameters.float_valued_meta_data.push_back(tsp.v1_);
1446 maneuver_msg.lane_following_maneuver.parameters.float_valued_meta_data.push_back(tsp.x1_);
1447
1448 maneuver_msg.lane_following_maneuver.parameters.float_valued_meta_data.push_back(tsp.a2_);
1449 maneuver_msg.lane_following_maneuver.parameters.float_valued_meta_data.push_back(tsp.v2_);
1450 maneuver_msg.lane_following_maneuver.parameters.float_valued_meta_data.push_back(tsp.x2_);
1451
1452 maneuver_msg.lane_following_maneuver.parameters.float_valued_meta_data.push_back(tsp.a3_);
1453 maneuver_msg.lane_following_maneuver.parameters.float_valued_meta_data.push_back(tsp.v3_);
1454 maneuver_msg.lane_following_maneuver.parameters.float_valued_meta_data.push_back(tsp.x3_);
1455
1456 maneuver_msg.lane_following_maneuver.parameters.int_valued_meta_data.push_back(static_cast<int>(tsp.case_num));
1457 maneuver_msg.lane_following_maneuver.parameters.int_valued_meta_data.push_back(static_cast<int>(tsp.is_algorithm_successful));
1458
1459 for (auto llt : crossed_lanelets)
1460 {
1461 maneuver_msg.lane_following_maneuver.lane_ids.push_back(std::to_string(llt.id()));
1462 }
1463 // Start time and end time for maneuver are assigned in updateTimeProgress
1464
1465 RCLCPP_INFO_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Creating TrajectorySmoothingManeuver start dist: " << start_dist << " end dist: " << end_dist
1466 << " start_time: " << std::to_string(start_time.seconds())
1467 << " end_time: " << std::to_string(end_time.seconds()));
1468
1469 return maneuver_msg;
1470}

References lci_strategic_plugin::TrajectoryParams::a1_, lci_strategic_plugin::TrajectoryParams::a2_, lci_strategic_plugin::TrajectoryParams::a3_, lci_strategic_plugin::TrajectoryParams::case_num, config_, lci_strategic_plugin::TrajectoryParams::is_algorithm_successful, lci_strategic_plugin::LCIStrategicPluginConfig::lane_following_plugin_name, light_controlled_intersection_strategy_, lci_strategic_plugin::LCIStrategicPluginConfig::strategic_plugin_name, carma_cooperative_perception::to_string(), lci_strategic_plugin::TrajectoryParams::v1_, lci_strategic_plugin::TrajectoryParams::v2_, lci_strategic_plugin::TrajectoryParams::v3_, lci_strategic_plugin::TrajectoryParams::x1_, lci_strategic_plugin::TrajectoryParams::x2_, and lci_strategic_plugin::TrajectoryParams::x3_.

Referenced by handleCruisingUntilStop(), handleFailureCase(), and handleGreenSignalScenario().

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

◆ estimate_distance_to_stop()

double lci_strategic_plugin::LCIStrategicPlugin::estimate_distance_to_stop ( double  v,
double  a 
) const
private

Helper method to use basic kinematics to compute an estimated stopping distance from from the inputs.

Parameters
vThe initial velocity in m/s
aThe deceleration in m/s^2
Returns
The estimated stopping distance in meters

Definition at line 24 of file lci_strategic_plugin_algo.cpp.

25{
26 return (v * v) / (2.0 * a);
27}

Referenced by planWhenUNAVAILABLE().

Here is the caller graph for this function:

◆ estimate_time_to_stop()

double lci_strategic_plugin::LCIStrategicPlugin::estimate_time_to_stop ( double  d,
double  v 
) const
private

Helper method to use basic kinematics to compute an estimated stopping time from from the inputs.

Parameters
dThe distance to travel in meters
vThe initial velocity in m/s
Returns
The estimated stopping time in seconds

Definition at line 29 of file lci_strategic_plugin_algo.cpp.

30{
31 return 2.0 * d / v;
32};

◆ extractInitialState()

LCIStrategicPlugin::VehicleState lci_strategic_plugin::LCIStrategicPlugin::extractInitialState ( carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr  req) const
private

Helper method to extract the initial vehicle state from the planning request method based on if the prior_plan was set or not.

Parameters
reqThe maneuver planning request to extract the vehicle state from
Returns
The extracted VehicleState

Definition at line 236 of file lci_strategic_plugin.cpp.

237{
238 VehicleState state;
239 if (!req->prior_plan.maneuvers.empty())
240 {
241 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Provided with initial plan...");
242 state.stamp = GET_MANEUVER_PROPERTY(req->prior_plan.maneuvers.back(), end_time);
243 state.downtrack = GET_MANEUVER_PROPERTY(req->prior_plan.maneuvers.back(), end_dist);
244 state.speed = GET_MANEUVER_PROPERTY(req->prior_plan.maneuvers.back(), end_speed);
245 state.lane_id = getLaneletsBetweenWithException(state.downtrack, state.downtrack, true).front().id();
246 }
247 else
248 {
249 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "No initial plan provided...");
250
251 state.stamp = rclcpp::Time(req->header.stamp, RCL_SYSTEM_TIME);
252 state.downtrack = req->veh_downtrack;
253 state.speed = req->veh_logitudinal_velocity;
254 state.lane_id = stoi(req->veh_lane_id);
255 }
256 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "extractInitialState >>>> state.stamp: " << std::to_string(state.stamp.seconds()));
257 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "extractInitialState >>>> state.downtrack : " << state.downtrack );
258 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "extractInitialState >>>> state.speed: " << state.speed);
259 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "extractInitialState >>>> state.lane_id: " << state.lane_id);
260
261 return state;
262}
std::vector< lanelet::ConstLanelet > getLaneletsBetweenWithException(double start_downtrack, double end_downtrack, bool shortest_path_only=false, bool bounds_inclusive=true) const
Helper method which calls carma_wm::WorldModel::getLaneletsBetween(start_downtrack,...
#define GET_MANEUVER_PROPERTY(mvr, property)

References lci_strategic_plugin::LCIStrategicPlugin::VehicleState::downtrack, GET_MANEUVER_PROPERTY, getLaneletsBetweenWithException(), lci_strategic_plugin::LCIStrategicPlugin::VehicleState::lane_id, lci_strategic_plugin::LCIStrategicPlugin::VehicleState::speed, lci_strategic_plugin::LCIStrategicPlugin::VehicleState::stamp, and carma_cooperative_perception::to_string().

Referenced by plan_maneuvers_callback().

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

◆ findSpeedLimit()

double lci_strategic_plugin::LCIStrategicPlugin::findSpeedLimit ( const lanelet::ConstLanelet &  llt) const
private

Given a Lanelet, find it's associated Speed Limit.

Parameters
lltConstant Lanelet object
Exceptions
std::invalid_argumentif the speed limit could not be retrieved
Returns
value of speed limit in mps

Definition at line 264 of file lci_strategic_plugin.cpp.

265{
266 lanelet::Optional<carma_wm::TrafficRulesConstPtr> traffic_rules = wm_->getTrafficRules();
267 if (traffic_rules)
268 {
269 return (*traffic_rules)->speedLimit(llt).speedLimit.value();
270 }
271 else
272 {
273 throw std::invalid_argument("Valid traffic rules object could not be built");
274 }
275}
carma_wm::WorldModelConstPtr wm_
World Model pointer.

References wm_.

Referenced by planWhenAPPROACHING(), and planWhenUNAVAILABLE().

Here is the caller graph for this function:

◆ FRIEND_TEST() [1/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicPluginTest  ,
moboperationcbtest   
)
private

◆ FRIEND_TEST() [2/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicPluginTest  ,
parseStrategyParamstest   
)
private

◆ FRIEND_TEST() [3/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicTestFixture  ,
calc_estimated_entry_time_left   
)
private

◆ FRIEND_TEST() [4/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicTestFixture  ,
composeIntersectionTransitMessage   
)
private

◆ FRIEND_TEST() [5/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicTestFixture  ,
composeStopAndWaitManeuverMessage   
)
private

◆ FRIEND_TEST() [6/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicTestFixture  ,
composeTrajectorySmoothingManeuverMessage   
)
private

◆ FRIEND_TEST() [7/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicTestFixture  ,
DISABLED_extractInitialState   
)
private

◆ FRIEND_TEST() [8/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicTestFixture  ,
DISABLED_planManeuverCb   
)
private

◆ FRIEND_TEST() [9/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicTestFixture  ,
DISABLED_planWhenETInTBD   
)
private

◆ FRIEND_TEST() [10/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicTestFixture  ,
estimate_distance_to_stop   
)
private

◆ FRIEND_TEST() [11/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicTestFixture  ,
estimate_time_to_stop   
)
private

◆ FRIEND_TEST() [12/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicTestFixture  ,
extractInitialState   
)
private

◆ FRIEND_TEST() [13/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicTestFixture  ,
findSpeedLimit   
)
private

◆ FRIEND_TEST() [14/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicTestFixture  ,
get_distance_to_accel_or_decel_once   
)
private

◆ FRIEND_TEST() [15/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicTestFixture  ,
get_distance_to_accel_or_decel_twice   
)
private

◆ FRIEND_TEST() [16/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicTestFixture  ,
get_earliest_entry_time   
)
private

◆ FRIEND_TEST() [17/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicTestFixture  ,
get_eet_or_tbd   
)
private

◆ FRIEND_TEST() [18/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicTestFixture  ,
get_nearest_green_entry_time   
)
private

◆ FRIEND_TEST() [19/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicTestFixture  ,
getDiscoveryMsg   
)
private

◆ FRIEND_TEST() [20/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicTestFixture  ,
getLaneletsBetweenWithException   
)
private

◆ FRIEND_TEST() [21/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicTestFixture  ,
handleFailureCase   
)
private

◆ FRIEND_TEST() [22/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicTestFixture  ,
handleFailureCaseHelper   
)
private

◆ FRIEND_TEST() [23/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicTestFixture  ,
handleStopping   
)
private

◆ FRIEND_TEST() [24/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicTestFixture  ,
planManeuverCb   
)
private

◆ FRIEND_TEST() [25/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicTestFixture  ,
planWhenETInTBD   
)
private

◆ FRIEND_TEST() [26/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicTestFixture  ,
supportedLightState   
)
private

◆ FRIEND_TEST() [27/27]

lci_strategic_plugin::LCIStrategicPlugin::FRIEND_TEST ( LCIStrategicTestFixture  ,
validLightState   
)
private

◆ generateMobilityOperation()

carma_v2x_msgs::msg::MobilityOperation lci_strategic_plugin::LCIStrategicPlugin::generateMobilityOperation ( )

Generates Mobility Operation messages.

Returns
mobility operation msg for status and intent

Definition at line 1197 of file lci_strategic_plugin.cpp.

1198{
1199 carma_v2x_msgs::msg::MobilityOperation mo_;
1200 mo_.m_header.timestamp = now().nanoseconds()/1000000;
1201 mo_.m_header.sender_id = config_.vehicle_id;
1202 mo_.m_header.recipient_id = upcoming_id_;
1203 mo_.m_header.sender_bsm_id = bsm_id_;
1205
1206 double vehicle_acceleration_limit_ = config_.vehicle_accel_limit * config_.vehicle_accel_limit_multiplier;
1207 double vehicle_deceleration_limit_ = -1 * config_.vehicle_decel_limit * config_.vehicle_decel_limit_multiplier;
1208
1209 std::string intersection_turn_direction = "straight";
1210 if (intersection_turn_direction_ == TurnDirection::Right) intersection_turn_direction = "right";
1211 if (intersection_turn_direction_ == TurnDirection::Left) intersection_turn_direction = "left";
1212
1213 mo_.strategy_params = "access: 1, max_accel: " + std::to_string(vehicle_acceleration_limit_) + // NOTE: Access currently set to 1 at all times since its not specified by streets
1214 ", max_decel: " + std::to_string(vehicle_deceleration_limit_) + ", react_time: " + std::to_string(config_.reaction_time) +
1215 ", min_gap: " + std::to_string(config_.min_gap) + ", depart_pos: 0" + // NOTE: Departure position set to 0 at all times since it's not specified by streets
1216 ", turn_direction: " + intersection_turn_direction + ", msg_count: " + std::to_string(bsm_msg_count_) + ", sec_mark: " + std::to_string(bsm_sec_mark_);
1217
1218
1219 return mo_;
1220}
double reaction_time
Double: Vehicle reaction time to a received schedule in seconds (approximate value,...
double min_gap
Double: Minimum inter-vehicle gap.

References bsm_id_, bsm_msg_count_, bsm_sec_mark_, config_, intersection_turn_direction_, lci_strategic_plugin::Left, light_controlled_intersection_strategy_, lci_strategic_plugin::LCIStrategicPluginConfig::min_gap, lci_strategic_plugin::LCIStrategicPluginConfig::reaction_time, lci_strategic_plugin::Right, carma_cooperative_perception::to_string(), upcoming_id_, lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_accel_limit, lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_accel_limit_multiplier, lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_decel_limit, lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_decel_limit_multiplier, and lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_id.

Referenced by publishMobilityOperation().

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

◆ get_availability()

bool lci_strategic_plugin::LCIStrategicPlugin::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 1541 of file lci_strategic_plugin.cpp.

1542{
1543 return true;
1544}

◆ get_boundary_traj_params()

std::vector< TrajectoryParams > lci_strategic_plugin::LCIStrategicPlugin::get_boundary_traj_params ( double  t,
double  v0,
double  v1,
double  v_max,
double  v_min,
double  a_max,
double  a_min,
double  x0,
double  x_end,
double  dx,
BoundaryDistances  boundary_distances 
)
private

Get all possible trajectory smoothing parameters for each segments. Later this will be used to generate a single trajectory.

Parameters
tcurrent time in seconds
v0starting_speed
v1departure_speed
v_maxspeed_limit
v_minminimum speed
a_maxmax_comfort_acceleration limit
a_minmax_comfort_deceleration limit
x0current_downtrack
x_endtraffic_light_down_track
dxdistance_remaining_to_traffic_light
boundary_distancesboundary_distances to compare against current state
Returns
all possible trajectory smoothing parameters to later generate single trajectory

Definition at line 504 of file lci_strategic_plugin_algo.cpp.

505{
506 double dx1 = boundary_distances.dx1;
507 double dx2 = boundary_distances.dx2;
508 double dx3 = boundary_distances.dx3;
509 double dx4 = boundary_distances.dx4;
510 double dx5 = boundary_distances.dx5;
511 TrajectoryParams traj1, traj2, traj3, traj4, traj5, traj6, traj7, traj8;
512
513 // t1, t2, t3
514 if (dx < dx2)
515 {
516 traj1 = boundary_accel_or_decel_incomplete_upper(t, v0, v1, a_max, a_min, x0, x_end, dx);
517 traj2 = traj1;
518 traj3 = traj1;
519 }
520 else if (dx < dx1)
521 {
522 traj1 = boundary_accel_nocruise_notmaxspeed_decel(t, v0, v1, a_max, a_min, x0, x_end, dx);
523 traj2 = traj1;
524 traj3 = boundary_accel_or_decel_complete_upper(t, v0, v1, x0, x_end, dx);
525 }
526 else
527 {
528 traj1 = boundary_accel_cruise_maxspeed_decel(t, v0, v1, v_max, a_max, a_min, x0, x_end, dx);
529 traj2 = boundary_accel_nocruise_maxspeed_decel(t, v0, v1, v_max, a_max, a_min, x0, x_end, dx);
530 traj3 = boundary_accel_or_decel_complete_upper(t, v0, v1, x0, x_end, dx);
531 }
532 // t4, t5, t6, t7
533 if (dx < dx4)
534 {
535 traj4 = traj1;
536 traj5 = traj1;
537 traj6 = boundary_decel_incomplete_lower(t, v0, a_min, x0, x_end, dx);
538 traj7 = traj6;
539 }
540 else if (dx < dx3)
541 {
542 if (dx < dx2)
543 {
544 traj4 = traj1;
545 }
546 else
547 {
548 traj4 = boundary_decel_nocruise_notminspeed_accel(t, v0, v1, v_min, a_max, a_min, x0, x_end, dx);
549 }
550 traj5 = traj4;
551 traj6 = boundary_decel_nocruise_minspeed_accel_incomplete(t, v0, v_min, a_max, a_min, x0, x_end, dx);
552 traj7 = boundary_decel_cruise_minspeed(t, v0, v_min, a_min, x0, x_end, dx);
553
554 }
555 else
556 {
557 traj4 = boundary_decel_nocruise_minspeed_accel_complete(t, v0, v1, v_max, v_min, a_max, a_min, x0, x_end, dx);
558 traj5 = boundary_decel_cruise_minspeed_accel(t, v0, v1, v_min, a_max, a_min, x0, x_end, dx);
559 traj6 = traj5;
560 traj7 = boundary_decel_cruise_minspeed(t, v0, v_min, a_min, x0, x_end, dx);
561 }
562 // t8
563 if (dx < dx4)
564 {
565 traj8 = traj6;
566 }
567 else if (dx < dx5)
568 {
569 traj8 = boundary_decel_incomplete_lower(t, v0, a_min, x0, x_end, dx);
570 }
571 else
572 {
573 traj8 = boundary_decel_cruise_minspeed_decel(t, v0, v_min, a_min, x0, x_end, dx);
574 }
575
576 return {traj1, traj2, traj3, traj4, traj5, traj6, traj7, traj8};
577}
TrajectoryParams boundary_decel_nocruise_notminspeed_accel(double t, double v0, double v1, double v_min, double a_max, double a_min, double x0, double x_end, double dx)
TrajectoryParams boundary_decel_cruise_minspeed_decel(double t, double v0, double v_min, double a_min, double x0, double x_end, double dx)
TrajectoryParams boundary_accel_nocruise_maxspeed_decel(double t, double v0, double v1, double v_max, double a_max, double a_min, double x0, double x_end, double dx)
TrajectoryParams boundary_accel_or_decel_complete_upper(double t, double v0, double v1, double x0, double x_end, double dx)
TrajectoryParams boundary_accel_or_decel_incomplete_upper(double t, double v0, double v1, double a_max, double a_min, double x0, double x_end, double dx)
TrajectoryParams boundary_accel_nocruise_notmaxspeed_decel(double t, double v0, double v1, double a_max, double a_min, double x0, double x_end, double dx)
TrajectoryParams boundary_decel_nocruise_minspeed_accel_incomplete(double t, double v0, double v_min, double a_max, double a_min, double x0, double x_end, double dx)
TrajectoryParams boundary_accel_cruise_maxspeed_decel(double t, double v0, double v1, double v_max, double a_max, double a_min, double x0, double x_end, double dx)
TrajectoryParams boundary_decel_incomplete_lower(double t, double v0, double a_min, double x0, double x_end, double dx)
TrajectoryParams boundary_decel_cruise_minspeed_accel(double t, double v0, double v1, double v_min, double a_max, double a_min, double x0, double x_end, double dx)
TrajectoryParams boundary_decel_nocruise_minspeed_accel_complete(double t, double v0, double v1, double v_max, double v_min, double a_max, double a_min, double x0, double x_end, double dx)
TrajectoryParams boundary_decel_cruise_minspeed(double t, double v0, double v_min, double a_min, double x0, double x_end, double dx)

References boundary_accel_cruise_maxspeed_decel(), boundary_accel_nocruise_maxspeed_decel(), boundary_accel_nocruise_notmaxspeed_decel(), boundary_accel_or_decel_complete_upper(), boundary_accel_or_decel_incomplete_upper(), boundary_decel_cruise_minspeed(), boundary_decel_cruise_minspeed_accel(), boundary_decel_cruise_minspeed_decel(), boundary_decel_incomplete_lower(), boundary_decel_nocruise_minspeed_accel_complete(), boundary_decel_nocruise_minspeed_accel_incomplete(), boundary_decel_nocruise_notminspeed_accel(), lci_strategic_plugin::BoundaryDistances::dx1, lci_strategic_plugin::BoundaryDistances::dx2, lci_strategic_plugin::BoundaryDistances::dx3, lci_strategic_plugin::BoundaryDistances::dx4, and lci_strategic_plugin::BoundaryDistances::dx5.

Referenced by planWhenAPPROACHING().

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

◆ get_delta_x()

BoundaryDistances lci_strategic_plugin::LCIStrategicPlugin::get_delta_x ( double  v0,
double  v1,
double  v_max,
double  v_min,
double  a_max,
double  a_min 
)
private

Get boundary distances used to compare against current state in order to create trajectory smoothing parameters.

Parameters
v0starting_speed
v1departure_speed
v_maxspeed_limit
v_minminimum speed
a_maxmax_comfort_acceleration limit
a_minmax_comfort_deceleration limit
Returns
boundary distances used to generate trajectory smoothing segments

Definition at line 452 of file lci_strategic_plugin_algo.cpp.

453{
454 BoundaryDistances distances;
455
456 distances.dx1 = ((pow(v_max, 2) - pow(v0, 2)) / (2 * a_max)) + ((pow(v1, 2) - pow(v_max, 2)) / (2 * a_min));
457 if (v1 > v0)
458 distances.dx2 = ((pow(v1, 2) - pow(v0, 2)) / (2 * a_max));
459 else
460 distances.dx2 = ((pow(v1, 2) - pow(v0, 2)) / (2 * a_min));
461
462 distances.dx3 = ((pow(v_min, 2) - pow(v0, 2)) / (2 * a_min)) + ((pow(v1, 2) - pow(v_min, 2)) / (2 * a_max));
463 distances.dx4 = ((pow(v_min, 2) - pow(v0, 2)) / (2 * a_min));
464 distances.dx5 = - pow(v0, 2) / (2 * a_min);
465
466 return distances;
467}

References lci_strategic_plugin::BoundaryDistances::dx1, lci_strategic_plugin::BoundaryDistances::dx2, lci_strategic_plugin::BoundaryDistances::dx3, lci_strategic_plugin::BoundaryDistances::dx4, and lci_strategic_plugin::BoundaryDistances::dx5.

Referenced by planWhenAPPROACHING().

Here is the caller graph for this function:

◆ get_distance_to_accel_or_decel_once()

double lci_strategic_plugin::LCIStrategicPlugin::get_distance_to_accel_or_decel_once ( double  current_speed,
double  departure_speed,
double  max_accel,
double  max_decel 
) const
private

Get required distance to accel or decel to reach departure_speed with given speed and acceleration parameters.

Parameters
current_speedCurrent speed in m/s
departure_speedSpeed to enter into the intersection in m/s
max_accelAcceleration rate during acceleration segment in m/s^2
max_decelDeceleration rate during acceleration segment in m/s^2
Returns
estimated distance to accel or decel in meters

Definition at line 40 of file lci_strategic_plugin_algo.cpp.

41{
42 if (current_speed <= departure_speed + epsilon_)
43 {
44 return (std::pow(departure_speed, 2) - std::pow(current_speed, 2))/(2 * max_accel);
45 }
46 else
47 {
48 return (std::pow(departure_speed, 2) - std::pow(current_speed, 2))/(2 * max_decel);
49 }
50}

References epsilon_.

Referenced by get_earliest_entry_time().

Here is the caller graph for this function:

◆ get_distance_to_accel_or_decel_twice()

double lci_strategic_plugin::LCIStrategicPlugin::get_distance_to_accel_or_decel_twice ( double  free_flow_speed,
double  current_speed,
double  departure_speed,
double  max_accel,
double  max_decel 
) const
private

Get required distance to accel then decel, or vise versa - each at least once - to reach departure_speed with given speed and acceleration parameters.

Parameters
free_flow_speedFree flow speed in m/s (usually the speed limit)
current_speedCurrent speed in m/s
departure_speedSpeed to enter into the intersection in m/s
max_accelAcceleration rate during acceleration segment in m/s^2
max_decelDeceleration rate during acceleration segment in m/s^2
Returns
estimated distance to accel/decel or vice versa exactly twice in meters

Definition at line 34 of file lci_strategic_plugin_algo.cpp.

35{
36 // (v_e^2 - v^2)/ 2a_a + (v_d^2 - v_e^2)/ 2a_d
37 return (std::pow(free_flow_speed, 2) - std::pow(current_speed, 2))/(2 * max_accel) + (std::pow(departure_speed, 2) - std::pow(free_flow_speed, 2))/(2* max_decel);
38}

Referenced by get_earliest_entry_time().

Here is the caller graph for this function:

◆ get_earliest_entry_time()

rclcpp::Duration lci_strategic_plugin::LCIStrategicPlugin::get_earliest_entry_time ( double  remaining_distance,
double  free_flow_speed,
double  current_speed,
double  departure_speed,
double  max_accel,
double  max_decel 
) const
private

Gets the earliest entry time into the intersection that is kinematically possible for the vehicle. Designed to get it for motion that has maximum one acceleration, deceleration, or cruise segments until destination.

Parameters
remaining_distanceDistance to the intersection in meters
free_flow_speedFree flow speed along the route until the intersection (usually speed_limit) in m/s
current_speedCurrent speed in m/s
departure_speedSpeed into the intersection in m/s. A.k.a target speed at the intersection
max_accelThe acceleration in m/s^2 of the acceleration segment
max_decelThe deceleration in m/s^2 of the deceleration segment
Returns
The estimated stopping distance in meters NOTE: TSMO UC2: Algorithm 1. Earliest entering time estimation algorithm for EVs in all cooperation classes (defined for C-ADS-equipped vehicles)

Definition at line 192 of file lci_strategic_plugin_algo.cpp.

193{
194 double x = remaining_distance;
195 double x2 = get_distance_to_accel_or_decel_once(current_speed, departure_speed, max_accel, max_decel);
196 double x1 = get_distance_to_accel_or_decel_twice(free_flow_speed, current_speed, departure_speed, max_accel, max_decel);
197 double v_hat = get_inflection_speed_value(x, x1, x2, free_flow_speed, current_speed, departure_speed, max_accel, max_decel);
198
199 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "x: " << x << ", x2: " << x2 << ", x1: " << x1 << ", v_hat: " << v_hat);
200
201 if (v_hat <= config_.algo_minimum_speed - epsilon_ || isnan(v_hat))
202 {
203 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Detected that v_hat is smaller than allowed!!!: " << v_hat);
205 }
206
207 if (v_hat >= free_flow_speed + epsilon_)
208 {
209 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Detected that v_hat is Bigger than allowed!!!: " << v_hat);
210 v_hat = free_flow_speed;
211 }
212
213 rclcpp::Duration t_accel(0,0);
214 if ( x < x2 && current_speed > departure_speed)
215 {
216 t_accel = rclcpp::Duration(0.0);
217 }
218 else
219 {
220 t_accel = rclcpp::Duration(std::max((v_hat - current_speed) / max_accel, 0.0) * 1e9);
221 }
222 rclcpp::Duration t_decel(0,0);
223 if ( x < x2 && current_speed < departure_speed)
224 {
225 t_decel = rclcpp::Duration(0.0);
226 }
227 else
228 {
229 if (x < x2)
230 {
231 t_decel = rclcpp::Duration(std::max((v_hat - current_speed) / max_decel, 0.0) * 1e9);
232
233 }
234 else
235 {
236 t_decel = rclcpp::Duration(std::max((departure_speed - v_hat) / max_decel, 0.0) * 1e9);
237 }
238 }
239
240 rclcpp::Duration t_cruise(0,0);
241 if (x1 <= x)
242 {
243 t_cruise = rclcpp::Duration(std::max((x - x1)/v_hat, 0.0) * 1e9);
244 }
245 else
246 {
247 t_cruise = rclcpp::Duration(0.0);
248 }
249 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "t_accel: " << t_accel.seconds() << ", t_cruise: " << t_cruise.seconds() << ", t_decel: " << t_decel.seconds());
250 return t_accel + t_cruise + t_decel;
251
252}
double get_distance_to_accel_or_decel_twice(double free_flow_speed, double current_speed, double departure_speed, double max_accel, double max_decel) const
Get required distance to accel then decel, or vise versa - each at least once - to reach departure_sp...
double get_distance_to_accel_or_decel_once(double current_speed, double departure_speed, double max_accel, double max_decel) const
Get required distance to accel or decel to reach departure_speed with given speed and acceleration pa...
double get_inflection_speed_value(double x, double x1, double x2, double free_flow_speed, double current_speed, double departure_speed, double max_accel, double max_decel) const
Get the speed between the acceleration and deceleration pieces.

References lci_strategic_plugin::LCIStrategicPluginConfig::algo_minimum_speed, config_, epsilon_, get_distance_to_accel_or_decel_once(), get_distance_to_accel_or_decel_twice(), get_inflection_speed_value(), and process_traj_logs::x.

Referenced by planWhenAPPROACHING().

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

◆ get_eet_or_tbd()

rclcpp::Time lci_strategic_plugin::LCIStrategicPlugin::get_eet_or_tbd ( const rclcpp::Time &  earliest_entry_time,
const lanelet::CarmaTrafficSignalPtr &  signal 
) const
private

Returns the later of earliest_entry_time or the end of the available signal states in the traffic_signal.

Parameters
earliest_entry_timeEarliest ROS entry time into the intersection kinematically possible
signalCARMATrafficSignal that is responsible for the intersection along route
Returns
Returns the later of earliest_entry_time or the end of the available signal states in the traffic_signal

Definition at line 52 of file lci_strategic_plugin_algo.cpp.

53{
54 // If no green signal found after earliest entry time
55 auto start_of_tbd_time = rclcpp::Time((lanelet::time::toSec(signal->recorded_time_stamps.back().first) + EPSILON) * 1e9);
56 if (earliest_entry_time > start_of_tbd_time)
57 {
58 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Not enough signals are available to check for EET, so returning EET at: " << std::to_string(earliest_entry_time.seconds()));
59 return earliest_entry_time; //return TBD or EET red if no green is found...
60 }
61
62 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "No valid green entry time found, so returning start of TBD at: " << std::to_string(start_of_tbd_time.seconds()));
63 return start_of_tbd_time;
64}
#define EPSILON

References EPSILON, and carma_cooperative_perception::to_string().

Referenced by get_final_entry_time_and_conditions().

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

◆ get_final_entry_time_and_conditions()

std::tuple< rclcpp::Time, bool, bool > lci_strategic_plugin::LCIStrategicPlugin::get_final_entry_time_and_conditions ( const VehicleState current_state,
const rclcpp::Time &  earliest_entry_time,
lanelet::CarmaTrafficSignalPtr  traffic_light 
)
private

Get the final entry time from either vehicle's own internal ET calculation (TSMO UC2) or from carma-street (TSMO UC3) This function also applies necessary green_buffer to adjust the ET.

Parameters
current_stateCurrent state of the vehicle
earliest_entry_timeEarliest entry time calculated by the vehicle
traffic_lighttraffic signal the vehicle is using
Returns
tuple of <final entry time the vehicle uses to enter the intersection, is_entry_time_within_green_or_tbd: true if ET is in green or TBD (related to UC3, always set to true in UC2), in_tbd: true if ET is in TBD (false if in UC2)>

Definition at line 254 of file lci_strategic_plugin_algo.cpp.

255{
256 rclcpp::Time nearest_green_entry_time = rclcpp::Time(0);
257 bool is_entry_time_within_green_or_tbd = false;
258 bool in_tbd = true;
259
261 {
262 auto nearest_green_entry_time_optional = get_nearest_green_entry_time(current_state.stamp, earliest_entry_time, traffic_light);
263 is_entry_time_within_green_or_tbd = true;
264
265 if (!nearest_green_entry_time_optional)
266 {
267 nearest_green_entry_time = get_eet_or_tbd(earliest_entry_time, traffic_light);
268 }
269 else
270 {
271 in_tbd = false;
272 nearest_green_entry_time = nearest_green_entry_time_optional.value() + rclcpp::Duration(EPSILON * 1e9); //0.01sec more buffer since green_light algorithm's timestamp picks the previous signal - Vehicle Estimation
273 }
274 }
276 {
277 nearest_green_entry_time = rclcpp::Time(std::max(earliest_entry_time.seconds(), (scheduled_enter_time_)/1000.0) * 1e9) + rclcpp::Duration(EPSILON * 1e9); //Carma Street
278
279 // check if scheduled_enter_time_ is inside the available states interval
280 size_t i = 0;
281
282
283 for (auto pair : traffic_light->recorded_time_stamps)
284 {
285 if (lanelet::time::timeFromSec(nearest_green_entry_time.seconds()) < pair.first)
286 {
287 if (pair.second == lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED)
288 {
289 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "ET is inside the GREEN phase! where starting time: " << std::to_string(lanelet::time::toSec(traffic_light->recorded_start_time_stamps[i]))
290 << ", ending time of that green signal is: " << std::to_string(lanelet::time::toSec(pair.first)));
291 is_entry_time_within_green_or_tbd = true;
292 }
293 else
294 {
295 RCLCPP_ERROR_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Vehicle should plan cruise and stop as ET is inside the RED or YELLOW phase! where starting time: " << std::to_string(lanelet::time::toSec(traffic_light->recorded_start_time_stamps[i]))
296 << ", ending time of that green signal is: " << std::to_string(lanelet::time::toSec(pair.first)));
297 is_entry_time_within_green_or_tbd = false;
298 }
299
300 in_tbd = false;
301 break;
302 }
303 i++;
304 }
305
306 if (in_tbd)
307 {
308 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "ET is inside TBD phase! where starting time: " << std::to_string(lanelet::time::toSec(traffic_light->recorded_time_stamps.back().first)));
309 is_entry_time_within_green_or_tbd = true;
310 }
311
312 }
313 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "nearest_green_entry_time: " << nearest_green_entry_time.get_clock_type());
314 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "current_state.stamp: " << current_state.stamp.get_clock_type());
315
316 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "nearest_green_entry_time: " << std::to_string(nearest_green_entry_time.seconds()) << ", with : " << std::to_string((nearest_green_entry_time - current_state.stamp).seconds()) << " seconds left at: " << std::to_string(current_state.stamp.seconds()));
317
319 { // always pick later of buffered green entry time, or earliest entry time
320 nearest_green_entry_time = rclcpp::Time(std::max(nearest_green_entry_time.seconds(), nearest_green_entry_time_cached_.get().seconds()) * 1e9);
321 }
322
323 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "After accounting for cached - nearest_green_entry_time: " << std::to_string(nearest_green_entry_time.seconds()) << ", with : " << std::to_string((nearest_green_entry_time - current_state.stamp).seconds()) << " seconds left at: " << std::to_string(current_state.stamp.seconds()));
324
325 if (!nearest_green_entry_time_cached_ && is_entry_time_within_green_or_tbd)
326 {
327 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Applying green_light_buffer for the first time and caching! nearest_green_entry_time (without buffer):" << std::to_string(nearest_green_entry_time.seconds()) << ", and earliest_entry_time: " << std::to_string(earliest_entry_time.seconds()));
328 // save first calculated nearest_green_entry_time + buffer to compare against in the future as nearest_green_entry_time changes with earliest_entry_time
329
330 // check if it needs buffer below:
331 rclcpp::Time early_arrival_time_green_et =
332 nearest_green_entry_time - rclcpp::Duration(config_.green_light_time_buffer * 1e9);
333
334 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "early_arrival_time_green_et: " << std::to_string(early_arrival_time_green_et.seconds()));
335
336 auto early_arrival_state_green_et_optional = traffic_light->predictState(lanelet::time::timeFromSec(early_arrival_time_green_et.seconds()));
337
338 if (!validLightState(early_arrival_state_green_et_optional, early_arrival_time_green_et))
339 {
340 RCLCPP_ERROR_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Unable to resolve give signal...");
341 return std::make_tuple(rclcpp::Time(0), is_entry_time_within_green_or_tbd, in_tbd);
342 }
343
344 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "early_arrival_state_green_et: " << early_arrival_state_green_et_optional.get().second);
345
346 bool can_make_early_arrival = (early_arrival_state_green_et_optional.get().second == lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED);
347
348 // nearest_green_entry_time is by definition on green, so only check early_arrival
349 if (can_make_early_arrival) // Green light with Certainty
350 {
351 nearest_green_entry_time_cached_ = nearest_green_entry_time; //don't apply buffer if ET is in green
352 }
353 else //buffer is needed
354 {
355 // below logic stores correct buffered timestamp into nearest_green_entry_time_cached_ to be used later
356
357 rclcpp::Time nearest_green_signal_start_time = rclcpp::Time(0);
358 if (traffic_light->fixed_cycle_duration.total_milliseconds()/1000.0 > 1.0) // UC2
359 {
360 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "UC2 Handling");
361 auto normal_arrival_state_green_et_optional = traffic_light->predictState(lanelet::time::timeFromSec(nearest_green_entry_time.seconds()));
362
363 if (!validLightState(normal_arrival_state_green_et_optional, nearest_green_entry_time))
364 {
365 RCLCPP_ERROR_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Unable to resolve give signal...");
366 return std::make_tuple(rclcpp::Time(0), is_entry_time_within_green_or_tbd, in_tbd);
367 }
368
369 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "normal_arrival_signal_end_time: " << std::to_string(lanelet::time::toSec(normal_arrival_state_green_et_optional.get().first)));
370
371 // nearest_green_signal_start_time = normal_arrival_signal_end_time (green guaranteed) - green_signal_duration
372 nearest_green_signal_start_time = rclcpp::Time(lanelet::time::toSec(normal_arrival_state_green_et_optional.get().first - traffic_light->signal_durations[lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED]) * 1e9);
373 }
374 else // UC3
375 {
376 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "UC3 Handling");
377
378 for (size_t i = 0; i < traffic_light->recorded_start_time_stamps.size(); i++)
379 {
380 if (traffic_light->recorded_time_stamps[i].second == lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED &&
381 lanelet::time::timeFromSec(nearest_green_entry_time.seconds()) < traffic_light->recorded_time_stamps[i].first ) // Make sure it is in correct GREEN phase there are multiple
382 {
383 nearest_green_signal_start_time = rclcpp::Time(lanelet::time::toSec(traffic_light->recorded_start_time_stamps[i]) * 1e9);
384 break;
385 }
386 }
387
388 if (nearest_green_signal_start_time == rclcpp::Time(0)) //in tdb
389 {
390 nearest_green_signal_start_time = rclcpp::Time(lanelet::time::toSec(traffic_light->recorded_time_stamps.back().first) * 1e9);
391 }
392 }
393
394 // If ET is within green or TBD, it should always aim for at least minimum of "start_time of green or tdb + green_buffer" for safety
395
396 nearest_green_entry_time_cached_ = nearest_green_signal_start_time + rclcpp::Duration((config_.green_light_time_buffer + EPSILON) * 1e9);
397
398 // EPSILON=0.01 is there because if predictState's input exactly falls on ending_time it picks the previous state.
399 //For example, if 0 - 10s is GREEN, and 10 - 12s is YELLOW, checking exactly 10.0s will return GREEN,
400 //but 10.01s will return YELLOW. This 0.01 convention is used throughout the file, so thought it is better
401 //to keep it consistent and probably too detailed for the user to think about, which is why it is not included in the buffer.
402 //Actually including in the buffer doesn't work because it uses that same buffer to check early and late. If buffer is 2s and
403 //green starts at 10s, it will check +/-2s from 12s. If the buffer was 2.01s and green starts at 10s again, it checks +/-2.01
404 //from 12.01, so both checks 10s.
405
406 }
407
408 nearest_green_entry_time = rclcpp::Time(std::max(nearest_green_entry_time.seconds(), nearest_green_entry_time_cached_.get().seconds()) * 1e9);
409 }
410
411 if (nearest_green_entry_time_cached_ && nearest_green_entry_time > nearest_green_entry_time_cached_.get())
412 {
413 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Earliest entry time... has gone past the cashed entering time. nearest_green_entry_time_cached_ (which can also be TBD):" << std::to_string(nearest_green_entry_time_cached_.get().seconds()) << ", and earliest_entry_time: " << std::to_string(earliest_entry_time.seconds()));
414 }
415 return std::make_tuple(nearest_green_entry_time, is_entry_time_within_green_or_tbd, in_tbd);
416}
rclcpp::Time get_eet_or_tbd(const rclcpp::Time &earliest_entry_time, const lanelet::CarmaTrafficSignalPtr &signal) const
Returns the later of earliest_entry_time or the end of the available signal states in the traffic_sig...
boost::optional< rclcpp::Time > nearest_green_entry_time_cached_
std::optional< rclcpp::Time > get_nearest_green_entry_time(const rclcpp::Time &current_time, const rclcpp::Time &earliest_entry_time, const lanelet::CarmaTrafficSignalPtr &signal, double minimum_required_green_time=0.0) const
Provides the scheduled entry time for the vehicle in the future. This scheduled time is the earliest ...

References config_, lci_strategic_plugin::LCIStrategicPluginConfig::enable_carma_streets_connection, EPSILON, get_eet_or_tbd(), get_nearest_green_entry_time(), lci_strategic_plugin::LCIStrategicPluginConfig::green_light_time_buffer, process_bag::i, nearest_green_entry_time_cached_, scheduled_enter_time_, lci_strategic_plugin::LCIStrategicPlugin::VehicleState::stamp, carma_cooperative_perception::to_string(), and validLightState().

Referenced by planWhenAPPROACHING().

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

◆ get_inflection_speed_value()

double lci_strategic_plugin::LCIStrategicPlugin::get_inflection_speed_value ( double  x,
double  x1,
double  x2,
double  free_flow_speed,
double  current_speed,
double  departure_speed,
double  max_accel,
double  max_decel 
) const
private

Get the speed between the acceleration and deceleration pieces.

Parameters
xDistance remaining in meters
x1Required distance to accel then decel, or vise versa-each at least once-to reach departure_speed with given speed and acceleration parameters
x2required distance to accel or decel to reach departure_speed with given speed and acceleration parameters
free_flow_speedFree flow speed in m/s (usually the speed limit)
current_speedCurrent speed in m/s
departure_speedSpeed to enter into the intersection in m/s
max_accelAcceleration rate during acceleration segment in m/s^2
max_decelDeceleration rate during acceleration segment in m/s^2 NOTE: note that this returns departure speed if x < x2 since vehicle's trajectory corresponding to its EET would contain only one acceleration or deceleration piece
Returns
The estimated stopping distance in meters

Definition at line 418 of file lci_strategic_plugin_algo.cpp.

419{
420 if (x >= x1)
421 {
422 return free_flow_speed;
423 }
424 else if (x1 > x && x >= x2)
425 {
426 return std::sqrt((2 * x * max_accel * max_decel + max_decel * std::pow(current_speed, 2) - max_accel * (std::pow(departure_speed, 2)))/(max_decel - max_accel));
427 }
428 else if (x2 > x)
429 {
430 if (current_speed <= departure_speed)
431 {
432 return std::sqrt(2 * x * max_accel + std::pow(current_speed, 2));
433 }
434 else
435 {
436 return std::sqrt(2 * x * max_decel + std::pow(current_speed, 2));
437 }
438 }
439
440}

References process_traj_logs::x.

Referenced by get_earliest_entry_time().

Here is the caller graph for this function:

◆ get_nearest_green_entry_time()

std::optional< rclcpp::Time > lci_strategic_plugin::LCIStrategicPlugin::get_nearest_green_entry_time ( const rclcpp::Time &  current_time,
const rclcpp::Time &  earliest_entry_time,
const lanelet::CarmaTrafficSignalPtr &  signal,
double  minimum_required_green_time = 0.0 
) const
private

Provides the scheduled entry time for the vehicle in the future. This scheduled time is the earliest possible entry time that is during green phase and after timestamps both that is kinematically possible and required times for vehicle in front to pass through first Returns std::nullopt if no valid green entry time found.

Parameters
current_timeCurrent state's ROS time
earliest_entry_timeEarliest ROS entry time into the intersection kinematically possible
signalCARMATrafficSignal that is responsible for the intersection along route
minimum_required_green_timeMinimum seconds required by other vehicles in front to pass through the intersection first
Returns
Nearest ROS entry time during green phase if it exists, std::nullopt if no valid green entry time found NOTE: TSMO UC2: Algorithm 2. Entering time estimation algorithm for EVs in cooperation Class A when the SPaT plan is fixed-time (defined for C-ADS-equipped vehicles)

Definition at line 66 of file lci_strategic_plugin_algo.cpp.

67{
68 boost::posix_time::time_duration g = lanelet::time::durationFromSec(minimum_required_green_time); // provided by considering min headways of vehicles in front
69 boost::posix_time::ptime t = lanelet::time::timeFromSec(current_time.seconds()); // time variable
70 boost::posix_time::ptime eet = lanelet::time::timeFromSec(earliest_entry_time.seconds()); // earliest entry time
71
72 // check if the signal even has a green signal
73 bool has_green_signal = false;
74 for (auto pair : signal->recorded_time_stamps)
75 {
76 if (pair.second == lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED &&
77 t <= pair.first )
78 {
79 has_green_signal = true;
80 break;
81 }
82 }
83
84 if (!has_green_signal)
85 {
86 return std::nullopt;
87 }
88
89 auto curr_pair = signal->predictState(t);
90 if (!curr_pair)
91 throw std::invalid_argument("Traffic signal with id:" + std::to_string(signal->id()) + ", does not have any recorded time stamps!");
92
93 boost::posix_time::time_duration theta = curr_pair.get().first - t; // remaining time left in this state
94 auto p = curr_pair.get().second;
95 while ( 0.0 < g.total_milliseconds() || p != lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED) //green
96 {
97 if ( p == lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED)
98 {
99 if (g < theta)
100 {
101 t = t + g;
102 theta = theta - g;
103 g = boost::posix_time::seconds(0);
104 }
105 else
106 {
107 t = t + theta;
108 g = g - theta;
109 curr_pair = signal->predictState(t + boost::posix_time::milliseconds(20)); // select next phase
110 p = curr_pair.get().second;
111 theta = curr_pair.get().first - t;
112 }
113 }
114 else
115 {
116 t = t + theta;
117 curr_pair = signal->predictState(t + boost::posix_time::milliseconds(20)); // select next phase
118 p = curr_pair.get().second;
119 theta = curr_pair.get().first - t;
120 }
121 }
122
123 if (t <= eet)
124 {
125 double cycle_duration = signal->fixed_cycle_duration.total_milliseconds()/1000.0;
126 if (cycle_duration < 0.001) //if it is a dynamic traffic signal not fixed
127 cycle_duration = lanelet::time::toSec(signal->recorded_time_stamps.back().first) - lanelet::time::toSec(signal->recorded_start_time_stamps.front());
128
129 t = t + lanelet::time::durationFromSec(std::floor((eet - t).total_milliseconds()/1000.0/cycle_duration) * cycle_duration); //fancy logic was needed to compile
130 curr_pair = signal->predictState(t + boost::posix_time::milliseconds(20)); // select next phase
131 p = curr_pair.get().second;
132 theta = curr_pair.get().first - t;
133 while ( t < eet || p != lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED)
134 {
135 if ( p == lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED && eet - t < theta)
136 {
137 t = eet;
138 theta = theta - (eet - t);
139 }
140 else
141 {
142 t = t + theta;
143 curr_pair = signal->predictState(t + boost::posix_time::milliseconds(20)); // select next phase
144 p = curr_pair.get().second;
145 theta = curr_pair.get().first - t;
146 }
147
148 if (t != lanelet::time::timeFromSec(lanelet::time::INFINITY_END_TIME_FOR_NOT_ENOUGH_STATES))
149 continue;
150
151 // if no green signal left in the signal states, return
152 return std::nullopt;
153 }
154 }
155 return rclcpp::Time(lanelet::time::toSec(t) * 1e9);
156}

References carma_cooperative_perception::to_string().

Referenced by get_final_entry_time_and_conditions().

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

◆ get_trajectory_smoothing_activation_distance()

double lci_strategic_plugin::LCIStrategicPlugin::get_trajectory_smoothing_activation_distance ( double  time_remaining_at_free_flow,
double  full_cycle_duration,
double  current_speed,
double  speed_limit,
double  departure_speed,
double  max_accel,
double  max_decel 
) const
private

Gets maximum distance (nearest downtrack) the trajectory smoothing algorithm makes difference than simple lane following within half of one full fixed cycle time boundary compared to free flow arrival time.

Parameters
time_remaining_at_free_flowFree flow arrival at the intersection
full_cycle_durationOne fixed cycle of the signal
current_speedCurrent speed in m/s
speed_limitSpeed limit speed in m/s
departure_speedSpeed into the intersection in m/s. A.k.a target speed at the intersection
max_accelThe acceleration in m/s^2 of the acceleration segment
max_decelThe deceleration in m/s^2 of the deceleration segment
Returns
the max distance the plugin should activate to support all speed profile cases of the trajectory smoothing algorithm -1 if it is within the distance already

Definition at line 158 of file lci_strategic_plugin_algo.cpp.

159{
160 // TSMO USE CASE 2: Figure 7. Trajectory smoothing solution Case 2. Subsituted a+ as max_accel and solved for inflection_speed
161 double accel_ratio = max_accel / max_decel;
162 double remaining_time = time_remaining_at_free_flow - full_cycle_duration / 2;
163 double inflection_speed = (max_accel * remaining_time - accel_ratio * departure_speed + current_speed)/ (1 - accel_ratio);
164 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "ENTER TRAJ CALC: time_remaining_at_free_flow: " << time_remaining_at_free_flow << ", full_cycle_duration: " << full_cycle_duration << ", inflection_speed: " << inflection_speed);
165
166 if (remaining_time < 0)
167 return -1;
168
169 if (inflection_speed > 0 && inflection_speed <= speed_limit + epsilon_ && inflection_speed >= departure_speed - epsilon_)
170 {
171 // kinematic equation to find distance of acceleration + deceleration
172 // (vf^2 - vi^2)/2a = d
173 double d = (std::pow(inflection_speed, 2) - std::pow (current_speed, 2)) / (2 * max_accel) + (std::pow(departure_speed, 2) - std::pow(inflection_speed, 2)) / (2 * max_decel);
174 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "calculated distance WITHOUT cruising: " << d);
175 return d;
176 }
177 else //there must be cruising
178 {
179 // acceleration and deceleration parts must reach maximum speed
180 // kinematic equation: t = (vf - vi)/ a where vf = 0
181 double decel_time = (current_speed - speed_limit) / max_decel;
182 double accel_time = (speed_limit - current_speed) / max_accel;
183 double cruising_time = remaining_time - decel_time - accel_time;
184 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "decel_time: " << decel_time << ", accel_time: " << accel_time << ", cruising_time: " << cruising_time);
185 double d = (std::pow(speed_limit, 2) - std::pow (current_speed, 2)) / (2 * max_accel) + (std::pow(departure_speed, 2) - std::pow(speed_limit, 2)) / (2 * max_decel) + cruising_time * speed_limit;
186 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "calculated distance with cruising: " << d << ", accel_seg: " << (std::pow(speed_limit, 2) - std::pow (current_speed, 2)) / (2 * max_accel) <<
187 ", cruising: " << + cruising_time * speed_limit << ", decel_seg:" << (std::pow(departure_speed, 2) - std::pow(speed_limit, 2)) / (2 * max_decel));
188 return d;
189 }
190}

References epsilon_.

◆ get_ts_case()

TrajectoryParams lci_strategic_plugin::LCIStrategicPlugin::get_ts_case ( double  t,
double  et,
double  v0,
double  v1,
double  v_max,
double  v_min,
double  a_max,
double  a_min,
double  x0,
double  x_end,
double  dx,
BoundaryDistances  boundary_distances,
std::vector< TrajectoryParams params 
)
private

Definition at line 579 of file lci_strategic_plugin_algo.cpp.

580{
581 double dx1 = boundary_distances.dx1;
582 double dx2 = boundary_distances.dx2;
583 double dx3 = boundary_distances.dx3;
584 double dx4 = boundary_distances.dx4;
585 double dx5 = boundary_distances.dx5;
586
587 if (params.size() != 8)
588 {
589 throw std::invalid_argument("Not enough trajectory paras given! Given size: " + std::to_string(params.size()));
590 }
591
592 TrajectoryParams traj1 = params[0];
593 TrajectoryParams traj2 = params[1];
594 TrajectoryParams traj3 = params[2];
595 TrajectoryParams traj4 = params[3];
596 TrajectoryParams traj5 = params[4];
597 TrajectoryParams traj6 = params[5];
598 TrajectoryParams traj7 = params[6];
599 TrajectoryParams traj8 = params[7];
600 TrajectoryParams veh_traj;
601 veh_traj.is_algorithm_successful = true;
602
603 if (traj1.t3_ <= et && et < traj2.t3_)
604 {
605 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "CALCULATED: case 1");
606 veh_traj = ts_case1(t, et, v0, v1, v_max, a_max, a_min, x0, x_end, dx);
607 veh_traj.case_num = CASE_1;
608 }
609 else if (traj2.t3_ <= et && et < traj3.t3_)
610 {
611 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "CALCULATED: case 2");
612 veh_traj = ts_case2(t, et, v0, v1, a_max, a_min, x0, x_end, dx);
613 veh_traj.case_num = CASE_2;
614 }
615 else if (traj3.t3_ <= et && et < traj4.t3_)
616 {
617 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "CALCULATED: case 3");
618 veh_traj = ts_case3(t, et, v0, v1, a_max, a_min, x0, x_end, dx);
619 veh_traj.case_num = CASE_3;
620 }
621 else if (traj4.t3_ <= et && et < traj5.t3_)
622 {
623 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "CALCULATED: case 4");
624 veh_traj = ts_case4(t, et, v0, v1, v_min, a_max, a_min, x0, x_end, dx);
625 veh_traj.case_num = CASE_4;
626 }
627 else if (traj5.t3_ <= et && et < traj6.t3_)
628 {
629 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "CALCULATED: case 5");
630 veh_traj = ts_case5(t, et, v0, a_max, a_min, x0, x_end, dx);
631 veh_traj.case_num = CASE_5;
632 }
633 else if (traj6.t3_ <= et && et < traj7.t3_)
634 {
635 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "CALCULATED: case 6");
636 veh_traj = ts_case6(t, et, v0, v_min, a_min, x0, x_end, dx, dx3, traj6);
637 veh_traj.case_num = CASE_6;
638 }
639 else if (traj7.t3_ <= et && et <= traj8.t3_)
640 {
641 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "CALCULATED: case 7");
642 veh_traj = ts_case7(t, et, v0, v_min, a_min, x0, x_end, dx);
643 veh_traj.case_num = CASE_7;
644 }
645 else
646 {
647 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "CALCULATED: case 8");
648 veh_traj = ts_case8(dx, dx5, traj8);
649 veh_traj.case_num = CASE_8;
650 }
651
652 return veh_traj;
653}
TrajectoryParams ts_case7(double t, double et, double v0, double v_min, double a_min, double x0, double x_end, double dx)
TrajectoryParams ts_case1(double t, double et, double v0, double v1, double v_max, double a_max, double a_min, double x0, double x_end, double dx)
Trajectory Smoothing Algorithm 8 cases. TSMO UC2, UC3 algorithm equations.
TrajectoryParams ts_case6(double t, double et, double v0, double v_min, double a_min, double x0, double x_end, double dx, double dx3, TrajectoryParams traj6)
TrajectoryParams ts_case4(double t, double et, double v0, double v1, double v_min, double a_max, double a_min, double x0, double x_end, double dx)
TrajectoryParams ts_case2(double t, double et, double v0, double v1, double a_max, double a_min, double x0, double x_end, double dx)
TrajectoryParams ts_case8(double dx, double dx5, TrajectoryParams traj8)
TrajectoryParams ts_case3(double t, double et, double v0, double v1, double a_max, double a_min, double x0, double x_end, double dx)
TrajectoryParams ts_case5(double t, double et, double v0, double a_max, double a_min, double x0, double x_end, double dx)

References lci_strategic_plugin::CASE_1, lci_strategic_plugin::CASE_2, lci_strategic_plugin::CASE_3, lci_strategic_plugin::CASE_4, lci_strategic_plugin::CASE_5, lci_strategic_plugin::CASE_6, lci_strategic_plugin::CASE_7, lci_strategic_plugin::CASE_8, lci_strategic_plugin::TrajectoryParams::case_num, lci_strategic_plugin::BoundaryDistances::dx1, lci_strategic_plugin::BoundaryDistances::dx2, lci_strategic_plugin::BoundaryDistances::dx3, lci_strategic_plugin::BoundaryDistances::dx4, lci_strategic_plugin::BoundaryDistances::dx5, lci_strategic_plugin::TrajectoryParams::is_algorithm_successful, lci_strategic_plugin::TrajectoryParams::t3_, carma_cooperative_perception::to_string(), ts_case1(), ts_case2(), ts_case3(), ts_case4(), ts_case5(), ts_case6(), ts_case7(), and ts_case8().

Referenced by planWhenAPPROACHING().

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

◆ get_version_id()

std::string lci_strategic_plugin::LCIStrategicPlugin::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 1546 of file lci_strategic_plugin.cpp.

1547{
1548 return "v1.0";
1549}

◆ getLaneletsBetweenWithException()

std::vector< lanelet::ConstLanelet > lci_strategic_plugin::LCIStrategicPlugin::getLaneletsBetweenWithException ( double  start_downtrack,
double  end_downtrack,
bool  shortest_path_only = false,
bool  bounds_inclusive = true 
) const
private

Helper method which calls carma_wm::WorldModel::getLaneletsBetween(start_downtrack, end_downtrack, shortest_path_only, bounds_inclusive) and throws and exception if the returned list of lanelets is empty. See the referenced method for additional details on parameters.

Definition at line 341 of file lci_strategic_plugin.cpp.

345{
346 std::vector<lanelet::ConstLanelet> crossed_lanelets =
347 wm_->getLaneletsBetween(start_downtrack, end_downtrack, shortest_path_only, bounds_inclusive);
348
349 if (crossed_lanelets.size() == 0)
350 {
351 throw std::invalid_argument("getLaneletsBetweenWithException called but inputs do not cross any lanelets going "
352 "from: " +
353 std::to_string(start_downtrack) + " to: " + std::to_string(end_downtrack));
354 }
355
356 return crossed_lanelets;
357}

References carma_cooperative_perception::to_string(), and wm_.

Referenced by extractInitialState(), handleCruisingUntilStop(), handleFailureCase(), handleGreenSignalScenario(), handleStopping(), and planWhenDEPARTING().

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

◆ getTurnDirectionAtIntersection()

TurnDirection lci_strategic_plugin::LCIStrategicPlugin::getTurnDirectionAtIntersection ( std::vector< lanelet::ConstLanelet >  lanelets_list)

Determine the turn direction at intersection.

Parameters
lanelets_listList of lanelets crossed around the intersection area
Returns
turn direction in format of straight, left, right

Definition at line 1222 of file lci_strategic_plugin.cpp.

1223{
1224 TurnDirection turn_direction = TurnDirection::Straight;
1225 for (auto l:lanelets_list)
1226 {
1227 if(l.hasAttribute("turn_direction")) {
1228 std::string direction_attribute = l.attribute("turn_direction").value();
1229 if (direction_attribute == "right")
1230 {
1231 turn_direction = TurnDirection::Right;
1232 break;
1233 }
1234 else if (direction_attribute == "left")
1235 {
1236 turn_direction = TurnDirection::Left;
1237 break;
1238 }
1239 else turn_direction = TurnDirection::Straight;
1240 }
1241 else
1242 {
1243 // if there is no attribute, assumption is straight
1244 turn_direction = TurnDirection::Straight;
1245 }
1246
1247 }
1248 return turn_direction;
1249}

References lci_strategic_plugin::Left, lci_strategic_plugin::Right, and lci_strategic_plugin::Straight.

Referenced by planWhenAPPROACHING().

Here is the caller graph for this function:

◆ handleCruisingUntilStop()

void lci_strategic_plugin::LCIStrategicPlugin::handleCruisingUntilStop ( carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr  req,
carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr  resp,
const VehicleState current_state,
double  current_state_speed,
const lanelet::CarmaTrafficSignalPtr &  traffic_light,
double  traffic_light_down_track,
const TrajectoryParams ts_params 
)
private

This function returns valid maneuvers if the vehicle is able to utilize trajectory smoothing parameters to go through the intersection with certainty It utilizes canMakeWithCertainty function to determine if it is able to make it. Corresponds to TSCase 1-7.

Parameters
reqPlan maneuver request
[out]respPlan maneuver response with a list of maneuver plan
current_stateCurrent state of the vehicle
current_state_speedThe current speed to use when planning
traffic_lightCarmaTrafficSignalPtr of the relevant signal
traffic_light_down_trackDowntrack to the given traffic_light
ts_paramstrajectory smoothing params
Returns
void. if successful, resp is non-empty. Resp is empty if not able to make it with certainty or ts_params.is_successful is false

Definition at line 433 of file lci_strategic_plugin.cpp.

439{
440 if (!ts_params.is_algorithm_successful || ts_params.case_num != TSCase::CASE_8)
441 {
442 RCLCPP_WARN_STREAM(rclcpp::get_logger("lci_strategic_plugin"),"handleCruisingUntilStop is called but it is not case_8");
443 return;
444 }
445
446 auto new_ts_params = ts_params;
447
448 double decel_rate = std::fabs(ts_params.a3_);
449
450 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "CASE_8: Planning cruise and stop with decel_rate: " << decel_rate);
451
452 new_ts_params.t3_ = new_ts_params.t2_;
453 new_ts_params.x3_ = new_ts_params.x2_;
454 new_ts_params.v3_ = new_ts_params.v2_;
455 new_ts_params.a3_ = new_ts_params.a2_;
456
457 // Identify the lanelets which will be crossed by approach maneuvers stopping part
458 std::vector<lanelet::ConstLanelet> lane_follow_crossed_lanelets =
459 getLaneletsBetweenWithException(new_ts_params.x1_, new_ts_params.x2_, true, true);
460
461 resp->new_plan.maneuvers.push_back(composeTrajectorySmoothingManeuverMessage(current_state.downtrack, new_ts_params.x2_, lane_follow_crossed_lanelets,
462 current_state_speed, new_ts_params.v2_, current_state.stamp, rclcpp::Time(new_ts_params.t2_ * 1e9), new_ts_params));
463
464 // Identify the lanelets which will be crossed by approach maneuvers stopping part
465 std::vector<lanelet::ConstLanelet> case_8_crossed_lanelets =
466 getLaneletsBetweenWithException(new_ts_params.x2_, traffic_light_down_track, true, true);
467
468 resp->new_plan.maneuvers.push_back(composeStopAndWaitManeuverMessage(
469 new_ts_params.x2_, traffic_light_down_track, new_ts_params.v2_, case_8_crossed_lanelets.front().id(),
470 case_8_crossed_lanelets.back().id(), rclcpp::Time(new_ts_params.t2_ * 1e9),
471 rclcpp::Time(new_ts_params.t2_ * 1e9) + rclcpp::Duration(config_.min_maneuver_planning_period * 1e9), decel_rate));
472
473 return;
474}
carma_planning_msgs::msg::Maneuver composeTrajectorySmoothingManeuverMessage(double start_dist, double end_dist, const std::vector< lanelet::ConstLanelet > &crossed_lanelets, double start_speed, double target_speed, rclcpp::Time start_time, rclcpp::Time end_time, const TrajectoryParams &tsp) const
Compose a trajectory smoothing maneuver msg (sent as transit maneuver message)
carma_planning_msgs::msg::Maneuver composeStopAndWaitManeuverMessage(double current_dist, double end_dist, double start_speed, const lanelet::Id &starting_lane_id, const lanelet::Id &ending_lane_id, rclcpp::Time start_time, rclcpp::Time end_time, double stopping_accel) const
Compose a stop and wait maneuver message based on input params.

References lci_strategic_plugin::TrajectoryParams::a3_, lci_strategic_plugin::CASE_8, lci_strategic_plugin::TrajectoryParams::case_num, composeStopAndWaitManeuverMessage(), composeTrajectorySmoothingManeuverMessage(), config_, lci_strategic_plugin::LCIStrategicPlugin::VehicleState::downtrack, getLaneletsBetweenWithException(), lci_strategic_plugin::TrajectoryParams::is_algorithm_successful, lci_strategic_plugin::LCIStrategicPluginConfig::min_maneuver_planning_period, and lci_strategic_plugin::LCIStrategicPlugin::VehicleState::stamp.

Referenced by planWhenAPPROACHING().

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

◆ handleFailureCase()

void lci_strategic_plugin::LCIStrategicPlugin::handleFailureCase ( carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr  req,
carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr  resp,
const VehicleState current_state,
double  current_state_speed,
double  speed_limit,
double  remaining_time,
lanelet::Id  exit_lanelet_id,
const lanelet::CarmaTrafficSignalPtr &  traffic_light,
double  traffic_light_down_track,
const TrajectoryParams ts_params 
)
private

When the vehicle is not able to successfully run the algorithm or not able to stop, this function modifies departure speed as close as possible to the original using max comfortable accelerations with given distance.

Parameters
reqPlan maneuver request
[out]respPlan maneuver response with a list of maneuver plan
current_stateCurrent state of the vehicle
current_state_speedThe current speed to use when planning
speed_limitSpeed limit to cap the speed
remaining_timeRemaining time until scheduled entry
exit_lanelet_idId of the exit lanelet
traffic_lightCarmaTrafficSignalPtr of the relevant signal
traffic_light_down_trackDowntrack to the given traffic_light
ts_paramstrajectory smoothing params
Returns
void. if successful, resp is non-empty. Resp is empty if not able to make it with certainty or ts_params.is_successful is false

Definition at line 394 of file lci_strategic_plugin.cpp.

403{
404 double distance_remaining_to_traffic_light = traffic_light_down_track - current_state.downtrack;
405
406 // Identify the lanelets which will be crossed by approach maneuvers lane follow maneuver
407 std::vector<lanelet::ConstLanelet> crossed_lanelets =
408 getLaneletsBetweenWithException(current_state.downtrack, traffic_light_down_track, true, true);
409
410 auto incomplete_traj_params = handleFailureCaseHelper(traffic_light, current_state.stamp.seconds(), current_state_speed, intersection_speed_.get(), speed_limit, distance_remaining_to_traffic_light, traffic_light_down_track);
411
412 if (incomplete_traj_params.is_algorithm_successful == false)
413 {
414 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Failed to generate maneuver for edge cases...");
415 return;
416 }
417
418 resp->new_plan.maneuvers.push_back(composeTrajectorySmoothingManeuverMessage(current_state.downtrack, traffic_light_down_track, crossed_lanelets,
419 current_state_speed, incomplete_traj_params.modified_departure_speed, current_state.stamp, current_state.stamp + rclcpp::Duration(incomplete_traj_params.modified_remaining_time * 1e9), incomplete_traj_params));
420
421 double intersection_length = intersection_end_downtrack_.get() - traffic_light_down_track;
422
423 rclcpp::Time intersection_exit_time =
424 current_state.stamp + rclcpp::Duration(incomplete_traj_params.modified_remaining_time * 1e9) + rclcpp::Duration(intersection_length / incomplete_traj_params.modified_departure_speed * 1e9);
425
426 resp->new_plan.maneuvers.push_back(composeIntersectionTransitMessage(
427 traffic_light_down_track, intersection_end_downtrack_.get(), intersection_speed_.get(),
428 incomplete_traj_params.modified_departure_speed, current_state.stamp + rclcpp::Duration(incomplete_traj_params.modified_remaining_time * 1e9), intersection_exit_time, crossed_lanelets.back().id(), crossed_lanelets.back().id()));
429
431}
TrajectoryParams handleFailureCaseHelper(const lanelet::CarmaTrafficSignalPtr &traffic_light, double current_time, double starting_speed, double departure_speed, double speed_limit, double remaining_downtrack, double traffic_light_downtrack)
Helper function to handleFailureCase that modifies ts_params to desired new parameters....
boost::optional< double > intersection_end_downtrack_
TSCase last_case_num_
Useful metrics for LCI Plugin.
boost::optional< double > intersection_speed_
Cache variables for storing the current intersection state between state machine transitions.
carma_planning_msgs::msg::Maneuver composeIntersectionTransitMessage(double start_dist, double end_dist, double start_speed, double target_speed, rclcpp::Time start_time, rclcpp::Time end_time, const lanelet::Id &starting_lane_id, const lanelet::Id &ending_lane_id) const
Compose a intersection transit maneuver message based on input params.

References composeIntersectionTransitMessage(), composeTrajectorySmoothingManeuverMessage(), lci_strategic_plugin::DEGRADED_TSCASE, lci_strategic_plugin::LCIStrategicPlugin::VehicleState::downtrack, getLaneletsBetweenWithException(), handleFailureCaseHelper(), intersection_end_downtrack_, intersection_speed_, last_case_num_, and lci_strategic_plugin::LCIStrategicPlugin::VehicleState::stamp.

Referenced by planWhenAPPROACHING().

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

◆ handleFailureCaseHelper()

TrajectoryParams lci_strategic_plugin::LCIStrategicPlugin::handleFailureCaseHelper ( const lanelet::CarmaTrafficSignalPtr &  traffic_light,
double  current_time,
double  starting_speed,
double  departure_speed,
double  speed_limit,
double  remaining_downtrack,
double  traffic_light_downtrack 
)
private

Helper function to handleFailureCase that modifies ts_params to desired new parameters. See handleFailureCase.

Parameters
starting_speedstarting speed
departure_speeddeparture_speed originally planned
speed_limitspeed_limit
remaining_downtrackremaining_downtrack until the intersection
traffic_light_downtracktraffic_light_downtrack when vehicle is scheduled to enter
Returns
TSP with parameters that is best available to pass the intersection. Either cruising with starting_speed or sacrifice departure speed to meet time and distance

Definition at line 521 of file lci_strategic_plugin.cpp.

522{
523 //Requested maneuver needs to be modified to meet remaining_dist req
524 //by trying to get close to the target_speed and remaining_time as much as possible
525 TrajectoryParams return_params;
526 TrajectoryParams traj_upper;
527 TrajectoryParams traj_lower;
528
529 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "HANDLE_LAST_RESORT_CASE: Starting...");
530 double starting_downtrack = traffic_light_downtrack - remaining_downtrack;
531 double modified_remaining_time_upper; // upper meaning downtrack vs time trajectory is curved upwards
532 double modified_remaining_time_lower; // lower meaning downtrack vs time trajectory is curved lower
533 double modified_departure_speed_upper;
534 double modified_departure_speed_lower;
535 bool calculation_success_upper = true; // identifies places in codes where calculation can be invalid such as negative distance
536
537 // the upper ET
538 // accel case
539 traj_upper.t0_ = current_time;
540 traj_upper.v0_ = starting_speed;
541 traj_upper.x0_ = starting_downtrack;
542 traj_upper.is_algorithm_successful = true;
543 traj_upper.case_num = CASE_1;
544
545 if (departure_speed >= starting_speed)
546 {
547 if ((pow(departure_speed,2) - pow(starting_speed,2))/(2*max_comfort_accel_) >= remaining_downtrack)
548 {
549 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "HandleFailureCase -> Upper Trajectory -> Current Speed <= Desired Departure Speed, Actual Departure Speed < Desired Departure Speed");
550
551 modified_departure_speed_upper = sqrt(pow(starting_speed, 2) + (2 * max_comfort_accel_ * remaining_downtrack));
552 modified_remaining_time_upper = (modified_departure_speed_upper - starting_speed) / max_comfort_accel_;
553
554 traj_upper.t1_ = current_time + modified_remaining_time_upper;
555 traj_upper.v1_ = modified_departure_speed_upper;
556 traj_upper.a1_ = max_comfort_accel_;
557 traj_upper.x1_ = traffic_light_downtrack;
558
559 traj_upper.t2_ = traj_upper.t1_;
560 traj_upper.v2_ = traj_upper.v1_;
561 traj_upper.a2_ = traj_upper.a1_;
562 traj_upper.x2_ = traj_upper.x1_;
563
564 traj_upper.modified_departure_speed = modified_departure_speed_upper;
565 traj_upper.modified_remaining_time = modified_remaining_time_upper;
566 }
567 else // NOTE: most likely will not happen as it would have happened at trajectory smoothing part
568 {
569 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "HandleFailureCase -> Upper Trajectory -> Current Speed < Desired Departure Speed, Actual Departure Speed = Desired Departure Speed");
570
571 double cruising_distance = remaining_downtrack - (pow(departure_speed, 2) - pow(starting_speed, 2))/ ( 2 * max_comfort_accel_);
572 if (cruising_distance < -EPSILON)
573 {
574 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Detected calculation failure in upper case 2");
575 calculation_success_upper = false;
576 }
577 modified_remaining_time_upper = ((departure_speed - starting_speed) / max_comfort_accel_) + (cruising_distance / departure_speed);
578
579 traj_upper.t1_ = current_time + ((departure_speed - starting_speed) / max_comfort_accel_);
580 traj_upper.v1_ = departure_speed;
581 traj_upper.a1_ = max_comfort_accel_;
582 traj_upper.x1_ = starting_downtrack + (pow(departure_speed, 2) - pow(starting_speed, 2)) / (2 * max_comfort_accel_);
583
584 traj_upper.t2_ = current_time + modified_remaining_time_upper;
585 traj_upper.v2_ = departure_speed;
586 traj_upper.a2_ = 0;
587 traj_upper.x2_ = traffic_light_downtrack;
588
589 traj_upper.modified_departure_speed = departure_speed;
590 traj_upper.modified_remaining_time = modified_remaining_time_upper;
591 }
592 }
593
594 if (departure_speed < starting_speed) // NOTE: most cases will not run due to departure speed being equal to speed limit
595 {
596 if ((pow(departure_speed,2) - pow(starting_speed,2))/(2*max_comfort_decel_) >= remaining_downtrack)
597 {
598 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "HandleFailureCase -> Upper Trajectory -> Current Speed > Desired Departure Speed, Actual Departure Speed > Desired Departure Speed");
599
600 modified_departure_speed_upper = sqrt(pow(starting_speed, 2) + (2 * max_comfort_decel_ * remaining_downtrack));
601 modified_remaining_time_upper = (modified_departure_speed_upper - starting_speed) / max_comfort_decel_;
602
603 traj_upper.t1_ = current_time + modified_remaining_time_upper;
604 traj_upper.v1_ = modified_departure_speed_upper;
605 traj_upper.a1_ = max_comfort_decel_;
606 traj_upper.x1_ = traffic_light_downtrack;
607
608 traj_upper.t2_ = traj_upper.t1_;
609 traj_upper.v2_ = traj_upper.v1_;
610 traj_upper.a2_ = traj_upper.a1_;
611 traj_upper.x2_ = traj_upper.x1_;
612
613 traj_upper.modified_departure_speed = modified_departure_speed_upper;
614 traj_upper.modified_remaining_time = modified_remaining_time_upper;
615 }
616 else // NOTE: most likely will not happen as it would have happened at trajectory smoothing part
617 {
618 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "HandleFailureCase -> Upper Trajectory -> Current Speed > Desired Departure Speed, Actual Departure Speed = Desired Departure Speed");
619
620 double cruising_distance = remaining_downtrack - (pow(departure_speed, 2) - pow(starting_speed, 2))/ ( 2 * max_comfort_decel_);
621
622 if (cruising_distance < -EPSILON)
623 {
624 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Detected calculation failure in upper case 4");
625 calculation_success_upper = false;
626 }
627
628 modified_remaining_time_upper = cruising_distance / starting_speed + (departure_speed - starting_speed) / max_comfort_decel_ ;
629
630 traj_upper.t1_ = current_time + cruising_distance / starting_speed;
631 traj_upper.v1_ = starting_speed;
632 traj_upper.a1_ = 0.0;
633 traj_upper.x1_ = starting_downtrack + cruising_distance;
634
635 traj_upper.t2_ = current_time + modified_remaining_time_upper;
636 traj_upper.v2_ = departure_speed;
637 traj_upper.a2_ = max_comfort_decel_;
638 traj_upper.x2_ = traffic_light_downtrack;
639
640 traj_upper.modified_departure_speed = departure_speed;
641 traj_upper.modified_remaining_time = modified_remaining_time_upper;
642 }
643 }
644
645 traj_upper.t3_ = traj_upper.t2_;
646 traj_upper.v3_ = traj_upper.v2_;
647 traj_upper.a3_ = traj_upper.a2_;
648 traj_upper.x3_ = traj_upper.x2_;
649
650 // The lower ET
651 // (note that the distance is definitely not enough for deceleration to zero speed, therefore, modified_departure_speed will be greater than zero for sure!).
652 modified_departure_speed_lower = sqrt(pow(starting_speed, 2) + (2 * max_comfort_decel_ * remaining_downtrack));
653 modified_remaining_time_lower = (modified_departure_speed_lower - starting_speed) / max_comfort_decel_;
654
655 traj_lower.t0_ = current_time;
656 traj_lower.v0_ = starting_speed;
657 traj_lower.x0_ = starting_downtrack;
658 traj_lower.is_algorithm_successful = true;
659 traj_lower.case_num = CASE_1;
660
661 traj_lower.t1_ = current_time + modified_remaining_time_lower;
662 traj_lower.v1_ = modified_departure_speed_lower;
663 traj_lower.a1_ = max_comfort_decel_;
664 traj_lower.x1_ = traffic_light_downtrack;
665
666 traj_lower.t2_ = traj_lower.t1_;
667 traj_lower.v2_ = traj_lower.v1_;
668 traj_lower.a2_ = traj_lower.a1_;
669 traj_lower.x2_ = traj_lower.x1_;
670
671 traj_lower.t3_ = traj_lower.t2_;
672 traj_lower.v3_ = traj_lower.v2_;
673 traj_lower.a3_ = traj_lower.a2_;
674 traj_lower.x3_ = traj_lower.x2_;
675
676 traj_lower.modified_departure_speed = modified_departure_speed_lower;
677 traj_lower.modified_remaining_time = modified_remaining_time_upper;
678
679 // Pick UPPER or LOWER trajectory based on light
680 bool is_return_params_found = false;
681
682 if (calculation_success_upper)
683 {
684 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Checking this time!: " << current_time + modified_remaining_time_upper);
685
686 auto upper_optional = traffic_light->predictState(lanelet::time::timeFromSec(current_time + modified_remaining_time_upper));
687
688 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Checking this time! state: " << upper_optional.get().second);
689
690 if (!validLightState(upper_optional, rclcpp::Time((current_time + modified_remaining_time_upper) * 1e9)))
691 {
692 RCLCPP_ERROR_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Unable to resolve give signal for modified_remaining_time_upper: " << std::to_string(current_time + modified_remaining_time_upper));
693 }
694 else
695 {
696 if (upper_optional.get().second == lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED)
697 {
698 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Detected Upper GREEN case");
699 return_params = traj_upper;
700 is_return_params_found = true;
701 }
702 }
703 }
704
705 if (!is_return_params_found)
706 {
707 auto lower_optional = traffic_light->predictState(lanelet::time::timeFromSec(current_time + modified_remaining_time_lower));
708
709 if (!validLightState(lower_optional, rclcpp::Time((current_time + modified_remaining_time_lower) * 1e9)))
710 {
711 RCLCPP_ERROR_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Unable to resolve give signal for modified_remaining_time_lower:" << std::to_string(current_time + modified_remaining_time_lower));
712 }
713 else
714 {
715 if (lower_optional.get().second == lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED)
716 {
717 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Detected Lower GREEN case");
718 return_params = traj_lower;
719 is_return_params_found = true;
720 }
721 }
722 }
723
724 // Handle hard failure case such as nan or invalid states
725 if (is_return_params_found && !isnan(return_params.modified_departure_speed) && return_params.modified_departure_speed > epsilon_ &&
726 return_params.modified_departure_speed < speed_limit ) //80_mph
727 {
728 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Updated the speed, and using modified_departure_speed: " << return_params.modified_departure_speed);
729 print_params(return_params);
730 return return_params;
731 }
732 else
733 {
734 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Unable to handle edge case gracefully");
735 return_params = TrajectoryParams(); //reset
736 return_params.is_algorithm_successful = false;
737 return return_params;
738 }
739}
void print_params(TrajectoryParams params)
Helper method to print TrajectoryParams.
#define EPSILON

References lci_strategic_plugin::TrajectoryParams::a1_, lci_strategic_plugin::TrajectoryParams::a2_, lci_strategic_plugin::TrajectoryParams::a3_, lci_strategic_plugin::CASE_1, lci_strategic_plugin::TrajectoryParams::case_num, EPSILON, epsilon_, lci_strategic_plugin::TrajectoryParams::is_algorithm_successful, max_comfort_accel_, max_comfort_decel_, lci_strategic_plugin::TrajectoryParams::modified_departure_speed, lci_strategic_plugin::TrajectoryParams::modified_remaining_time, print_params(), lci_strategic_plugin::TrajectoryParams::t0_, lci_strategic_plugin::TrajectoryParams::t1_, lci_strategic_plugin::TrajectoryParams::t2_, lci_strategic_plugin::TrajectoryParams::t3_, carma_cooperative_perception::to_string(), lci_strategic_plugin::TrajectoryParams::v0_, lci_strategic_plugin::TrajectoryParams::v1_, lci_strategic_plugin::TrajectoryParams::v2_, lci_strategic_plugin::TrajectoryParams::v3_, validLightState(), lci_strategic_plugin::TrajectoryParams::x0_, lci_strategic_plugin::TrajectoryParams::x1_, lci_strategic_plugin::TrajectoryParams::x2_, and lci_strategic_plugin::TrajectoryParams::x3_.

Referenced by handleFailureCase().

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

◆ handleGreenSignalScenario()

void lci_strategic_plugin::LCIStrategicPlugin::handleGreenSignalScenario ( carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr  req,
carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr  resp,
const VehicleState current_state,
double  current_state_speed,
const lanelet::CarmaTrafficSignalPtr &  traffic_light,
const lanelet::ConstLanelet &  entry_lanelet,
const lanelet::ConstLanelet &  exit_lanelet,
double  traffic_light_down_track,
const TrajectoryParams ts_params,
bool  is_certainty_check_optional 
)
private

This function returns valid maneuvers if the vehicle is able to utilize trajectory smoothing parameters to go through the intersection with certainty It utilizes canMakeWithCertainty function to determine if it is able to make it. Corresponds to TSCase 1-7.

Parameters
reqPlan maneuver request
[out]respPlan maneuver response with a list of maneuver plan
current_stateCurrent state of the vehicle
current_state_speedThe current speed to use when planning
traffic_lightCarmaTrafficSignalPtr of the relevant signal
entry_laneletEntry lanelet in to the intersection along route
exit_laneletExit lanelet in to the intersection along route
traffic_light_down_trackDowntrack to the given traffic_light
ts_paramstrajectory smoothing params
Returns
void. if successful, resp is non-empty. Resp is empty if not able to make it with certainty or ts_params.is_successful is false

Definition at line 476 of file lci_strategic_plugin.cpp.

483{
484 if (!ts_params.is_algorithm_successful || ts_params.case_num == TSCase::CASE_8)
485 {
486 return;
487 }
488
489 rclcpp::Time light_arrival_time_by_algo = rclcpp::Time(ts_params.t3_ * 1e9);
490 double remaining_time = light_arrival_time_by_algo.seconds() - rclcpp::Time(req->header.stamp, RCL_SYSTEM_TIME).seconds();
491 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Algo initially successful: New light_arrival_time_by_algo: " << std::to_string(light_arrival_time_by_algo.seconds()) << ", with remaining_time: " << std::to_string(remaining_time));
492 auto can_make_green_optional = canArriveAtGreenWithCertainty(light_arrival_time_by_algo, traffic_light);
493
494 // Identify the lanelets which will be crossed by approach maneuvers lane follow maneuver
495 std::vector<lanelet::ConstLanelet> crossed_lanelets =
496 getLaneletsBetweenWithException(current_state.downtrack, traffic_light_down_track, true, true);
497
498 // no change for maneuver if invalid light states
499 if (!can_make_green_optional)
500 return;
501
502 if (can_make_green_optional.get() || is_certainty_check_optional)
503 {
504 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "HANDLE_SUCCESSFULL: Algorithm successful, and able to make it at green with certainty. Planning traj smooth and intersection transit maneuvers");
505
506 resp->new_plan.maneuvers.push_back(composeTrajectorySmoothingManeuverMessage(current_state.downtrack, traffic_light_down_track, crossed_lanelets,
507 current_state_speed, ts_params.v3_, current_state.stamp, light_arrival_time_by_algo, ts_params));
508
509 double intersection_length = intersection_end_downtrack_.get() - traffic_light_down_track;
510
511 rclcpp::Time intersection_exit_time =
512 light_arrival_time_by_algo + rclcpp::Duration(intersection_length / intersection_speed_.get() * 1e9);
513
514 resp->new_plan.maneuvers.push_back(composeIntersectionTransitMessage(
515 traffic_light_down_track, intersection_end_downtrack_.get(), intersection_speed_.get(),
516 intersection_speed_.get(), light_arrival_time_by_algo, intersection_exit_time, crossed_lanelets.back().id(), crossed_lanelets.back().id()));
517 }
518}
boost::optional< bool > canArriveAtGreenWithCertainty(const rclcpp::Time &light_arrival_time_by_algo, const lanelet::CarmaTrafficSignalPtr &traffic_light, bool check_late, bool check_early) const
Return true if the car can arrive at given arrival time within green light time buffer.

References canArriveAtGreenWithCertainty(), lci_strategic_plugin::CASE_8, lci_strategic_plugin::TrajectoryParams::case_num, composeIntersectionTransitMessage(), composeTrajectorySmoothingManeuverMessage(), lci_strategic_plugin::LCIStrategicPlugin::VehicleState::downtrack, getLaneletsBetweenWithException(), intersection_end_downtrack_, intersection_speed_, lci_strategic_plugin::TrajectoryParams::is_algorithm_successful, lci_strategic_plugin::LCIStrategicPlugin::VehicleState::stamp, lci_strategic_plugin::TrajectoryParams::t3_, carma_cooperative_perception::to_string(), and lci_strategic_plugin::TrajectoryParams::v3_.

Referenced by planWhenAPPROACHING().

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

◆ handleStopping()

void lci_strategic_plugin::LCIStrategicPlugin::handleStopping ( carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr  req,
carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr  resp,
const VehicleState current_state,
const lanelet::CarmaTrafficSignalPtr &  traffic_light,
const lanelet::ConstLanelet &  entry_lanelet,
const lanelet::ConstLanelet &  exit_lanelet,
const lanelet::ConstLanelet &  current_lanelet,
double  traffic_light_down_track,
bool  is_emergency = false 
)
private

This function returns stopping maneuver if the vehicle is able to stop at red and in safe stopping distance. Given the initial speed, ending speed (which is 0), and remaining_downtrack, this function checks if calculated remaining_time falls on RED.

Parameters
reqPlan maneuver request
[out]respPlan maneuver response with a list of maneuver plan
current_stateCurrent state of the vehicle
traffic_lightCarmaTrafficSignalPtr of the relevant signal
entry_laneletEntry lanelet in to the intersection along route
exit_laneletExit lanelet in to the intersection along route
current_laneletCurrent lanelet
traffic_light_down_trackDowntrack to the given traffic_light
is_emergencyif enabled, double the deceleration rate of max_comfort_accel is used
Returns
void. if successful, resp is non-empty

Definition at line 359 of file lci_strategic_plugin.cpp.

366{
367 double distance_remaining_to_traffic_light = traffic_light_down_track - current_state.downtrack;
368
369 // Identify the lanelets which will be crossed by approach maneuvers lane follow maneuver
370 std::vector<lanelet::ConstLanelet> crossed_lanelets =
371 getLaneletsBetweenWithException(current_state.downtrack, traffic_light_down_track, true, true);
372
373 double decel_rate = max_comfort_decel_norm_; // Kinematic |(v_f - v_i) / t = a|
374
375 if (is_emergency)
376 {
377 decel_rate = emergency_decel_norm_;
379 }
380 else
381 {
383 }
384
385 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "HANDLE_STOPPING: Planning stop and wait maneuver at decel_rate: " << decel_rate);
386
387 resp->new_plan.maneuvers.push_back(composeStopAndWaitManeuverMessage(
388 current_state.downtrack, traffic_light_down_track, current_state.speed, crossed_lanelets.front().id(),
389 crossed_lanelets.back().id(), current_state.stamp,
390 current_state.stamp + rclcpp::Duration(config_.min_maneuver_planning_period * 1e9), decel_rate));
391}

References composeStopAndWaitManeuverMessage(), config_, lci_strategic_plugin::LCIStrategicPlugin::VehicleState::downtrack, emergency_decel_norm_, lci_strategic_plugin::EMERGENCY_STOPPING, getLaneletsBetweenWithException(), last_case_num_, max_comfort_decel_norm_, lci_strategic_plugin::LCIStrategicPluginConfig::min_maneuver_planning_period, lci_strategic_plugin::LCIStrategicPlugin::VehicleState::speed, lci_strategic_plugin::LCIStrategicPlugin::VehicleState::stamp, and lci_strategic_plugin::STOPPING.

Referenced by planWhenAPPROACHING().

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

◆ lookupFrontBumperTransform()

void lci_strategic_plugin::LCIStrategicPlugin::lookupFrontBumperTransform ( )

Lookup transfrom from front bumper to base link.

Definition at line 219 of file lci_strategic_plugin.cpp.

220{
221 tf2_listener_.reset(new tf2_ros::TransformListener(tf2_buffer_));
222 tf2_buffer_.setUsingDedicatedThread(true);
223 try
224 {
225 geometry_msgs::msg::TransformStamped tf2 = tf2_buffer_.lookupTransform("base_link", "vehicle_front", rclcpp::Time(0), rclcpp::Duration(20.0 * 1e9)); //save to local copy of transform 20 sec timeout
226 length_to_front_bumper_ = tf2.transform.translation.x;
227 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "length_to_front_bumper_: " << length_to_front_bumper_);
228
229 }
230 catch (const tf2::TransformException &ex)
231 {
232 RCLCPP_WARN_STREAM(rclcpp::get_logger("lci_strategic_plugin"), ex.what());
233 }
234}
std::unique_ptr< tf2_ros::TransformListener > tf2_listener_

References length_to_front_bumper_, tf2_buffer_, and tf2_listener_.

Referenced by on_configure_plugin().

Here is the caller graph for this function:

◆ mobilityOperationCb()

void lci_strategic_plugin::LCIStrategicPlugin::mobilityOperationCb ( carma_v2x_msgs::msg::MobilityOperation::UniquePtr  msg)

callback function for mobility operation

Parameters
msginput mobility operation msg

Definition at line 1151 of file lci_strategic_plugin.cpp.

1152{
1153 if (msg->strategy == light_controlled_intersection_strategy_)
1154 {
1155 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Received Schedule message with id: " << msg->m_header.plan_id);
1157 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Approaching light Controlled Intersection: " << approaching_light_controlled_intersection_);
1158
1159 if (msg->m_header.recipient_id == config_.vehicle_id)
1160 {
1161 street_msg_timestamp_ = msg->m_header.timestamp;
1162 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "street_msg_timestamp_: " << street_msg_timestamp_);
1163 parseStrategyParams(msg->strategy_params);
1164 previous_strategy_params_ = msg->strategy_params;
1165 }
1166 }
1167
1168}
void parseStrategyParams(const std::string &strategy_params)
parse strategy parameters

References approaching_light_controlled_intersection_, config_, light_controlled_intersection_strategy_, parseStrategyParams(), previous_strategy_params_, street_msg_timestamp_, and lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_id.

Referenced by on_configure_plugin().

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

◆ on_activate_plugin()

carma_ros2_utils::CallbackReturn lci_strategic_plugin::LCIStrategicPlugin::on_activate_plugin ( )
virtual

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.

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

Reimplemented from carma_guidance_plugins::PluginBaseNode.

Definition at line 178 of file lci_strategic_plugin.cpp.

179{
180 mob_op_pub_timer_ = create_timer(get_clock(),
181 std::chrono::duration<double>(1/config_.mobility_rate),
183
184 ts_info_pub_timer_ = create_timer(get_clock(),
185 std::chrono::duration<double>(0.5),
187
188 return CallbackReturn::SUCCESS;
189}
void publishTrajectorySmoothingInfo()
Publish trajectory smoothing info at a fixed rate.
void publishMobilityOperation()
Publish mobility operation at a fixed rate.
rclcpp::TimerBase::SharedPtr ts_info_pub_timer_
rclcpp::TimerBase::SharedPtr mob_op_pub_timer_

References config_, mob_op_pub_timer_, lci_strategic_plugin::LCIStrategicPluginConfig::mobility_rate, publishMobilityOperation(), publishTrajectorySmoothingInfo(), and ts_info_pub_timer_.

Here is the call graph for this function:

◆ on_configure_plugin()

carma_ros2_utils::CallbackReturn lci_strategic_plugin::LCIStrategicPlugin::on_configure_plugin ( )
virtual

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 73 of file lci_strategic_plugin.cpp.

74{
75 // reset config
76 config_ = LCIStrategicPluginConfig();
77
78 // clang-format off
79 get_parameter<double>("vehicle_acceleration_limit", config_.vehicle_accel_limit);
80 get_parameter<double>("vehicle_deceleration_limit", config_.vehicle_decel_limit);
81 get_parameter<double>("vehicle_decel_limit_multiplier", config_.vehicle_decel_limit_multiplier);
82 get_parameter<double>("vehicle_accel_limit_multiplier", config_.vehicle_accel_limit_multiplier);
83 get_parameter<double>("min_approach_distance", config_.min_approach_distance);
84 get_parameter<double>("trajectory_smoothing_activation_distance", config_.trajectory_smoothing_activation_distance);
85 get_parameter<double>("stopping_location_buffer", config_.stopping_location_buffer);
86 get_parameter<double>("green_light_time_buffer", config_.green_light_time_buffer);
87 get_parameter<double>("algo_minimum_speed", config_.algo_minimum_speed);
88 get_parameter<double>("deceleration_fraction", config_.deceleration_fraction);
89 get_parameter<double>("desired_distance_to_stop_buffer", config_.desired_distance_to_stop_buffer);
90 get_parameter<double>("min_maneuver_planning_period", config_.min_maneuver_planning_period);
91 get_parameter<std::string>("strategic_plugin_name", config_.strategic_plugin_name);
92 get_parameter<std::string>("lane_following_plugin_name", config_.lane_following_plugin_name);
93 get_parameter<std::string>("stop_and_wait_plugin_name", config_.stop_and_wait_plugin_name);
94 get_parameter<std::string>("intersection_transit_plugin_name", config_.intersection_transit_plugin_name);
95 get_parameter<bool>("enable_carma_streets_connection", config_.enable_carma_streets_connection);
96 get_parameter<double>("mobility_rate", config_.mobility_rate);
97 get_parameter<std::string>("vehicle_id", config_.vehicle_id);
98
103
104 // clang-format on
105
106 // Register runtime parameter update callback
107 add_on_set_parameters_callback(std::bind(&LCIStrategicPlugin::parameter_update_callback, this, std_ph::_1));
108
109 RCLCPP_INFO_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Done loading parameters: " << config_);
110
112
113 // Mobility Operation Subscriber
114 mob_operation_sub_ = create_subscription<carma_v2x_msgs::msg::MobilityOperation>("incoming_mobility_operation", 1,
115 std::bind(&LCIStrategicPlugin::mobilityOperationCb,this,std_ph::_1));
116
117 // BSM subscriber
118 bsm_sub_ = create_subscription<carma_v2x_msgs::msg::BSM>("bsm_outbound", 1,
119 std::bind(&LCIStrategicPlugin::BSMCb,this,std_ph::_1));
120
121 // set world model point form wm listener
123
124 // Setup publishers
125 mobility_operation_pub_ = create_publisher<carma_v2x_msgs::msg::MobilityOperation>("outgoing_mobility_operation", 1);
126 case_pub_ = create_publisher<std_msgs::msg::Int8>("lci_strategic_plugin/ts_case_num", 1);
127 tf_distance_pub_ = create_publisher<std_msgs::msg::Float64>("lci_strategic_plugin/distance_remaining_to_tf", 1);
128 earliest_et_pub_ = create_publisher<std_msgs::msg::Float64>("lci_strategic_plugin/earliest_entry_time", 1);
129 et_pub_ = create_publisher<std_msgs::msg::Float64>("lci_strategic_plugin/scheduled_entry_time", 1);
130
131 // Return success if everything initialized successfully
132 return CallbackReturn::SUCCESS;
133}
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...
void lookupFrontBumperTransform()
Lookup transfrom from front bumper to base link.
void mobilityOperationCb(carma_v2x_msgs::msg::MobilityOperation::UniquePtr msg)
callback function for mobility operation
carma_ros2_utils::PubPtr< std_msgs::msg::Float64 > tf_distance_pub_
carma_ros2_utils::SubPtr< carma_v2x_msgs::msg::MobilityOperation > mob_operation_sub_
carma_ros2_utils::SubPtr< carma_v2x_msgs::msg::BSM > bsm_sub_
carma_ros2_utils::PubPtr< std_msgs::msg::Int8 > case_pub_
void BSMCb(carma_v2x_msgs::msg::BSM::UniquePtr msg)
BSM callback function.
carma_ros2_utils::PubPtr< std_msgs::msg::Float64 > earliest_et_pub_
carma_ros2_utils::PubPtr< carma_v2x_msgs::msg::MobilityOperation > mobility_operation_pub_
rcl_interfaces::msg::SetParametersResult parameter_update_callback(const std::vector< rclcpp::Parameter > &parameters)
Callback for dynamic parameter updates.
carma_ros2_utils::PubPtr< std_msgs::msg::Float64 > et_pub_

References lci_strategic_plugin::LCIStrategicPluginConfig::algo_minimum_speed, bsm_sub_, BSMCb(), case_pub_, config_, lci_strategic_plugin::LCIStrategicPluginConfig::deceleration_fraction, lci_strategic_plugin::LCIStrategicPluginConfig::desired_distance_to_stop_buffer, earliest_et_pub_, emergency_decel_norm_, lci_strategic_plugin::LCIStrategicPluginConfig::enable_carma_streets_connection, et_pub_, carma_guidance_plugins::PluginBaseNode::get_world_model(), lci_strategic_plugin::LCIStrategicPluginConfig::green_light_time_buffer, lci_strategic_plugin::LCIStrategicPluginConfig::intersection_transit_plugin_name, lci_strategic_plugin::LCIStrategicPluginConfig::lane_following_plugin_name, lookupFrontBumperTransform(), max_comfort_accel_, max_comfort_decel_, max_comfort_decel_norm_, lci_strategic_plugin::LCIStrategicPluginConfig::min_approach_distance, lci_strategic_plugin::LCIStrategicPluginConfig::min_maneuver_planning_period, mob_operation_sub_, mobility_operation_pub_, lci_strategic_plugin::LCIStrategicPluginConfig::mobility_rate, mobilityOperationCb(), parameter_update_callback(), lci_strategic_plugin::LCIStrategicPluginConfig::stop_and_wait_plugin_name, lci_strategic_plugin::LCIStrategicPluginConfig::stopping_location_buffer, lci_strategic_plugin::LCIStrategicPluginConfig::strategic_plugin_name, tf_distance_pub_, lci_strategic_plugin::LCIStrategicPluginConfig::trajectory_smoothing_activation_distance, lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_accel_limit, lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_accel_limit_multiplier, lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_decel_limit, lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_decel_limit_multiplier, lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_id, and wm_.

Here is the call graph for this function:

◆ parameter_update_callback()

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

Callback for dynamic parameter updates.

Definition at line 135 of file lci_strategic_plugin.cpp.

136{
137 auto error_double = update_params<double>({
138 {"vehicle_acceleration_limit", config_.vehicle_accel_limit},
139 {"vehicle_deceleration_limit", config_.vehicle_decel_limit},
140 {"vehicle_decel_limit_multiplier", config_.vehicle_decel_limit_multiplier},
141 {"vehicle_accel_limit_multiplier", config_.vehicle_accel_limit_multiplier},
142 {"min_approach_distance", config_.min_approach_distance},
143 {"trajectory_smoothing_activation_distance", config_.trajectory_smoothing_activation_distance},
144 {"stopping_location_buffer", config_.stopping_location_buffer},
145 {"green_light_time_buffer", config_.green_light_time_buffer},
146 {"algo_minimum_speed", config_.algo_minimum_speed},
147 {"deceleration_fraction", config_.deceleration_fraction},
148 {"desired_distance_to_stop_buffer", config_.desired_distance_to_stop_buffer},
149 {"min_maneuver_planning_period", config_.min_maneuver_planning_period},
150 {"mobility_rate", config_.mobility_rate},
151 }, parameters);
152
153 rcl_interfaces::msg::SetParametersResult result;
154
155 result.successful = !error_double;
156
157 return result;
158}

References lci_strategic_plugin::LCIStrategicPluginConfig::algo_minimum_speed, config_, lci_strategic_plugin::LCIStrategicPluginConfig::deceleration_fraction, lci_strategic_plugin::LCIStrategicPluginConfig::desired_distance_to_stop_buffer, lci_strategic_plugin::LCIStrategicPluginConfig::green_light_time_buffer, lci_strategic_plugin::LCIStrategicPluginConfig::min_approach_distance, lci_strategic_plugin::LCIStrategicPluginConfig::min_maneuver_planning_period, lci_strategic_plugin::LCIStrategicPluginConfig::mobility_rate, lci_strategic_plugin::LCIStrategicPluginConfig::stopping_location_buffer, lci_strategic_plugin::LCIStrategicPluginConfig::trajectory_smoothing_activation_distance, lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_accel_limit, lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_accel_limit_multiplier, lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_decel_limit, and lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_decel_limit_multiplier.

Referenced by on_configure_plugin().

Here is the caller graph for this function:

◆ parseStrategyParams()

void lci_strategic_plugin::LCIStrategicPlugin::parseStrategyParams ( const std::string &  strategy_params)

parse strategy parameters

Parameters
strategy_paramsinput string of strategy params from mob op msg

Definition at line 1178 of file lci_strategic_plugin.cpp.

1179{
1180 // sample strategy_params: "et:1634067059"
1181 std::string params = strategy_params;
1182 std::vector<std::string> inputsParams;
1183 boost::algorithm::split(inputsParams, params, boost::is_any_of(","));
1184
1185 std::vector<std::string> et_parsed;
1186 boost::algorithm::split(et_parsed, inputsParams[0], boost::is_any_of(":"));
1187 auto new_scheduled_enter_time = std::stoull(et_parsed[1]);
1188
1189 if (scheduled_enter_time_ != new_scheduled_enter_time) //reset green buffer cache so it can be re-evaluated
1191
1192 scheduled_enter_time_ = new_scheduled_enter_time;
1193 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "scheduled_enter_time_: " << scheduled_enter_time_);
1194
1195}

References nearest_green_entry_time_cached_, scheduled_enter_time_, and process_traj_logs::split.

Referenced by mobilityOperationCb().

Here is the caller graph for this function:

◆ plan_maneuvers_callback()

void lci_strategic_plugin::LCIStrategicPlugin::plan_maneuvers_callback ( std::shared_ptr< rmw_request_id_t >  srv_header,
carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr  req,
carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr  resp 
)
virtual

Service callback for arbitrator maneuver planning.

Parameters
reqPlan maneuver request
respPlan maneuver response with a list of maneuver plan
Returns
If service call successed

Implements carma_guidance_plugins::StrategicPlugin.

Definition at line 1262 of file lci_strategic_plugin.cpp.

1266{
1267 std::chrono::system_clock::time_point execution_start_time = std::chrono::system_clock::now(); // Start timing the execution time for planning so it can be logged
1268
1269 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "<<<<<<<<<<<<<<<<< STARTING LCI_STRATEGIC_PLAN!!!!!!!!! >>>>>>>>>>>>>>>>");
1270
1271 if (!wm_->getRoute())
1272 {
1273 RCLCPP_ERROR_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Could not plan maneuvers as route was not available");
1274 return;
1275 }
1276
1278 {
1280 {
1281 resp->new_plan.maneuvers = {};
1282 RCLCPP_WARN_STREAM(rclcpp::get_logger("lci_strategic_plugin"),"Not approaching light-controlled intersection so no maneuvers");
1283 return;
1284 }
1285
1286 bool is_empty_schedule_msg = (scheduled_enter_time_ == 0);
1287 if (is_empty_schedule_msg)
1288 {
1289 resp->new_plan.maneuvers = {};
1290 RCLCPP_WARN_STREAM(rclcpp::get_logger("lci_strategic_plugin"),"Receiving empty schedule message");
1291 return;
1292 }
1293 }
1294
1295 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Finding car information");
1296
1297 // Extract vehicle data from request
1298 VehicleState current_state = extractInitialState(req);
1299 if (transition_table_.getState() != TransitState::UNAVAILABLE && !req->prior_plan.maneuvers.empty())
1300 {
1301 RCLCPP_WARN_STREAM(rclcpp::get_logger("lci_strategic_plugin"),"State is NOT UNAVAILABLE AND Maneuvers in request is NOT empty");
1302 return;
1303 }
1304 // Get current traffic light information
1305 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "\n\nFinding traffic_light information");
1306
1307 auto inter_list = wm_->getSignalizedIntersectionsAlongRoute({ req->veh_x, req->veh_y });
1308 auto upcoming_id_= inter_list.front()->id();
1309
1310 auto traffic_list = wm_->getSignalsAlongRoute({ req->veh_x, req->veh_y });
1311
1312 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Found traffic lights of size: " << traffic_list.size());
1313
1314 auto current_lanelets = wm_->getLaneletsFromPoint({ req->veh_x, req->veh_y});
1315 lanelet::ConstLanelet current_lanelet;
1316
1317 if (current_lanelets.empty())
1318 {
1319 RCLCPP_ERROR_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Given vehicle position is not on the road! Returning...");
1320 return;
1321 }
1322
1323 // get the lanelet that is on the route in case overlapping ones found
1324 auto llt_on_route_optional = wm_->getFirstLaneletOnShortestPath(current_lanelets);
1325
1326 if (llt_on_route_optional){
1327 current_lanelet = llt_on_route_optional.value();
1328 }
1329 else{
1330 RCLCPP_WARN_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "When identifying the corresponding lanelet for requested maneuever's state, x: "
1331 << req->veh_x << ", y: " << req->veh_y << ", no possible lanelet was found to be on the shortest path."
1332 << "Picking arbitrary lanelet: " << current_lanelets[0].id() << ", instead");
1333 current_lanelet = current_lanelets[0];
1334 }
1335
1336 lanelet::CarmaTrafficSignalPtr nearest_traffic_signal = nullptr;
1337
1338 lanelet::ConstLanelet entry_lanelet;
1339 lanelet::ConstLanelet exit_lanelet;
1340
1341 for (auto signal : traffic_list)
1342 {
1343 auto optional_entry_exit = wm_->getEntryExitOfSignalAlongRoute(signal);
1344 // if signal is not matching our destination skip
1345 if (!optional_entry_exit)
1346 {
1347 RCLCPP_ERROR_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Did not find entry.exit along the route");
1348 continue;
1349 }
1350
1351 entry_lanelet = optional_entry_exit.get().first;
1352 exit_lanelet = optional_entry_exit.get().second;
1353
1354 nearest_traffic_signal = signal;
1355 break;
1356 }
1357
1358
1359 TransitState prev_state;
1360
1361 do
1362 {
1363 // Clear previous maneuvers planned by this plugin as guard against state change since each state generates an
1364 // independent set of maneuvers
1365 resp->new_plan = carma_planning_msgs::msg::ManeuverPlan();
1366
1367 prev_state = transition_table_.getState(); // Cache previous state to check if state has changed after 1 iteration
1368
1369 RCLCPP_INFO_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Planning in state: " << transition_table_.getState());
1370
1371 boost::optional<std::pair<boost::posix_time::ptime, lanelet::CarmaTrafficSignalState>> current_light_state_optional = boost::none;
1372 if (nearest_traffic_signal)
1373 {
1374 current_light_state_optional = nearest_traffic_signal->predictState(lanelet::time::timeFromSec(current_state.stamp.seconds()));
1375 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Real-time current signal: " << current_light_state_optional.get().second << ", for Id: " << nearest_traffic_signal->id());
1376 if (current_light_state_optional.get().second == lanelet::CarmaTrafficSignalState::UNAVAILABLE || !current_light_state_optional)
1377 {
1378 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Signal state not available returning..." );
1379 return;
1380 }
1381 }
1382 switch (transition_table_.getState())
1383 {
1385 planWhenUNAVAILABLE(req, resp, current_state, nearest_traffic_signal, entry_lanelet, exit_lanelet, current_lanelet);
1386 break;
1387
1389 planWhenAPPROACHING(req, resp, current_state, nearest_traffic_signal, entry_lanelet, exit_lanelet, current_lanelet);
1390 break;
1391
1393 planWhenWAITING(req, resp, current_state, nearest_traffic_signal, entry_lanelet, exit_lanelet, current_lanelet);
1394 break;
1395
1397 // Reset intersection state since we are no longer in an intersection
1399 {
1400 throw std::invalid_argument("State is DEPARTING but the intersection variables are not available");
1401 }
1402 planWhenDEPARTING(req, resp, current_state, intersection_end_downtrack_.get(), intersection_speed_.get());
1403 break;
1404
1405 default:
1406 throw std::invalid_argument("LCIStrategic Strategic Plugin entered unknown state");
1407 break;
1408 }
1409
1410 } while (transition_table_.getState() != prev_state); // If the state has changed then continue looping
1411
1412 std::chrono::system_clock::time_point execution_end_time = std::chrono::system_clock::now(); // Planning complete
1413
1414 auto execution_duration = execution_end_time - execution_start_time;
1415 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "ExecutionTime lci_strategic_plugin: " << std::chrono::duration<double>(execution_duration).count());
1416
1417 return;
1418 // We need to evaluate the events so the state transitions can be triggered
1419}
VehicleState extractInitialState(carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req) const
Helper method to extract the initial vehicle state from the planning request method based on if the p...
void planWhenDEPARTING(carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, const VehicleState &current_state, double intersection_end_downtrack, double intersection_speed_limit)
Method for performing maneuver planning when the current plugin state is TransitState::DEPARTING Ther...
void planWhenWAITING(carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, const VehicleState &current_state, const lanelet::CarmaTrafficSignalPtr &traffic_light, const lanelet::ConstLanelet &entry_lanelet, const lanelet::ConstLanelet &exit_lanelet, const lanelet::ConstLanelet &current_lanelet)
Method for performing maneuver planning when the current plugin state is TransitState::WAITING Theref...
void planWhenUNAVAILABLE(carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, const VehicleState &current_state, const lanelet::CarmaTrafficSignalPtr &traffic_light, const lanelet::ConstLanelet &entry_lanelet, const lanelet::ConstLanelet &exit_lanelet, const lanelet::ConstLanelet &current_lanelet)
Method for performing maneuver planning when the current plugin state is TransitState::UNAVAILABLE Th...
void planWhenAPPROACHING(carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, const VehicleState &current_state, const lanelet::CarmaTrafficSignalPtr &traffic_light, const lanelet::ConstLanelet &entry_lanelet, const lanelet::ConstLanelet &exit_lanelet, const lanelet::ConstLanelet &current_lanelet)
Method for performing maneuver planning when the current plugin state is TransitState::APPROACHING Th...
LCIStrategicStateTransitionTable transition_table_
State Machine Transition table.
TransitState getState() const
Returns the current state.
TransitState
Enum describing the possible states of the LCIStrategic Strategic Plugin.
Definition: lci_states.hpp:25

References lci_strategic_plugin::APPROACHING, approaching_light_controlled_intersection_, config_, lci_strategic_plugin::DEPARTING, lci_strategic_plugin::LCIStrategicPluginConfig::enable_carma_streets_connection, extractInitialState(), lci_strategic_plugin::LCIStrategicStateTransitionTable::getState(), intersection_end_downtrack_, intersection_speed_, planWhenAPPROACHING(), planWhenDEPARTING(), planWhenUNAVAILABLE(), planWhenWAITING(), scheduled_enter_time_, lci_strategic_plugin::LCIStrategicPlugin::VehicleState::stamp, transition_table_, lci_strategic_plugin::UNAVAILABLE, upcoming_id_, lci_strategic_plugin::WAITING, and wm_.

Here is the call graph for this function:

◆ planWhenAPPROACHING()

void lci_strategic_plugin::LCIStrategicPlugin::planWhenAPPROACHING ( carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr  req,
carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr  resp,
const VehicleState current_state,
const lanelet::CarmaTrafficSignalPtr &  traffic_light,
const lanelet::ConstLanelet &  entry_lanelet,
const lanelet::ConstLanelet &  exit_lanelet,
const lanelet::ConstLanelet &  current_lanelet 
)
private

Method for performing maneuver planning when the current plugin state is TransitState::APPROACHING Therefore the planned maneuvers deal with approaching a traffic light.

Parameters
reqPlan maneuver request
[out]respPlan maneuver response with a list of maneuver plan
current_stateThe current state of the vehicle at the start of planning
traffic_lightThe single traffic light along the vehicle's route in the intersection that is relevant and in front of the vehicle
entry_laneletThe entry lanelet into the intersection
exit_laneletThe exit lanelet into the intersection
current_laneletThe current lanelet the vehicle's state is on
Exceptions
ifgiven entry_lanelet doesn't have stop_line or speed profile case number was failed to be calculated NOTE: if there is empty traffic_light, it signals that the vehicle has crossed the bar, or if invalid light state is given

Definition at line 812 of file lci_strategic_plugin.cpp.

815{
817
818 if (!traffic_light) // If we are in the approaching state and there is no longer any lights ahead of us then
819 // the vehicle must have crossed the stop bar
820 {
822 return;
823 }
824
825 double current_state_speed = std::max(current_state.speed, config_.algo_minimum_speed * 1.001);
826
827 auto stop_line = traffic_light->getStopLine(entry_lanelet);
828
829 if (!stop_line)
830 {
831 throw std::invalid_argument("Given entry lanelet doesn't have stop_line...");
832 }
833
834 double traffic_light_down_track =
835 wm_->routeTrackPos(stop_line.get().front().basicPoint2d()).downtrack;
836
837 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "traffic_light_down_track: " << traffic_light_down_track);
838
839 double distance_remaining_to_traffic_light = traffic_light_down_track - current_state.downtrack;
840
841 distance_remaining_to_tf_ = distance_remaining_to_traffic_light;
842
843 if (distance_remaining_to_traffic_light < 0) // there is small discrepancy between signal's routeTrackPos as well as current
844 { // downtrack calculated using veh_x,y from state. Therefore, it may have crossed it
845 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Crossed the bar distance_remaining_to_traffic_light: " << distance_remaining_to_traffic_light);
847 return;
848 }
849
850 // At this point we know the vehicle is within the activation distance and we know the current and next light phases
851 // All we need to now determine is if we should stop or if we should continue
852 lanelet::ConstLanelet intersection_lanelet;
853
854 auto route = wm_->getRoute()->shortestPath();
855 auto entry_llt_iter = std::find(route.begin(), route.end(), entry_lanelet);
856 if (entry_llt_iter != route.end())
857 {
858 intersection_lanelet = *(entry_llt_iter + 1);
859 }
860
861 if (intersection_lanelet.id() != lanelet::InvalId)
862 {
863 intersection_speed_ = findSpeedLimit(intersection_lanelet);
865 }
866 else
867 {
868 intersection_speed_ = findSpeedLimit(exit_lanelet);
869 }
870
871 intersection_speed_ = intersection_speed_.get() * 0.999; // so that speed_limit is not exactly same as departure or current speed
872
873 double speed_limit = findSpeedLimit(current_lanelet);
874
875 current_state_speed = std::min(current_state_speed, speed_limit - 5 * epsilon_); // so that current_speed is not exactly same as departure or speed limit
876
877 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "current_state_speed: " << current_state_speed);
878 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "intersection_speed_: " << intersection_speed_.get());
879 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "distance_remaining_to_traffic_light: " << distance_remaining_to_traffic_light);
880
882 wm_->routeTrackPos(exit_lanelet.centerline2d().front().basicPoint2d()).downtrack;
883
884 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "intersection_end_downtrack_: " << intersection_end_downtrack_.get());
885
886 // If the vehicle is at a stop trigger the stopped state
887 constexpr double HALF_MPH_IN_MPS = 0.22352;
888 if (current_state.speed < HALF_MPH_IN_MPS &&
889 fabs(distance_remaining_to_traffic_light) < config_.stopping_location_buffer)
890 {
891 transition_table_.signal(TransitEvent::STOPPED); // The vehicle has come to a stop at the light
892 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "CARMA has detected that the vehicle stopped at the stop bar. Transitioning to WAITING STATE");
893
894 return;
895 }
896
898
899 rclcpp::Time earliest_entry_time = current_state.stamp + get_earliest_entry_time(distance_remaining_to_traffic_light, speed_limit,
900 current_state_speed, intersection_speed_.get(), max_comfort_accel_, max_comfort_decel_);
901
902 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "earliest_entry_time: " << std::to_string(earliest_entry_time.seconds()) << ", with : " << std::to_string((earliest_entry_time - current_state.stamp).seconds()) << " left at: " << std::to_string(current_state.stamp.seconds()));
903
904 auto [nearest_green_entry_time, is_entry_time_within_green_or_tbd, in_tbd] = get_final_entry_time_and_conditions(current_state, earliest_entry_time, traffic_light);
905
906 if (nearest_green_entry_time == rclcpp::Time(0))
907 return;
908
909 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Final nearest_green_entry_time: " << std::to_string(nearest_green_entry_time.seconds()));
910
911 auto et_state = traffic_light->predictState(lanelet::time::timeFromSec(nearest_green_entry_time.seconds()));
912 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Signal at ET: " << et_state.get().second);
913
915
916 double remaining_time = nearest_green_entry_time.seconds() - current_state.stamp.seconds();
917 double remaining_time_earliest_entry = earliest_entry_time.seconds() - current_state.stamp.seconds();
918 scheduled_entry_time_ = remaining_time; // performance metric
919 earliest_entry_time_ = remaining_time_earliest_entry; // performance metric
920
921 auto boundary_distances = get_delta_x(current_state_speed, intersection_speed_.get(), speed_limit, config_.algo_minimum_speed, max_comfort_accel_, max_comfort_decel_);
922 print_boundary_distances(boundary_distances); //debug
923
924 auto boundary_traj_params = get_boundary_traj_params(rclcpp::Time(req->header.stamp, RCL_SYSTEM_TIME).seconds(), current_state_speed, intersection_speed_.get(), speed_limit, config_.algo_minimum_speed, max_comfort_accel_, max_comfort_decel_, current_state.downtrack, traffic_light_down_track, distance_remaining_to_traffic_light, boundary_distances);
925
926 TrajectoryParams ts_params = get_ts_case(rclcpp::Time(req->header.stamp, RCL_SYSTEM_TIME).seconds(), nearest_green_entry_time.seconds(), current_state_speed, intersection_speed_.get(), speed_limit, config_.algo_minimum_speed, max_comfort_accel_, max_comfort_decel_, current_state.downtrack, traffic_light_down_track, distance_remaining_to_traffic_light, boundary_distances, boundary_traj_params);
927 print_params(ts_params);
928
929 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "SPEED PROFILE CASE:" << ts_params.case_num);
930
932 double emergency_distance_to_stop = pow(current_state.speed, 2)/(2 * emergency_decel_norm_) + config_.stopping_location_buffer / 2; //Idea is to aim the middle part of stopping buffer
933 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "emergency_distance_to_stop at emergency_decel_norm_ (with stopping_location_buffer/2): " << emergency_distance_to_stop << ", emergency_decel_norm_: " << emergency_decel_norm_);
934
935 double safe_distance_to_stop = pow(current_state.speed, 2)/(2 * max_comfort_decel_norm_) + config_.stopping_location_buffer / 2; //Idea is to aim the middle part of stopping buffer
936 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "safe_distance_to_stop at max_comfort_decel (with stopping_location_buffer/2): " << safe_distance_to_stop << ", max_comfort_decel_norm_: " << max_comfort_decel_norm_);
937
938 double desired_distance_to_stop = pow(current_state.speed, 2)/(2 * max_comfort_decel_norm_ * config_.deceleration_fraction) + config_.desired_distance_to_stop_buffer;
939 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "desired_distance_to_stop at: " << desired_distance_to_stop << ", where effective deceleration rate is: " << max_comfort_decel_norm_ * config_.deceleration_fraction);
940
941 emergency_distance_to_stop = std::max(emergency_distance_to_stop, config_.stopping_location_buffer);
942 safe_distance_to_stop = std::max(safe_distance_to_stop, config_.stopping_location_buffer);
943 desired_distance_to_stop = std::max(desired_distance_to_stop, config_.stopping_location_buffer);
944
945 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "new emergency_distance_to_stop: " << emergency_distance_to_stop);
946 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "new safe_distance_to_stop: " << safe_distance_to_stop);
947 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "new desired_distance_to_stop: " << desired_distance_to_stop);
948
949 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "distance_remaining_to_traffic_light: " << distance_remaining_to_traffic_light << ", current_state.speed: " << current_state.speed);
950
951 // Basic RED signal violation check
952 if (distance_remaining_to_traffic_light <= emergency_distance_to_stop || last_case_num_ == TSCase::EMERGENCY_STOPPING)
953 {
954 if (in_tbd) // Given ET is in TBD, but vehicle is too close to intersection
955 {
956 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "ET is still in TBD despite the vehicle being in desired distance to start stopping. Trying to handle this edge case gracefully...");
957 }
958
959 double stopping_time = current_state.speed / 1.5 / max_comfort_decel_norm_; //one half the acceleration (twice the acceleration to stop) to account for emergency case, see emergency_decel_norm_
960
961 rclcpp::Time stopping_arrival_time =
962 current_state.stamp + rclcpp::Duration(stopping_time * 1e9);
963
964 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "stopping_arrival_time: " << std::to_string(stopping_arrival_time.seconds()));
965
966 auto stopping_arrival_state_optional = traffic_light->predictState(lanelet::time::timeFromSec(stopping_arrival_time.seconds()));
967
968 if (!validLightState(stopping_arrival_state_optional, stopping_arrival_time))
969 {
970 RCLCPP_ERROR_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Unable to resolve give signal for stopping_arrival_state_optional: " << std::to_string(stopping_arrival_time.seconds()));
971 return;
972 }
973
974 if (stopping_arrival_state_optional.get().second == lanelet::CarmaTrafficSignalState::STOP_AND_REMAIN || last_case_num_ == TSCase::EMERGENCY_STOPPING) // if once started emergency stopped, keep doing it to avoid jerkiness
975 {
976 RCLCPP_WARN_STREAM(rclcpp::get_logger("lci_strategic_plugin"),"Detected possible RED light violation! Stopping!");
977 handleStopping(req,resp, current_state, traffic_light, entry_lanelet, exit_lanelet, current_lanelet, traffic_light_down_track, true); //case_11
979
980 return;
981 }
982 }
983
984 // Check if the vehicle can arrive with certainty (Case 1-7)
985 if (ts_params.is_algorithm_successful && ts_params.case_num != TSCase::CASE_8 &&
986 (distance_remaining_to_traffic_light >= desired_distance_to_stop || !in_tbd) &&
987 is_entry_time_within_green_or_tbd) // ET cannot be explicitly inside RED or YELLOW in available future states, which is ERROR case
988 {
989 handleGreenSignalScenario(req, resp, current_state, current_state_speed, traffic_light, entry_lanelet, exit_lanelet, traffic_light_down_track, ts_params, in_tbd); //in_tbd means optional to check certainty arrival at green
990
991 if (!resp->new_plan.maneuvers.empty()) // able to pass at green
992 {
993 last_case_num_ = ts_params.case_num;
994 return;
995 }
996
997 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Not able to make it with certainty: TSCase: " << ts_params.case_num << ", changing it to 8");
998 ts_params = boundary_traj_params[7];
999 ts_params.is_algorithm_successful = true; //false correspond to cases when vehicle is beyond safe_distance to stop for case8
1000 ts_params.case_num = CASE_8;
1001 print_params(ts_params);
1002 }
1003
1004 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Not able to make it with certainty: NEW TSCase: " << ts_params.case_num);
1005 // if algorithm is NOT successful or if the vehicle cannot make the green light with certainty
1006
1007 if (desired_distance_to_stop < distance_remaining_to_traffic_light && last_case_num_ != TSCase::STOPPING) // do not switch from STOPPING to case8 again
1008 {
1009 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Way too early to stop. Cruising at CASE8");
1010 handleCruisingUntilStop(req, resp, current_state, current_state_speed, traffic_light, traffic_light_down_track, ts_params);
1011
1012 if (!resp->new_plan.maneuvers.empty())
1013 {
1015 return;
1016 }
1017 }
1018
1019 if ((safe_distance_to_stop <= distance_remaining_to_traffic_light && desired_distance_to_stop >= distance_remaining_to_traffic_light) ||
1020 last_case_num_ == TSCase::STOPPING) // if stopping continue stopping until transition to planwhenWAITING
1021 {
1022 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Planning stopping now. last case:" << static_cast<int>(last_case_num_));
1023 handleStopping(req,resp, current_state, traffic_light, entry_lanelet, exit_lanelet, current_lanelet, traffic_light_down_track); //case_9
1024 return;
1025 }
1026
1027 if (safe_distance_to_stop > distance_remaining_to_traffic_light)
1028 {
1029 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "No longer within safe distance to stop! Decide to continue stopping or continue into intersection");
1030
1031 if (last_case_num_ != TSCase::STOPPING && last_case_num_ != TSCase::UNAVAILABLE && last_case_num_ != TSCase::CASE_8) //case 1-7 or emergency stop or handlefailure
1032 {
1033 // 3. if not able to stop nor reach target speed at green, attempt its best to reach the target parameters at the intersection
1034 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "HANDLE_LAST_RESORT: The vehicle is not able to stop at red/yellow light nor is able to reach target speed at green. Attempting its best to pass through at green!");
1035
1036 handleFailureCase(req, resp, current_state, current_state_speed, speed_limit, remaining_time,
1037 exit_lanelet.id(), traffic_light, traffic_light_down_track, ts_params);
1038
1039 if (resp->new_plan.maneuvers.empty())
1040 {
1041 RCLCPP_WARN_STREAM(rclcpp::get_logger("lci_strategic_plugin"),"HANDLE_SAFETY: Planning forced slow-down... last case:" << static_cast<int>(last_case_num_));
1042 handleStopping(req,resp, current_state, traffic_light, entry_lanelet, exit_lanelet, current_lanelet, traffic_light_down_track, true); //case_11 emergency case with twice the normal deceleration
1043 }
1044 }
1045 else
1046 {
1047 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "HANDLE_SAFETY: Planning to keep stopping now. last case:" << static_cast<int>(last_case_num_));
1048 handleStopping(req,resp, current_state, traffic_light, entry_lanelet, exit_lanelet, current_lanelet, traffic_light_down_track); //case_9
1049 }
1050 }
1051
1052
1053}
void handleStopping(carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, const VehicleState &current_state, const lanelet::CarmaTrafficSignalPtr &traffic_light, const lanelet::ConstLanelet &entry_lanelet, const lanelet::ConstLanelet &exit_lanelet, const lanelet::ConstLanelet &current_lanelet, double traffic_light_down_track, bool is_emergency=false)
This function returns stopping maneuver if the vehicle is able to stop at red and in safe stopping di...
void handleGreenSignalScenario(carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, const VehicleState &current_state, double current_state_speed, const lanelet::CarmaTrafficSignalPtr &traffic_light, const lanelet::ConstLanelet &entry_lanelet, const lanelet::ConstLanelet &exit_lanelet, double traffic_light_down_track, const TrajectoryParams &ts_params, bool is_certainty_check_optional)
This function returns valid maneuvers if the vehicle is able to utilize trajectory smoothing paramete...
BoundaryDistances get_delta_x(double v0, double v1, double v_max, double v_min, double a_max, double a_min)
Get boundary distances used to compare against current state in order to create trajectory smoothing ...
double findSpeedLimit(const lanelet::ConstLanelet &llt) const
Given a Lanelet, find it's associated Speed Limit.
rclcpp::Duration get_earliest_entry_time(double remaining_distance, double free_flow_speed, double current_speed, double departure_speed, double max_accel, double max_decel) const
Gets the earliest entry time into the intersection that is kinematically possible for the vehicle....
void handleFailureCase(carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, const VehicleState &current_state, double current_state_speed, double speed_limit, double remaining_time, lanelet::Id exit_lanelet_id, const lanelet::CarmaTrafficSignalPtr &traffic_light, double traffic_light_down_track, const TrajectoryParams &ts_params)
When the vehicle is not able to successfully run the algorithm or not able to stop,...
std::tuple< rclcpp::Time, bool, bool > get_final_entry_time_and_conditions(const VehicleState &current_state, const rclcpp::Time &earliest_entry_time, lanelet::CarmaTrafficSignalPtr traffic_light)
Get the final entry time from either vehicle's own internal ET calculation (TSMO UC2) or from carma-s...
TrajectoryParams get_ts_case(double t, double et, double v0, double v1, double v_max, double v_min, double a_max, double a_min, double x0, double x_end, double dx, BoundaryDistances boundary_distances, std::vector< TrajectoryParams > params)
void handleCruisingUntilStop(carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, const VehicleState &current_state, double current_state_speed, const lanelet::CarmaTrafficSignalPtr &traffic_light, double traffic_light_down_track, const TrajectoryParams &ts_params)
This function returns valid maneuvers if the vehicle is able to utilize trajectory smoothing paramete...
TurnDirection getTurnDirectionAtIntersection(std::vector< lanelet::ConstLanelet > lanelets_list)
Determine the turn direction at intersection.
std::vector< TrajectoryParams > get_boundary_traj_params(double t, double v0, double v1, double v_max, double v_min, double a_max, double a_min, double x0, double x_end, double dx, BoundaryDistances boundary_distances)
Get all possible trajectory smoothing parameters for each segments. Later this will be used to genera...
void print_boundary_distances(BoundaryDistances delta_xs)
Helper method to print TrajectoryParams.
void signal(TransitEvent signal)
Trigger signal for the transition table.

References lci_strategic_plugin::LCIStrategicPluginConfig::algo_minimum_speed, lci_strategic_plugin::CASE_8, lci_strategic_plugin::TrajectoryParams::case_num, config_, lci_strategic_plugin::CROSSED_STOP_BAR, lci_strategic_plugin::LCIStrategicPluginConfig::deceleration_fraction, lci_strategic_plugin::LCIStrategicPluginConfig::desired_distance_to_stop_buffer, distance_remaining_to_tf_, lci_strategic_plugin::LCIStrategicPlugin::VehicleState::downtrack, earliest_entry_time_, emergency_decel_norm_, lci_strategic_plugin::EMERGENCY_STOPPING, epsilon_, findSpeedLimit(), get_boundary_traj_params(), get_delta_x(), get_earliest_entry_time(), get_final_entry_time_and_conditions(), get_ts_case(), getTurnDirectionAtIntersection(), handleCruisingUntilStop(), handleFailureCase(), handleGreenSignalScenario(), handleStopping(), intersection_end_downtrack_, intersection_speed_, intersection_turn_direction_, lci_strategic_plugin::TrajectoryParams::is_algorithm_successful, last_case_num_, max_comfort_accel_, max_comfort_decel_, max_comfort_decel_norm_, print_boundary_distances(), print_params(), scheduled_entry_time_, lci_strategic_plugin::LCIStrategicStateTransitionTable::signal(), lci_strategic_plugin::LCIStrategicPlugin::VehicleState::speed, lci_strategic_plugin::LCIStrategicPlugin::VehicleState::stamp, lci_strategic_plugin::STOPPED, lci_strategic_plugin::STOPPING, lci_strategic_plugin::LCIStrategicPluginConfig::stopping_location_buffer, carma_cooperative_perception::to_string(), transition_table_, lci_strategic_plugin::UNAVAILABLE, validLightState(), and wm_.

Referenced by plan_maneuvers_callback().

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

◆ planWhenDEPARTING()

void lci_strategic_plugin::LCIStrategicPlugin::planWhenDEPARTING ( carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr  req,
carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr  resp,
const VehicleState current_state,
double  intersection_end_downtrack,
double  intersection_speed_limit 
)
private

Method for performing maneuver planning when the current plugin state is TransitState::DEPARTING Therefor the planned maneuvers deal with the transit of the intersection once the stop bar has been crossed.

Parameters
reqPlan maneuver request
[out]respPlan maneuver response with a list of maneuver plan
current_stateThe current state of the vehicle at the start of planning
intersection_end_downtrackThe ending downtrack in meters of the current intersection
intersection_speed_limitThe speed limit of the current intersection

Definition at line 1122 of file lci_strategic_plugin.cpp.

1125{
1127
1128 if (current_state.downtrack > intersection_end_downtrack)
1129 {
1130 transition_table_.signal(TransitEvent::INTERSECTION_EXIT); // If we are past the most recent
1131 return;
1132 }
1133
1134 // Calculate exit time assuming constant acceleration
1135 rclcpp::Time intersection_exit_time =
1136 current_state.stamp +
1137 rclcpp::Duration(2.0 * (intersection_end_downtrack - current_state.downtrack) / (current_state.speed + intersection_speed_limit) * 1e9);
1138
1139 // Identify the lanelets which will be crossed by approach maneuvers lane follow maneuver
1140 std::vector<lanelet::ConstLanelet> crossed_lanelets =
1141 getLaneletsBetweenWithException(current_state.downtrack, intersection_end_downtrack, true, false);
1142
1143 // Compose intersection transit maneuver
1144 resp->new_plan.maneuvers.push_back(composeIntersectionTransitMessage(
1145 current_state.downtrack, intersection_end_downtrack, current_state.speed, intersection_speed_limit,
1146 current_state.stamp, intersection_exit_time, crossed_lanelets.back().id(), crossed_lanelets.back().id()));
1147}

References composeIntersectionTransitMessage(), lci_strategic_plugin::LCIStrategicPlugin::VehicleState::downtrack, getLaneletsBetweenWithException(), lci_strategic_plugin::INTERSECTION_EXIT, last_case_num_, lci_strategic_plugin::LCIStrategicStateTransitionTable::signal(), lci_strategic_plugin::LCIStrategicPlugin::VehicleState::speed, lci_strategic_plugin::LCIStrategicPlugin::VehicleState::stamp, transition_table_, and lci_strategic_plugin::UNAVAILABLE.

Referenced by plan_maneuvers_callback().

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

◆ planWhenUNAVAILABLE()

void lci_strategic_plugin::LCIStrategicPlugin::planWhenUNAVAILABLE ( carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr  req,
carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr  resp,
const VehicleState current_state,
const lanelet::CarmaTrafficSignalPtr &  traffic_light,
const lanelet::ConstLanelet &  entry_lanelet,
const lanelet::ConstLanelet &  exit_lanelet,
const lanelet::ConstLanelet &  current_lanelet 
)
private

Method for performing maneuver planning when the current plugin state is TransitState::UNAVAILABLE Therefor no maneuvers are planned but the system checks for the precense of traffic lights ahead of it.

Parameters
reqPlan maneuver request
[out]respPlan maneuver response with a list of maneuver plan
current_stateThe current state of the vehicle at the start of planning
traffic_lightThe single traffic light along the vehicle's route in the intersection that is relevant and in front of the vehicle
entry_laneletThe entry lanelet into the intersection
exit_laneletThe exit lanelet into the intersection
current_laneletThe current lanelet the vehicle's state is on
Exceptions
ifgiven entry_lanelet doesn't have stop_line NOTE: returns empty if the given traffic light is empty

Definition at line 742 of file lci_strategic_plugin.cpp.

745{
746 // Reset intersection state since in this state we are not yet known to be in or approaching an intersection
747 intersection_speed_ = boost::none;
748 intersection_end_downtrack_ = boost::none;
749 double current_state_speed = std::max(current_state.speed, config_.algo_minimum_speed * 1.001);
750
751
752 if (!traffic_light)
753 {
754 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "No lights found along route. Returning maneuver plan unchanged");
755 return;
756 }
757
759 double max_comfort_decel = -1.0 * config_.vehicle_decel_limit * config_.vehicle_decel_limit_multiplier;
760
761 auto stop_line = traffic_light->getStopLine(entry_lanelet);
762
763 if (!stop_line)
764 {
765 throw std::invalid_argument("Given entry lanelet doesn't have stop_line...");
766 }
767
768 double traffic_light_down_track =
769 wm_->routeTrackPos(stop_line.get().front().basicPoint2d()).downtrack;
770
771 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "traffic_light_down_track: " << traffic_light_down_track);
772
773 double distance_remaining_to_traffic_light = traffic_light_down_track - current_state.downtrack;
774
775 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "distance_remaining_to_traffic_light: " << distance_remaining_to_traffic_light <<
776 ", current_state.downtrack: " << current_state.downtrack);
777
778 distance_remaining_to_tf_ = distance_remaining_to_traffic_light; // performance metric
779
780 auto speed_limit = findSpeedLimit(current_lanelet);
781
782 current_state_speed = std::min(speed_limit, current_state_speed);
783
784 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "speed_limit (free flow speed): " << speed_limit);
785
786 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "trajectory_smoothing_activation_distance: " << config_.trajectory_smoothing_activation_distance);
787
788 double stopping_dist = estimate_distance_to_stop(current_state_speed, config_.vehicle_decel_limit_multiplier *
789 config_.vehicle_decel_limit); //accepts positive decel
790
791 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Stopping distance: " << stopping_dist);
792
793 double plugin_activation_distance = std::max(stopping_dist, config_.min_approach_distance);
794
795 plugin_activation_distance = std::max(plugin_activation_distance, config_.trajectory_smoothing_activation_distance);
796
797 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "plugin_activation_distance: " << plugin_activation_distance);
798
799 if (distance_remaining_to_traffic_light <= plugin_activation_distance)
800 {
801 RCLCPP_INFO_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Within intersection range");
802 transition_table_.signal(TransitEvent::IN_STOPPING_RANGE); // Evaluate Signal and Run Trajectory Smoothing Algorithm
803 }
804 else
805 {
807 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Not within intersection range");
808 }
809
810}
double estimate_distance_to_stop(double v, double a) const
Helper method to use basic kinematics to compute an estimated stopping distance from from the inputs.

References lci_strategic_plugin::LCIStrategicPluginConfig::algo_minimum_speed, config_, distance_remaining_to_tf_, lci_strategic_plugin::LCIStrategicPlugin::VehicleState::downtrack, estimate_distance_to_stop(), findSpeedLimit(), lci_strategic_plugin::IN_STOPPING_RANGE, intersection_end_downtrack_, intersection_speed_, last_case_num_, lci_strategic_plugin::LCIStrategicPluginConfig::min_approach_distance, lci_strategic_plugin::LCIStrategicStateTransitionTable::signal(), lci_strategic_plugin::LCIStrategicPlugin::VehicleState::speed, lci_strategic_plugin::LCIStrategicPluginConfig::trajectory_smoothing_activation_distance, transition_table_, lci_strategic_plugin::UNAVAILABLE, lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_accel_limit, lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_accel_limit_multiplier, lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_decel_limit, lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_decel_limit_multiplier, and wm_.

Referenced by plan_maneuvers_callback().

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

◆ planWhenWAITING()

void lci_strategic_plugin::LCIStrategicPlugin::planWhenWAITING ( carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr  req,
carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr  resp,
const VehicleState current_state,
const lanelet::CarmaTrafficSignalPtr &  traffic_light,
const lanelet::ConstLanelet &  entry_lanelet,
const lanelet::ConstLanelet &  exit_lanelet,
const lanelet::ConstLanelet &  current_lanelet 
)
private

Method for performing maneuver planning when the current plugin state is TransitState::WAITING Therefor the planned maneuvers deal with waiting at a red light.

Parameters
reqPlan maneuver request
[out]respPlan maneuver response with a list of maneuver plan
current_stateThe current state of the vehicle at the start of planning
traffic_lightThe single traffic light along the vehicle's route in the intersection that is relevant and in front of the vehicle
entry_laneletThe entry lanelet into the intersection
exit_laneletThe exit lanelet into the intersection
current_laneletThe current lanelet the vehicle's state is on NOTE: returns empty if the given traffic light is empty

Definition at line 1055 of file lci_strategic_plugin.cpp.

1058{
1060
1061 if (!traffic_light)
1062 {
1063 throw std::invalid_argument("While in WAITING state, the traffic lights disappeared.");
1064 }
1065
1066 auto stop_line = traffic_light->getStopLine(entry_lanelet);
1067
1068 if (!stop_line)
1069 {
1070 throw std::invalid_argument("Given entry lanelet doesn't have stop_line...");
1071 }
1072
1073 double traffic_light_down_track =
1074 wm_->routeTrackPos(stop_line.get().front().basicPoint2d()).downtrack;
1075
1076 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "traffic_light_down_track: "<< traffic_light_down_track);
1077
1078 double entering_time = current_state.stamp.seconds();
1079
1080 auto current_light_state_optional = traffic_light->predictState(lanelet::time::timeFromSec(entering_time));
1081
1082 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "WAITING STATE: requested time to rclcpp::Time(req->header.stamp, RCL_SYSTEM_TIME) check: " << std::to_string(rclcpp::Time(req->header.stamp, RCL_SYSTEM_TIME).seconds()));
1083 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "WAITING STATE: requested time to CURRENT STATE check: " << std::to_string(entering_time));
1084
1085 if (!validLightState(current_light_state_optional, rclcpp::Time(entering_time * 1e9)))
1086 return;
1087
1088 auto bool_optional_late_certainty = canArriveAtGreenWithCertainty(rclcpp::Time(entering_time * 1e9), traffic_light, true, false);
1089
1090 if (!bool_optional_late_certainty)
1091 {
1092 RCLCPP_ERROR_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "Unable to resolve green light...");
1093 return;
1094 }
1095
1096 bool should_enter = true; //uc2
1097
1098 if (config_.enable_carma_streets_connection && entering_time > current_state.stamp.seconds()) //uc3
1099 should_enter = false;
1100
1101 if (current_light_state_optional.get().second == lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED &&
1102 bool_optional_late_certainty.get() && should_enter) // if can make with certainty
1103 {
1104 transition_table_.signal(TransitEvent::RED_TO_GREEN_LIGHT); // If the light is green send the light transition
1105 // signal
1106 return;
1107 }
1108
1109 // A fixed buffer to add to stopping maneuvers once the vehicle is already stopped to ensure that they can have their
1110 // trajectory planned
1111 constexpr double stop_maneuver_buffer = 10.0;
1112
1113 // If the light is not green then continue waiting by creating a stop and wait maneuver on top of the vehicle
1115
1116 resp->new_plan.maneuvers.push_back(composeStopAndWaitManeuverMessage(
1117 current_state.downtrack - stop_maneuver_buffer, traffic_light_down_track, current_state.speed,
1118 current_state.lane_id, current_state.lane_id, rclcpp::Time(entering_time * 1e9),
1119 rclcpp::Time(entering_time * 1e9) + rclcpp::Duration(config_.min_maneuver_planning_period * 1e9), stopping_accel));
1120}

References canArriveAtGreenWithCertainty(), composeStopAndWaitManeuverMessage(), config_, lci_strategic_plugin::LCIStrategicPlugin::VehicleState::downtrack, lci_strategic_plugin::LCIStrategicPluginConfig::enable_carma_streets_connection, lci_strategic_plugin::LCIStrategicPlugin::VehicleState::lane_id, last_case_num_, lci_strategic_plugin::LCIStrategicPluginConfig::min_maneuver_planning_period, lci_strategic_plugin::RED_TO_GREEN_LIGHT, lci_strategic_plugin::LCIStrategicStateTransitionTable::signal(), lci_strategic_plugin::LCIStrategicPlugin::VehicleState::speed, lci_strategic_plugin::LCIStrategicPlugin::VehicleState::stamp, lci_strategic_plugin::STOPPING, carma_cooperative_perception::to_string(), transition_table_, validLightState(), lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_decel_limit, lci_strategic_plugin::LCIStrategicPluginConfig::vehicle_decel_limit_multiplier, and wm_.

Referenced by plan_maneuvers_callback().

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

◆ print_boundary_distances()

void lci_strategic_plugin::LCIStrategicPlugin::print_boundary_distances ( BoundaryDistances  delta_xs)
private

Helper method to print TrajectoryParams.

Definition at line 494 of file lci_strategic_plugin_algo.cpp.

495{
496 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "\n");
497 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "dx1: " << delta_xs.dx1);
498 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "dx2: " << delta_xs.dx2);
499 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "dx3: " << delta_xs.dx3);
500 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "dx4: " << delta_xs.dx4);
501 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "dx5: " << delta_xs.dx5 << "\n");
502}

References lci_strategic_plugin::BoundaryDistances::dx1, lci_strategic_plugin::BoundaryDistances::dx2, lci_strategic_plugin::BoundaryDistances::dx3, lci_strategic_plugin::BoundaryDistances::dx4, and lci_strategic_plugin::BoundaryDistances::dx5.

Referenced by planWhenAPPROACHING().

Here is the caller graph for this function:

◆ print_params()

void lci_strategic_plugin::LCIStrategicPlugin::print_params ( TrajectoryParams  params)
private

Helper method to print TrajectoryParams.

Definition at line 469 of file lci_strategic_plugin_algo.cpp.

470{
471 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "\n");
472 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "t0: " << std::to_string(params.t0_));
473 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "v0: " << params.v0_);
474 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "x0: " << params.x0_);
475
476 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "t1: " << std::to_string(params.t1_));
477 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "v1: " << params.v1_);
478 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "x1: " << params.x1_);
479 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "a1: " << params.a1_);
480
481 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "t2: " << std::to_string(params.t2_));
482 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "v2: " << params.v2_);
483 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "x2: " << params.x2_);
484 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "a2: " << params.a2_);
485
486 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "t3: " << std::to_string(params.t3_));
487 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "v3: " << params.v3_);
488 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "x3: " << params.x3_);
489 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "a3: " << params.a3_);
490
491 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "\n");
492}

References lci_strategic_plugin::TrajectoryParams::a1_, lci_strategic_plugin::TrajectoryParams::a2_, lci_strategic_plugin::TrajectoryParams::a3_, lci_strategic_plugin::TrajectoryParams::t0_, lci_strategic_plugin::TrajectoryParams::t1_, lci_strategic_plugin::TrajectoryParams::t2_, lci_strategic_plugin::TrajectoryParams::t3_, carma_cooperative_perception::to_string(), lci_strategic_plugin::TrajectoryParams::v0_, lci_strategic_plugin::TrajectoryParams::v1_, lci_strategic_plugin::TrajectoryParams::v2_, lci_strategic_plugin::TrajectoryParams::v3_, lci_strategic_plugin::TrajectoryParams::x0_, lci_strategic_plugin::TrajectoryParams::x1_, lci_strategic_plugin::TrajectoryParams::x2_, and lci_strategic_plugin::TrajectoryParams::x3_.

Referenced by handleFailureCaseHelper(), and planWhenAPPROACHING().

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

◆ publishMobilityOperation()

void lci_strategic_plugin::LCIStrategicPlugin::publishMobilityOperation ( )

Publish mobility operation at a fixed rate.

Definition at line 1251 of file lci_strategic_plugin.cpp.

1252{
1254 {
1255 carma_v2x_msgs::msg::MobilityOperation status_msg = generateMobilityOperation();
1256 mobility_operation_pub_->publish(status_msg);
1257 }
1258}
carma_v2x_msgs::msg::MobilityOperation generateMobilityOperation()
Generates Mobility Operation messages.

References approaching_light_controlled_intersection_, generateMobilityOperation(), and mobility_operation_pub_.

Referenced by on_activate_plugin().

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

◆ publishTrajectorySmoothingInfo()

void lci_strategic_plugin::LCIStrategicPlugin::publishTrajectorySmoothingInfo ( )

Publish trajectory smoothing info at a fixed rate.

Definition at line 160 of file lci_strategic_plugin.cpp.

161{
162 std_msgs::msg::Int8 case_num_msg;
163 std_msgs::msg::Float64 tf_distance;
164 std_msgs::msg::Float64 earliest_et;
165 std_msgs::msg::Float64 scheduled_et;
166
167 case_num_msg.data = static_cast<int>(last_case_num_);
168 tf_distance.data = distance_remaining_to_tf_;
169 earliest_et.data = earliest_entry_time_;
170 scheduled_et.data = scheduled_entry_time_;
171
172 case_pub_->publish(case_num_msg);
173 tf_distance_pub_->publish(tf_distance);
174 earliest_et_pub_->publish(earliest_et);
175 et_pub_->publish(scheduled_et);
176}

References case_pub_, distance_remaining_to_tf_, earliest_entry_time_, earliest_et_pub_, et_pub_, last_case_num_, scheduled_entry_time_, and tf_distance_pub_.

Referenced by on_activate_plugin().

Here is the caller graph for this function:

◆ supportedLightState()

bool lci_strategic_plugin::LCIStrategicPlugin::supportedLightState ( lanelet::CarmaTrafficSignalState  state) const
private

Helper method to evaluate if the given traffic light state is supported by this plugin.

Parameters
stateThe state to evaluate
Returns
true if the state is supported, flase otherwise

Definition at line 191 of file lci_strategic_plugin.cpp.

192{
193 switch (state)
194 {
195 // NOTE: Following cases are intentional fall through.
196 // Supported light states
197 case lanelet::CarmaTrafficSignalState::STOP_AND_REMAIN: // Solid Red
198 case lanelet::CarmaTrafficSignalState::PROTECTED_CLEARANCE: // Yellow Solid no chance of conflicting traffic
199 case lanelet::CarmaTrafficSignalState::PROTECTED_MOVEMENT_ALLOWED: // Solid Green no chance of conflict traffic
200 // (normally used with arrows)
201 return true;
202
203 // Unsupported light states
204 case lanelet::CarmaTrafficSignalState::PERMISSIVE_MOVEMENT_ALLOWED: // Solid Green there could be conflict traffic
205 case lanelet::CarmaTrafficSignalState::PERMISSIVE_CLEARANCE: // Yellow Solid there is a chance of conflicting
206 // traffic
207 case lanelet::CarmaTrafficSignalState::UNAVAILABLE: // No data available
208 case lanelet::CarmaTrafficSignalState::DARK: // Light is non-functional
209 case lanelet::CarmaTrafficSignalState::STOP_THEN_PROCEED: // Flashing Red
210
211 case lanelet::CarmaTrafficSignalState::PRE_MOVEMENT: // Yellow Red transition (Found only in the EU)
212 // (normally used with arrows)
213 case lanelet::CarmaTrafficSignalState::CAUTION_CONFLICTING_TRAFFIC: // Yellow Flashing
214 default:
215 return false;
216 }
217}

References lci_strategic_plugin::UNAVAILABLE.

Referenced by validLightState().

Here is the caller graph for this function:

◆ ts_case1()

TrajectoryParams lci_strategic_plugin::LCIStrategicPlugin::ts_case1 ( double  t,
double  et,
double  v0,
double  v1,
double  v_max,
double  a_max,
double  a_min,
double  x0,
double  x_end,
double  dx 
)
private

Trajectory Smoothing Algorithm 8 cases. TSMO UC2, UC3 algorithm equations.

Definition at line 656 of file lci_strategic_plugin_algo.cpp.

657{
658 TrajectoryParams traj;
659
660 traj.t0_ = t;
661 traj.v0_ = v0;
662 traj.x0_ = x0;
663
664 double dt = et - t;
665 double nom1 = 2 * dx * (((1 - (a_max / a_min)) * v_max) + ((a_max / a_min) * v1) - v0);
666 double nom2 = dt * (((1 - (a_max / a_min)) * pow(v_max, 2)) + ((a_max / a_min) * pow(v1, 2)) - pow(v0, 2));
667 double den = pow(v_max - v0, 2) - ((a_max / a_min) * pow(v_max - v1, 2));
668
669 if (den <= epsilon_ && den >= -epsilon_)
670 throw std::invalid_argument("CASE1: Received den near zero..." + std::to_string(den));
671
672 double tc = (nom1 - nom2) / den;
673
674 traj.v1_ = v_max;
675
676 if (dt - tc <= epsilon_ && dt - tc >= -epsilon_)
677 throw std::invalid_argument("CASE1: Received dt - tc near zero..." + std::to_string(dt - tc));
678
679 traj.a1_ = (((1 - (a_max / a_min)) * v_max) + ((a_max / a_min) * v1) - v0) / (dt - tc);
680
681 if (traj.a1_ <= accel_epsilon_ && traj.a1_ >= -accel_epsilon_)
682 {
683 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "CASE1: Received traj.a1_ near zero...");
684 traj.t1_ = traj.t0_ + ((dt - tc) * (a_max / (a_min + a_max)));
685 traj.x1_ = traj.x0_ + (v_max * (traj.t1_ - traj.t0_));
686 }
687 else
688 {
689 traj.t1_ = traj.t0_ + ((traj.v1_ - traj.v0_) / traj.a1_);
690 traj.x1_ = traj.x0_ + ((pow(traj.v1_, 2) - pow(traj.v0_, 2)) / (2 * traj.a1_));
691 }
692 traj.a2_ = 0;
693 traj.v2_ = v_max;
694 traj.t2_ = traj.t1_ + tc;
695 traj.x2_ = traj.x1_ + (v_max * tc);
696
697 traj.t3_ = et;
698 traj.a3_ = traj.a1_ * (a_min / a_max);
699 traj.v3_ = v1;
700 traj.x3_ = x_end;
701
702 return traj;
703
704}

References lci_strategic_plugin::TrajectoryParams::a1_, lci_strategic_plugin::TrajectoryParams::a2_, lci_strategic_plugin::TrajectoryParams::a3_, accel_epsilon_, epsilon_, lci_strategic_plugin::TrajectoryParams::t0_, lci_strategic_plugin::TrajectoryParams::t1_, lci_strategic_plugin::TrajectoryParams::t2_, lci_strategic_plugin::TrajectoryParams::t3_, carma_cooperative_perception::to_string(), lci_strategic_plugin::TrajectoryParams::v0_, lci_strategic_plugin::TrajectoryParams::v1_, lci_strategic_plugin::TrajectoryParams::v2_, lci_strategic_plugin::TrajectoryParams::v3_, lci_strategic_plugin::TrajectoryParams::x0_, lci_strategic_plugin::TrajectoryParams::x1_, lci_strategic_plugin::TrajectoryParams::x2_, and lci_strategic_plugin::TrajectoryParams::x3_.

Referenced by get_ts_case().

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

◆ ts_case2()

TrajectoryParams lci_strategic_plugin::LCIStrategicPlugin::ts_case2 ( double  t,
double  et,
double  v0,
double  v1,
double  a_max,
double  a_min,
double  x0,
double  x_end,
double  dx 
)
private

Definition at line 705 of file lci_strategic_plugin_algo.cpp.

706{
707 TrajectoryParams traj;
708
709 traj.t0_ = t;
710 traj.v0_ = v0;
711 traj.x0_ = x0;
712
713 double dt = et - t;
714
715 if (dt <= epsilon_ && dt >= -epsilon_)
716 throw std::invalid_argument("CASE2: Received dt near zero..." + std::to_string(dt));
717
718 double sqr1 = pow(1 - (a_max / a_min), 2) * pow(dx / dt, 2);
719 double sqr2 = (1 - (a_max / a_min)) * (((a_max / a_min) * v1 * (v1 - (2 * dx / dt))) + (v0 * ((2 * dx / dt) - v0)));
720 double v_hat = (dx / dt) + (sqrt(sqr1 - sqr2) / (1 - (a_max / a_min)));
721
722 traj.v1_ = v_hat;
723 traj.a1_ = (((1 - (a_max / a_min)) * v_hat) + ((a_max / a_min) * v1) - v0) / dt;
724
725 if (traj.a1_ <= accel_epsilon_ && traj.a1_ >= -accel_epsilon_)
726 {
727 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "CASE2: Received traj.a1_ near zero...");
728 traj.t1_ = traj.t0_ + (dt * (a_max / (a_min + a_max)));
729 traj.x1_ = traj.x0_ + (v_hat * (traj.t1_ - traj.t0_));
730 }
731 else
732 {
733 traj.t1_ = traj.t0_ + ((traj.v1_ - traj.v0_) / traj.a1_);
734 traj.x1_ = traj.x0_ + ((pow(traj.v1_, 2) - pow(traj.v0_, 2)) / (2 * traj.a1_));
735 }
736
737 traj.v2_ = v1;
738 traj.a2_ = traj.a1_ * a_min / a_max;
739
740 if (traj.a2_ <= accel_epsilon_ && traj.a2_ >= -accel_epsilon_)
741 {
742 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "CASE2: Received traj.a2_ near zero...");
743 traj.t2_ = traj.t1_ + (dt * (a_min / (a_min + a_max)));
744 traj.x2_ = traj.x1_ + (v_hat * (traj.t2_ - traj.t1_));
745 }
746 else
747 {
748 traj.t2_ = traj.t1_ + ((traj.v2_ - traj.v1_) / traj.a2_);
749 traj.x2_ = x_end;
750 }
751
752 traj.t3_ = traj.t2_;
753 traj.a3_ = 0;
754 traj.v3_ = traj.v2_;
755 traj.x3_ = traj.x2_;
756
757 return traj;
758}

References lci_strategic_plugin::TrajectoryParams::a1_, lci_strategic_plugin::TrajectoryParams::a2_, lci_strategic_plugin::TrajectoryParams::a3_, accel_epsilon_, epsilon_, lci_strategic_plugin::TrajectoryParams::t0_, lci_strategic_plugin::TrajectoryParams::t1_, lci_strategic_plugin::TrajectoryParams::t2_, lci_strategic_plugin::TrajectoryParams::t3_, carma_cooperative_perception::to_string(), lci_strategic_plugin::TrajectoryParams::v0_, lci_strategic_plugin::TrajectoryParams::v1_, lci_strategic_plugin::TrajectoryParams::v2_, lci_strategic_plugin::TrajectoryParams::v3_, lci_strategic_plugin::TrajectoryParams::x0_, lci_strategic_plugin::TrajectoryParams::x1_, lci_strategic_plugin::TrajectoryParams::x2_, and lci_strategic_plugin::TrajectoryParams::x3_.

Referenced by get_ts_case().

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

◆ ts_case3()

TrajectoryParams lci_strategic_plugin::LCIStrategicPlugin::ts_case3 ( double  t,
double  et,
double  v0,
double  v1,
double  a_max,
double  a_min,
double  x0,
double  x_end,
double  dx 
)
private

Definition at line 759 of file lci_strategic_plugin_algo.cpp.

760{
761 TrajectoryParams traj;
762
763 traj.t0_ = t;
764 traj.v0_ = v0;
765 traj.x0_ = x0;
766
767 double dt = et - t;
768
769 if (dt <= epsilon_ && dt >= -epsilon_)
770 throw std::invalid_argument("CASE3: Received dt near zero..." + std::to_string(dt));
771
772 double sqr1 = pow((a_max / a_min) - 1, 2) * pow(dx / dt, 2);
773 double sqr2 = ((a_max / a_min) - 1) * ((v1 * (v1 - (2 * dx / dt))) + ((a_max / a_min) * v0 * ((2 * dx / dt) - v0)));
774 double v_hat = (dx / dt) + (sqrt(sqr1 - sqr2) / ((a_max / a_min) - 1));
775
776 traj.v1_ = v_hat;
777 traj.a1_ = (((1 - (a_min / a_max)) * v_hat) + ((a_min / a_max) * v1) - v0) / dt;
778
779 if (traj.a1_ <= accel_epsilon_ && traj.a1_ >= -accel_epsilon_)
780 {
781 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "CASE3: Received traj.a1_ near zero...");
782 traj.t1_ = traj.t0_ + (dt * (a_max / (a_min + a_max)));
783 traj.x1_ = traj.x0_ + (v_hat * (traj.t1_ - traj.t0_));
784 }
785 else
786 {
787 traj.t1_ = traj.t0_ + ((traj.v1_ - traj.v0_) / traj.a1_);
788 traj.x1_ = traj.x0_ + ((pow(traj.v1_, 2) - pow(traj.v0_, 2)) / (2 * traj.a1_));
789 }
790
791 traj.v2_ = v1;
792 traj.a2_ = traj.a1_ * a_max / a_min;
793 traj.t2_ = traj.t1_ + ((traj.v2_ - traj.v1_) / traj.a2_);
794 traj.x2_ = x_end;
795
796 traj.t3_ = traj.t2_;
797 traj.a3_ = 0;
798 traj.v3_ = traj.v2_;
799 traj.x3_ = traj.x2_;
800
801 return traj;
802}

References lci_strategic_plugin::TrajectoryParams::a1_, lci_strategic_plugin::TrajectoryParams::a2_, lci_strategic_plugin::TrajectoryParams::a3_, accel_epsilon_, epsilon_, lci_strategic_plugin::TrajectoryParams::t0_, lci_strategic_plugin::TrajectoryParams::t1_, lci_strategic_plugin::TrajectoryParams::t2_, lci_strategic_plugin::TrajectoryParams::t3_, carma_cooperative_perception::to_string(), lci_strategic_plugin::TrajectoryParams::v0_, lci_strategic_plugin::TrajectoryParams::v1_, lci_strategic_plugin::TrajectoryParams::v2_, lci_strategic_plugin::TrajectoryParams::v3_, lci_strategic_plugin::TrajectoryParams::x0_, lci_strategic_plugin::TrajectoryParams::x1_, lci_strategic_plugin::TrajectoryParams::x2_, and lci_strategic_plugin::TrajectoryParams::x3_.

Referenced by get_ts_case().

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

◆ ts_case4()

TrajectoryParams lci_strategic_plugin::LCIStrategicPlugin::ts_case4 ( double  t,
double  et,
double  v0,
double  v1,
double  v_min,
double  a_max,
double  a_min,
double  x0,
double  x_end,
double  dx 
)
private

Definition at line 803 of file lci_strategic_plugin_algo.cpp.

804{
805 TrajectoryParams traj;
806
807 traj.t0_ = t;
808 traj.v0_ = v0;
809 traj.x0_ = x0;
810
811 double dt = et - t;
812 double nom1 = 2 * dx * ((((a_max / a_min) - 1) * v_min) + v1 - ((a_max / a_min) * v0));
813 double nom2 = dt * ((((a_max / a_min) - 1) * pow(v_min, 2)) + pow(v1, 2) - ((a_max / a_min) * pow(v0, 2)));
814 double den = ((a_max / a_min) * pow(v_min - v0, 2)) - pow(v_min - v1, 2);
815
816 if (den <= epsilon_ && den >= -epsilon_)
817 throw std::invalid_argument("CASE4: Received den near zero..." + std::to_string(den));
818
819 double tc = (nom1 - nom2) / den;
820
821 traj.v1_ = v_min;
822
823 if (dt - tc <= epsilon_ && dt - tc >= -epsilon_)
824 throw std::invalid_argument("CASE4: Received dt - tc near zero..." + std::to_string(dt - tc));
825
826 traj.a1_ = (((1 - (a_min / a_max)) * v_min) + ((a_min / a_max) * v1) - v0) / (dt - tc);
827
828 if (traj.a1_ <= accel_epsilon_ && traj.a1_ >= -accel_epsilon_)
829 {
830 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "CASE4: Received traj.a1_ near zero...");
831 traj.t1_ = traj.t0_ + ((dt - tc) * (a_min / (a_min + a_max)));
832 traj.x1_ = traj.x0_ + (v_min * (traj.t1_ - traj.t0_));
833 }
834 else
835 {
836 traj.t1_ = traj.t0_ + ((traj.v1_ - traj.v0_) / traj.a1_);
837 traj.x1_ = traj.x0_ + ((pow(traj.v1_, 2) - pow(traj.v0_, 2)) / (2 * traj.a1_));
838 }
839
840 traj.v2_ = v_min;
841 traj.a2_ = 0;
842 traj.t2_ = traj.t1_ + tc;
843 traj.x2_ = traj.x1_ + (v_min * tc);
844
845 traj.t3_ = et;
846 traj.a3_ = traj.a1_ * a_max / a_min;
847 traj.v3_ = v1;
848 traj.x3_ = x_end;
849
850 return traj;
851}

References lci_strategic_plugin::TrajectoryParams::a1_, lci_strategic_plugin::TrajectoryParams::a2_, lci_strategic_plugin::TrajectoryParams::a3_, accel_epsilon_, epsilon_, lci_strategic_plugin::TrajectoryParams::t0_, lci_strategic_plugin::TrajectoryParams::t1_, lci_strategic_plugin::TrajectoryParams::t2_, lci_strategic_plugin::TrajectoryParams::t3_, carma_cooperative_perception::to_string(), lci_strategic_plugin::TrajectoryParams::v0_, lci_strategic_plugin::TrajectoryParams::v1_, lci_strategic_plugin::TrajectoryParams::v2_, lci_strategic_plugin::TrajectoryParams::v3_, lci_strategic_plugin::TrajectoryParams::x0_, lci_strategic_plugin::TrajectoryParams::x1_, lci_strategic_plugin::TrajectoryParams::x2_, and lci_strategic_plugin::TrajectoryParams::x3_.

Referenced by get_ts_case().

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

◆ ts_case5()

TrajectoryParams lci_strategic_plugin::LCIStrategicPlugin::ts_case5 ( double  t,
double  et,
double  v0,
double  a_max,
double  a_min,
double  x0,
double  x_end,
double  dx 
)
private

Definition at line 853 of file lci_strategic_plugin_algo.cpp.

854{
855 TrajectoryParams traj;
856
857 traj.t0_ = t;
858 traj.v0_ = v0;
859 traj.x0_ = x0;
860
861 double dt = et - t;
862 double sqr = ((a_max / a_min) - 1) * ((2 * a_min * (dx - (v0 * dt))) - pow(a_min * dt, 2));
863 double v_hat = (v0 + (a_min * dt)) - (sqrt(sqr) / ((a_max / a_min) - 1));
864 double v_p = ((1 - (a_max / a_min)) * v_hat) + ((a_max / a_min) * v0) + (a_max * dt);
865
866 traj.v1_ = v_hat;
867 traj.a1_ = a_min;
868
869 traj.t1_ = traj.t0_ + ((traj.v1_ - traj.v0_) / traj.a1_);
870 traj.x1_ = traj.x0_ + ((pow(traj.v1_, 2) - pow(traj.v0_, 2)) / (2 * traj.a1_));
871
872 traj.v2_ = v_p;
873 traj.a2_ = a_max;
874 traj.t2_ = traj.t1_ + ((traj.v2_ - traj.v1_) / traj.a2_);
875 traj.x2_ = x_end;
876
877 traj.t3_ = traj.t2_;
878 traj.a3_ = 0;
879 traj.v3_ = traj.v2_;
880 traj.x3_ = traj.x2_;
881
882 return traj;
883}

References lci_strategic_plugin::TrajectoryParams::a1_, lci_strategic_plugin::TrajectoryParams::a2_, lci_strategic_plugin::TrajectoryParams::a3_, lci_strategic_plugin::TrajectoryParams::t0_, lci_strategic_plugin::TrajectoryParams::t1_, lci_strategic_plugin::TrajectoryParams::t2_, lci_strategic_plugin::TrajectoryParams::t3_, lci_strategic_plugin::TrajectoryParams::v0_, lci_strategic_plugin::TrajectoryParams::v1_, lci_strategic_plugin::TrajectoryParams::v2_, lci_strategic_plugin::TrajectoryParams::v3_, lci_strategic_plugin::TrajectoryParams::x0_, lci_strategic_plugin::TrajectoryParams::x1_, lci_strategic_plugin::TrajectoryParams::x2_, and lci_strategic_plugin::TrajectoryParams::x3_.

Referenced by get_ts_case().

Here is the caller graph for this function:

◆ ts_case6()

TrajectoryParams lci_strategic_plugin::LCIStrategicPlugin::ts_case6 ( double  t,
double  et,
double  v0,
double  v_min,
double  a_min,
double  x0,
double  x_end,
double  dx,
double  dx3,
TrajectoryParams  traj6 
)
private

Definition at line 885 of file lci_strategic_plugin_algo.cpp.

886{
887 TrajectoryParams traj;
888
889 traj.t0_ = t;
890 traj.v0_ = v0;
891 traj.x0_ = x0;
892
893 double dt = et - t;
894
895 traj.v1_ = v_min;
896 traj.a1_ = a_min;
897 traj.t1_ = traj.t0_ + ((traj.v1_ - traj.v0_) / traj.a1_);
898 traj.x1_ = traj.x0_ + ((pow(traj.v1_, 2) - pow(traj.v0_, 2)) / (2 * traj.a1_));
899
900 double tc;
901
902 if (dx <= dx3)
903 tc = 0;
904 else
905 tc = traj6.t2_ - traj6.t1_;
906
907 traj.v2_ = v_min;
908 traj.a2_ = 0;
909 traj.t2_ = traj.t1_ + tc;
910 traj.x2_ = traj.x1_ + (v_min * tc);
911
912 double dt_p = dt - (traj.t1_ - traj.t0_) - tc;
913
914 if (dt_p <= epsilon_ && dt_p >= -epsilon_)
915 throw std::invalid_argument("CASE6: Received dt_p near zero..." + std::to_string(dt_p));
916
917 double v_p = ((2 * a_min * (dx - (v_min * tc))) - (pow(v_min, 2) - pow(v0, 2)) - (v_min * dt_p * a_min)) / (dt_p * a_min);
918
919 traj.v3_ = v_p;
920 traj.a3_ = (v_p - v_min) / dt_p;
921 traj.t3_ = et;
922 traj.x3_ = x_end;
923
924 return traj;
925}

References lci_strategic_plugin::TrajectoryParams::a1_, lci_strategic_plugin::TrajectoryParams::a2_, lci_strategic_plugin::TrajectoryParams::a3_, epsilon_, lci_strategic_plugin::TrajectoryParams::t0_, lci_strategic_plugin::TrajectoryParams::t1_, lci_strategic_plugin::TrajectoryParams::t2_, lci_strategic_plugin::TrajectoryParams::t3_, carma_cooperative_perception::to_string(), lci_strategic_plugin::TrajectoryParams::v0_, lci_strategic_plugin::TrajectoryParams::v1_, lci_strategic_plugin::TrajectoryParams::v2_, lci_strategic_plugin::TrajectoryParams::v3_, lci_strategic_plugin::TrajectoryParams::x0_, lci_strategic_plugin::TrajectoryParams::x1_, lci_strategic_plugin::TrajectoryParams::x2_, and lci_strategic_plugin::TrajectoryParams::x3_.

Referenced by get_ts_case().

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

◆ ts_case7()

TrajectoryParams lci_strategic_plugin::LCIStrategicPlugin::ts_case7 ( double  t,
double  et,
double  v0,
double  v_min,
double  a_min,
double  x0,
double  x_end,
double  dx 
)
private

Definition at line 927 of file lci_strategic_plugin_algo.cpp.

928{
929 TrajectoryParams traj;
930
931 traj.t0_ = t;
932 traj.v0_ = v0;
933 traj.x0_ = x0;
934
935 traj.v1_ = v_min;
936 traj.a1_ = a_min;
937 traj.t1_ = traj.t0_ + ((traj.v1_ - traj.v0_) / traj.a1_);
938 traj.x1_ = traj.x0_ + ((pow(traj.v1_, 2) - pow(traj.v0_, 2)) / (2 * traj.a1_));
939
940 double dt = et - t;
941 double v_p = v_min - sqrt(pow(v_min - v0, 2) - (2 * a_min * ((v_min * dt) - dx)));
942 double dt_p = (v_p - v_min) / a_min;
943
944 if (dt_p <= epsilon_ && dt_p >= -epsilon_)
945 throw std::invalid_argument("CASE7: Received dt_p near zero..." + std::to_string(dt_p));
946
947 double tc = dt - ((v_p - v0) / a_min);
948
949 traj.v2_ = v_min;
950 traj.a2_ = 0;
951 traj.t2_ = traj.t1_ + tc;
952 traj.x2_ = traj.x1_ + (v_min * tc);
953
954 traj.v3_ = v_p;
955 traj.a3_ = (v_p - v_min) / dt_p;
956 traj.t3_ = et;
957 traj.x3_ = x_end;
958
959 return traj;
960}

References lci_strategic_plugin::TrajectoryParams::a1_, lci_strategic_plugin::TrajectoryParams::a2_, lci_strategic_plugin::TrajectoryParams::a3_, epsilon_, lci_strategic_plugin::TrajectoryParams::t0_, lci_strategic_plugin::TrajectoryParams::t1_, lci_strategic_plugin::TrajectoryParams::t2_, lci_strategic_plugin::TrajectoryParams::t3_, carma_cooperative_perception::to_string(), lci_strategic_plugin::TrajectoryParams::v0_, lci_strategic_plugin::TrajectoryParams::v1_, lci_strategic_plugin::TrajectoryParams::v2_, lci_strategic_plugin::TrajectoryParams::v3_, lci_strategic_plugin::TrajectoryParams::x0_, lci_strategic_plugin::TrajectoryParams::x1_, lci_strategic_plugin::TrajectoryParams::x2_, and lci_strategic_plugin::TrajectoryParams::x3_.

Referenced by get_ts_case().

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

◆ ts_case8()

TrajectoryParams lci_strategic_plugin::LCIStrategicPlugin::ts_case8 ( double  dx,
double  dx5,
TrajectoryParams  traj8 
)
private

Definition at line 962 of file lci_strategic_plugin_algo.cpp.

963{
964 TrajectoryParams traj = traj8;
965 if (dx < dx5)
966 {
967 traj.is_algorithm_successful = false;
968 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "CASE8: Not within safe stopping distance originally planned!");
969 }
970 return traj;
971}

References lci_strategic_plugin::TrajectoryParams::is_algorithm_successful.

Referenced by get_ts_case().

Here is the caller graph for this function:

◆ validLightState()

bool lci_strategic_plugin::LCIStrategicPlugin::validLightState ( const boost::optional< std::pair< boost::posix_time::ptime, lanelet::CarmaTrafficSignalState > > &  optional_state,
const rclcpp::Time &  source_time 
) const
private

Helper method that checks both if the input optional light state is set and if the state it contains is supported via supportedLightState.

Parameters
optional_stateAn optional light state and its min_end_time pair. If this is unset the method will return false
source_timeThe time used to optain the optional light state. This is used for logging only
Returns
True if the optional is set and the contained state signal is supported. False otherwise

Definition at line 277 of file lci_strategic_plugin.cpp.

279{
280 if (!optional_state)
281 {
282 RCLCPP_WARN_STREAM(rclcpp::get_logger("lci_strategic_plugin"),"Traffic light data not available for source_time " << std::to_string(source_time.seconds()));
283 return false;
284 }
285
286 lanelet::CarmaTrafficSignalState light_state = optional_state.get().second;
287
288 if (!supportedLightState(light_state))
289 {
290 RCLCPP_ERROR_STREAM(rclcpp::get_logger("lci_strategic_plugin"), "LCIStrategic Plugin asked to handle CarmaTrafficSignalState: " << light_state
291 << " which is not supported.");
292 return false;
293 }
294
295 return true;
296}
bool supportedLightState(lanelet::CarmaTrafficSignalState state) const
Helper method to evaluate if the given traffic light state is supported by this plugin.

References supportedLightState(), and carma_cooperative_perception::to_string().

Referenced by canArriveAtGreenWithCertainty(), get_final_entry_time_and_conditions(), handleFailureCaseHelper(), planWhenAPPROACHING(), and planWhenWAITING().

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

Member Data Documentation

◆ accel_epsilon_

double lci_strategic_plugin::LCIStrategicPlugin::accel_epsilon_ = 0.0001
private

◆ approaching_light_controlled_intersection_

bool lci_strategic_plugin::LCIStrategicPlugin::approaching_light_controlled_intersection_ = false
private

◆ bsm_id_

std::string lci_strategic_plugin::LCIStrategicPlugin::bsm_id_ = "default_bsm_id"
private

Definition at line 208 of file lci_strategic_plugin.hpp.

Referenced by BSMCb(), and generateMobilityOperation().

◆ bsm_msg_count_

uint8_t lci_strategic_plugin::LCIStrategicPlugin::bsm_msg_count_ = 0
private

Definition at line 209 of file lci_strategic_plugin.hpp.

Referenced by BSMCb(), and generateMobilityOperation().

◆ bsm_sec_mark_

uint16_t lci_strategic_plugin::LCIStrategicPlugin::bsm_sec_mark_ = 0
private

Definition at line 210 of file lci_strategic_plugin.hpp.

Referenced by BSMCb(), and generateMobilityOperation().

◆ bsm_sub_

carma_ros2_utils::SubPtr<carma_v2x_msgs::msg::BSM> lci_strategic_plugin::LCIStrategicPlugin::bsm_sub_
private

Definition at line 264 of file lci_strategic_plugin.hpp.

Referenced by on_configure_plugin().

◆ case_pub_

carma_ros2_utils::PubPtr<std_msgs::msg::Int8> lci_strategic_plugin::LCIStrategicPlugin::case_pub_
private

◆ config_

◆ distance_remaining_to_tf_

double lci_strategic_plugin::LCIStrategicPlugin::distance_remaining_to_tf_ = 0.0
private

◆ earliest_entry_time_

double lci_strategic_plugin::LCIStrategicPlugin::earliest_entry_time_ = 0.0
private

◆ earliest_et_pub_

carma_ros2_utils::PubPtr<std_msgs::msg::Float64> lci_strategic_plugin::LCIStrategicPlugin::earliest_et_pub_
private

◆ emergency_decel_norm_

double lci_strategic_plugin::LCIStrategicPlugin::emergency_decel_norm_ = -2 * max_comfort_decel_
private

◆ epsilon_

◆ et_pub_

carma_ros2_utils::PubPtr<std_msgs::msg::Float64> lci_strategic_plugin::LCIStrategicPlugin::et_pub_
private

◆ frontbumper_transform_

tf2::Stamped<tf2::Transform> lci_strategic_plugin::LCIStrategicPlugin::frontbumper_transform_
private

Definition at line 249 of file lci_strategic_plugin.hpp.

◆ intersection_end_downtrack_

boost::optional<double> lci_strategic_plugin::LCIStrategicPlugin::intersection_end_downtrack_
private

◆ intersection_speed_

boost::optional<double> lci_strategic_plugin::LCIStrategicPlugin::intersection_speed_
private

Cache variables for storing the current intersection state between state machine transitions.

Definition at line 242 of file lci_strategic_plugin.hpp.

Referenced by handleFailureCase(), handleGreenSignalScenario(), plan_maneuvers_callback(), planWhenAPPROACHING(), and planWhenUNAVAILABLE().

◆ intersection_turn_direction_

TurnDirection lci_strategic_plugin::LCIStrategicPlugin::intersection_turn_direction_ = TurnDirection::Straight
private

Definition at line 232 of file lci_strategic_plugin.hpp.

Referenced by generateMobilityOperation(), and planWhenAPPROACHING().

◆ last_case_num_

TSCase lci_strategic_plugin::LCIStrategicPlugin::last_case_num_ = TSCase::UNAVAILABLE
private

Useful metrics for LCI Plugin.

Parameters
last_case_num_Current speed profile case generated
distance_remaining_to_tf_distance_remaining_to_traffic signal meters
earliest_entry_time_earliest_entry_time in sec
scheduled_entry_time_scheduled_entry_time in sec

Definition at line 227 of file lci_strategic_plugin.hpp.

Referenced by handleFailureCase(), handleStopping(), planWhenAPPROACHING(), planWhenDEPARTING(), planWhenUNAVAILABLE(), planWhenWAITING(), and publishTrajectorySmoothingInfo().

◆ length_to_front_bumper_

double lci_strategic_plugin::LCIStrategicPlugin::length_to_front_bumper_ = 3.0
private

Definition at line 250 of file lci_strategic_plugin.hpp.

Referenced by lookupFrontBumperTransform().

◆ light_controlled_intersection_strategy_

std::string lci_strategic_plugin::LCIStrategicPlugin::light_controlled_intersection_strategy_ = "Carma/signalized_intersection"
private

◆ max_comfort_accel_

double lci_strategic_plugin::LCIStrategicPlugin::max_comfort_accel_ = 2.0
private

◆ max_comfort_decel_

double lci_strategic_plugin::LCIStrategicPlugin::max_comfort_decel_ = -2.0
private

◆ max_comfort_decel_norm_

double lci_strategic_plugin::LCIStrategicPlugin::max_comfort_decel_norm_ = -1 * max_comfort_decel_
private

◆ mob_op_pub_timer_

rclcpp::TimerBase::SharedPtr lci_strategic_plugin::LCIStrategicPlugin::mob_op_pub_timer_
private

Definition at line 259 of file lci_strategic_plugin.hpp.

Referenced by on_activate_plugin().

◆ mob_operation_sub_

carma_ros2_utils::SubPtr<carma_v2x_msgs::msg::MobilityOperation> lci_strategic_plugin::LCIStrategicPlugin::mob_operation_sub_
private

Definition at line 263 of file lci_strategic_plugin.hpp.

Referenced by on_configure_plugin().

◆ mobility_operation_pub_

carma_ros2_utils::PubPtr<carma_v2x_msgs::msg::MobilityOperation> lci_strategic_plugin::LCIStrategicPlugin::mobility_operation_pub_
private

Definition at line 267 of file lci_strategic_plugin.hpp.

Referenced by on_configure_plugin(), and publishMobilityOperation().

◆ nearest_green_entry_time_cached_

boost::optional<rclcpp::Time> lci_strategic_plugin::LCIStrategicPlugin::nearest_green_entry_time_cached_
private

◆ previous_strategy_params_

std::string lci_strategic_plugin::LCIStrategicPlugin::previous_strategy_params_ = ""
private

Definition at line 204 of file lci_strategic_plugin.hpp.

Referenced by mobilityOperationCb().

◆ scheduled_enter_time_

unsigned long long lci_strategic_plugin::LCIStrategicPlugin::scheduled_enter_time_ = 0
private

◆ scheduled_entry_time_

double lci_strategic_plugin::LCIStrategicPlugin::scheduled_entry_time_ = 0.0
private

◆ street_msg_timestamp_

unsigned long long lci_strategic_plugin::LCIStrategicPlugin::street_msg_timestamp_ = 0
private

Definition at line 201 of file lci_strategic_plugin.hpp.

Referenced by mobilityOperationCb().

◆ tf2_buffer_

tf2_ros::Buffer lci_strategic_plugin::LCIStrategicPlugin::tf2_buffer_
private

Definition at line 247 of file lci_strategic_plugin.hpp.

Referenced by lookupFrontBumperTransform().

◆ tf2_listener_

std::unique_ptr<tf2_ros::TransformListener> lci_strategic_plugin::LCIStrategicPlugin::tf2_listener_
private

Definition at line 248 of file lci_strategic_plugin.hpp.

Referenced by lookupFrontBumperTransform().

◆ tf_distance_pub_

carma_ros2_utils::PubPtr<std_msgs::msg::Float64> lci_strategic_plugin::LCIStrategicPlugin::tf_distance_pub_
private

◆ transition_table_

LCIStrategicStateTransitionTable lci_strategic_plugin::LCIStrategicPlugin::transition_table_
private

State Machine Transition table.

Definition at line 239 of file lci_strategic_plugin.hpp.

Referenced by plan_maneuvers_callback(), planWhenAPPROACHING(), planWhenDEPARTING(), planWhenUNAVAILABLE(), and planWhenWAITING().

◆ ts_info_pub_timer_

rclcpp::TimerBase::SharedPtr lci_strategic_plugin::LCIStrategicPlugin::ts_info_pub_timer_
private

Definition at line 260 of file lci_strategic_plugin.hpp.

Referenced by on_activate_plugin().

◆ upcoming_id_

std::string lci_strategic_plugin::LCIStrategicPlugin::upcoming_id_ = ""
private

Definition at line 205 of file lci_strategic_plugin.hpp.

Referenced by generateMobilityOperation(), and plan_maneuvers_callback().

◆ wm_


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