19#include <rclcpp/rclcpp.hpp>
21#include <std_msgs/msg/string.hpp>
22#include <std_srvs/srv/empty.hpp>
23#include <carma_planning_msgs/msg/plugin.hpp>
24#include <carma_planning_msgs/msg/upcoming_lane_change_status.hpp>
25#include <carma_planning_msgs/msg/route_state.hpp>
26#include <carma_planning_msgs/msg/guidance_state.hpp>
27#include <carma_v2x_msgs/msg/bsm.hpp>
28#include <carma_v2x_msgs/msg/emergency_vehicle_response.hpp>
29#include <carma_v2x_msgs/msg/bsm.hpp>
30#include <carma_v2x_msgs/msg/emergency_vehicle_ack.hpp>
31#include <carma_msgs/msg/ui_instructions.hpp>
32#include <geometry_msgs/msg/twist_stamped.hpp>
35#include <lanelet2_core/geometry/Lanelet.h>
36#include <lanelet2_extension/projection/local_frame_projector.h>
37#include <lanelet2_extension/io/autoware_osm_parser.h>
39#include <boost/format.hpp>
40#include <std_msgs/msg/bool.hpp>
41#include <unordered_map>
54#define GET_MANEUVER_PROPERTY(mvr, property)\
55 (((mvr).type == carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_LEFT_TURN ? (mvr).intersection_transit_left_turn_maneuver.property :\
56 ((mvr).type == carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_RIGHT_TURN ? (mvr).intersection_transit_right_turn_maneuver.property :\
57 ((mvr).type == carma_planning_msgs::msg::Maneuver::INTERSECTION_TRANSIT_STRAIGHT ? (mvr).intersection_transit_straight_maneuver.property :\
58 ((mvr).type == carma_planning_msgs::msg::Maneuver::LANE_CHANGE ? (mvr).lane_change_maneuver.property :\
59 ((mvr).type == carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING ? (mvr).lane_following_maneuver.property :\
60 ((mvr).type == carma_planning_msgs::msg::Maneuver::STOP_AND_WAIT ? (mvr).stop_and_wait_maneuver.property :\
61 throw std::invalid_argument("GET_MANEUVER_PROPERTY (property) called on maneuver with invalid type id " + std::to_string((mvr).type)))))))))
121 carma_ros2_utils::SubPtr<geometry_msgs::msg::TwistStamped>
twist_sub_;
127 carma_ros2_utils::SubPtr<carma_planning_msgs::msg::Route>
route_sub_;
143 boost::optional<lanelet::BasicPoint2d>
getErvPositionInMap(
const double& current_latitude,
const double& current_longitude);
152 lanelet::Optional<lanelet::routing::Route>
generateErvRoute(
double current_latitude,
double current_longitude,
153 std::vector<carma_v2x_msgs::msg::Position3D> erv_destination_points);
175 boost::optional<double>
getSecondsUntilPassing(lanelet::Optional<lanelet::routing::Route>& erv_future_route,
const lanelet::BasicPoint2d& erv_position_in_map,
176 const double& erv_current_speed, lanelet::ConstLanelet& intersecting_lanelet);
246 rclcpp::Duration
getManeuverDuration(
const carma_planning_msgs::msg::Maneuver &maneuver,
double epsilon)
const;
259 double start_speed,
double target_speed,
int lanelet_id, rclcpp::Time& start_time)
const;
273 double start_speed,
double target_speed, lanelet::Id starting_lane_id, lanelet::Id ending_lane_id, rclcpp::Time& start_time)
const;
287 lanelet::Id starting_lane_id, lanelet::Id ending_lane_id,
double stopping_deceleration, rclcpp::Time& start_time)
const;
307 double downtrack_progress,
double stop_maneuver_beginning_downtrack,
double end_of_route_downtrack,
308 double stopping_entry_speed,
double stopping_deceleration,
double current_lanelet_ending_downtrack,
309 lanelet::ConstLanelet current_lanelet, rclcpp::Time time_progress);
328 lanelet::ConstLanelet current_lanelet,
double downtrack_progress,
double current_lanelet_ending_downtrack,
329 double speed_progress,
double target_speed, rclcpp::Time time_progress,
bool is_maintaining_non_reduced_speed);
348 lanelet::ConstLanelet current_lanelet,
double downtrack_progress,
double current_lanelet_ending_downtrack,
349 double speed_progress,
double target_speed, rclcpp::Time time_progress,
350 int ego_lane_index,
int erv_lane_index);
361 std::vector<lanelet::BasicPoint2d>
filter_points_ahead(
const lanelet::BasicPoint2d& reference_point,
const std::vector<lanelet::BasicPoint2d>& original_points)
const;
476 FRIEND_TEST(Testapproaching_emergency_vehicle_plugin, testStateMachineTransitions);
477 FRIEND_TEST(Testapproaching_emergency_vehicle_plugin, testBSMProcessing);
478 FRIEND_TEST(Testapproaching_emergency_vehicle_plugin, testRouteConflict);
479 FRIEND_TEST(Testapproaching_emergency_vehicle_plugin, testManeuverPlanWhenSlowingDownForErv);
480 FRIEND_TEST(Testapproaching_emergency_vehicle_plugin, testManeuverPlanWhenMovingOverForErv);
481 FRIEND_TEST(Testapproaching_emergency_vehicle_plugin, testWarningBroadcast);
482 FRIEND_TEST(Testapproaching_emergency_vehicle_plugin, testApproachingErvStatusMessage);
494 rcl_interfaces::msg::SetParametersResult
515 void routeCallback(carma_planning_msgs::msg::Route::UniquePtr msg);
534 void twistCallback(geometry_msgs::msg::TwistStamped::UniquePtr msg);
545 std::shared_ptr<rmw_request_id_t>,
546 carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req,
547 carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp)
override;
Class that implements the Approaching Emergency Vehicle Plugin (ERV) strategic plugin....
carma_ros2_utils::SubPtr< geometry_msgs::msg::TwistStamped > twist_sub_
bool has_broadcasted_warning_messages_
FRIEND_TEST(Testapproaching_emergency_vehicle_plugin, testManeuverPlanWhenSlowingDownForErv)
boost::optional< lanelet::ConstLanelet > getRouteIntersectingLanelet(const lanelet::routing::Route &erv_future_route)
Helper function to obtain the earliest lanelet that exists on both an ERV's future route and the ego ...
rcl_interfaces::msg::SetParametersResult parameter_update_callback(const std::vector< rclcpp::Parameter > ¶meters)
Callback for dynamic parameter updates.
carma_ros2_utils::SubPtr< carma_planning_msgs::msg::Route > route_sub_
void publishApproachingErvStatus()
This is a callback function for the approaching_emergency_vehicle_status_timer_. It makes a call to g...
rclcpp::Duration getManeuverDuration(const carma_planning_msgs::msg::Maneuver &maneuver, double epsilon) const
Helper function to obtain the (seconds) of a provided maneuver.
carma_ros2_utils::SubPtr< carma_v2x_msgs::msg::EmergencyVehicleAck > incoming_emergency_vehicle_ack_sub_
carma_ros2_utils::PubPtr< std_msgs::msg::Bool > hazard_light_cmd_pub_
carma_ros2_utils::CallbackReturn on_activate_plugin()
This method is used to create a timer and will be called on the activate transition.
void generateMoveOverManeuverPlan(carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, lanelet::ConstLanelet current_lanelet, double downtrack_progress, double current_lanelet_ending_downtrack, double speed_progress, double target_speed, rclcpp::Time time_progress, int ego_lane_index, int erv_lane_index)
Function to generate a maneuver plan when the ego vehicle must change lanes due to being in the MOVIN...
bool is_guidance_engaged_
boost::optional< std::string > map_projector_
lanelet::Optional< lanelet::routing::Route > generateErvRoute(double current_latitude, double current_longitude, std::vector< carma_v2x_msgs::msg::Position3D > erv_destination_points)
Helper function to generate an ERV's route based on its current position and its future route destina...
UpcomingLaneChangeParameters upcoming_lc_params_
carma_ros2_utils::SubPtr< carma_v2x_msgs::msg::BSM > incoming_bsm_sub_
void broadcastWarningToErv()
This is a callback function for the warning_broadcast_timer_, and is called to broadcast an Emergency...
std::shared_ptr< carma_wm::CARMAWorldModel > erv_world_model_
carma_planning_msgs::msg::Maneuver composeLaneFollowingManeuverMessage(double start_dist, double end_dist, double start_speed, double target_speed, int lanelet_id, rclcpp::Time &start_time) const
Function to compose a lane following maneuver message based on the provided maneuver parameters.
ApproachingEmergencyVehicleTransitionTable transition_table_
carma_ros2_utils::PubPtr< carma_msgs::msg::UIInstructions > approaching_erv_status_pub_
FRIEND_TEST(Testapproaching_emergency_vehicle_plugin, testManeuverPlanWhenMovingOverForErv)
void checkForErvTimeout()
This is a callback function for the erv_timeout_timer_ timer, and is called to determine whether a ti...
boost::optional< lanelet::ConstLanelet > getLaneletOnEgoRouteFromMapPosition(const double &x_position, const double &y_position)
Helper function to convert a map x,y coordinate pair to a lanelet on the ego vehicle's route.
const double MAINTAIN_SPEED_THRESHOLD
bool has_planned_upcoming_lc_
carma_ros2_utils::SubPtr< std_msgs::msg::String > georeference_sub_
void addStopAndWaitToEndOfPlan(carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, double downtrack_progress, double stop_maneuver_beginning_downtrack, double end_of_route_downtrack, double stopping_entry_speed, double stopping_deceleration, double current_lanelet_ending_downtrack, lanelet::ConstLanelet current_lanelet, rclcpp::Time time_progress)
Function to add a stop and wait maneuver to the end of the maneuver plan contained in the provided 'r...
carma_wm::WorldModelConstPtr wm_
ApproachingEmergencyVehiclePlugin(const rclcpp::NodeOptions &)
ApproachingEmergencyVehiclePlugin constructor.
bool get_availability() override
Get the availability status of this plugin based on the current operating environment....
carma_ros2_utils::CallbackReturn on_configure_plugin()
This method is used to load parameters and will be called on the configure state transition.
ErvInformation tracked_erv_
double non_reduced_speed_to_maintain_
carma_ros2_utils::PubPtr< carma_v2x_msgs::msg::EmergencyVehicleResponse > outgoing_emergency_vehicle_response_pub_
void routeStateCallback(carma_planning_msgs::msg::RouteState::UniquePtr msg)
Route State subscription callback, with is used to update this plugin's latest_route_state_ object.
void guidanceStateCallback(const carma_planning_msgs::msg::GuidanceState::UniquePtr msg)
Subscription callback to process the latest guidance state and update the is_guidance_engaged_ flag a...
void incomingEmergencyVehicleAckCallback(const carma_v2x_msgs::msg::EmergencyVehicleAck::UniquePtr msg)
Subscription callback for incoming EmergencyVehicleAck messages. If the message is from the currently...
carma_planning_msgs::msg::Maneuver composeStopAndWaitManeuverMessage(double start_dist, double end_dist, double start_speed, lanelet::Id starting_lane_id, lanelet::Id ending_lane_id, double stopping_deceleration, rclcpp::Time &start_time) const
Function to compose a stop and wait maneuver message based on the provided maneuver parameters.
boost::optional< double > getSecondsUntilPassing(lanelet::Optional< lanelet::routing::Route > &erv_future_route, const lanelet::BasicPoint2d &erv_position_in_map, const double &erv_current_speed, lanelet::ConstLanelet &intersecting_lanelet)
Helper function to calculate the estimated seconds until an ERV will pass the ego vehicle....
int num_warnings_broadcasted_
void generateReducedSpeedLaneFollowingeManeuverPlan(carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp, lanelet::ConstLanelet current_lanelet, double downtrack_progress, double current_lanelet_ending_downtrack, double speed_progress, double target_speed, rclcpp::Time time_progress, bool is_maintaining_non_reduced_speed)
Function to generate a maneuver plan when the ego vehicle must remain in its lane due to being in the...
std::unordered_map< std::string, bool > is_same_direction_
FRIEND_TEST(Testapproaching_emergency_vehicle_plugin, testStateMachineTransitions)
void publishHazardLightStatus()
This is a callback function for publishing turn ON/OFF (true/false) hazard light command to the ssc d...
carma_planning_msgs::msg::Maneuver composeLaneChangeManeuverMessage(double start_dist, double end_dist, double start_speed, double target_speed, lanelet::Id starting_lane_id, lanelet::Id ending_lane_id, rclcpp::Time &start_time) const
Function to compose a lane change maneuver message based on the provided maneuver parameters.
FRIEND_TEST(Testapproaching_emergency_vehicle_plugin, testBSMProcessing)
rclcpp::TimerBase::SharedPtr erv_timeout_timer_
std::unordered_map< std::string, rclcpp::Time > latest_erv_update_times_
carma_planning_msgs::msg::ManeuverPlan latest_maneuver_plan_
boost::optional< lanelet::BasicPoint2d > getErvPositionInMap(const double ¤t_latitude, const double ¤t_longitude)
Helper function to obtain an ERV's position in the map frame from its current latitude and longitude.
FRIEND_TEST(Testapproaching_emergency_vehicle_plugin, testApproachingErvStatusMessage)
FRIEND_TEST(Testapproaching_emergency_vehicle_plugin, testWarningBroadcast)
rclcpp::TimerBase::SharedPtr hazard_light_timer_
FRIEND_TEST(Testapproaching_emergency_vehicle_plugin, filter_points_ahead)
void incomingBsmCallback(carma_v2x_msgs::msg::BSM::UniquePtr msg)
Incoming BSM subscription callback, which determines whether a BSM should be processed,...
carma_planning_msgs::msg::RouteState latest_route_state_
void plan_maneuvers_callback(std::shared_ptr< rmw_request_id_t >, carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp) override
Extending class provided callback which should return a planned trajectory based on the provided traj...
carma_ros2_utils::SubPtr< carma_planning_msgs::msg::RouteState > route_state_sub_
double getLaneletSpeedLimit(const lanelet::ConstLanelet &lanelet)
Helper function to extract the speed limit (m/s) from a provided lanelet.
std::vector< lanelet::BasicPoint2d > filter_points_ahead(const lanelet::BasicPoint2d &reference_point, const std::vector< lanelet::BasicPoint2d > &original_points) const
Helper function that return points ahead of the given reference point accounting for the list of poin...
boost::optional< ErvInformation > getErvInformationFromBsm(carma_v2x_msgs::msg::BSM::UniquePtr msg)
Through internal logic and calls to separate helper functions, this function processes a received BSM...
std::string strategic_plugin_name_
void routeCallback(carma_planning_msgs::msg::Route::UniquePtr msg)
Route subscription callback, with is used to update this plugin's future_route_lanelet_ids_ object.
FRIEND_TEST(Testapproaching_emergency_vehicle_plugin, testRouteConflict)
void twistCallback(geometry_msgs::msg::TwistStamped::UniquePtr msg)
Subscription callback for the twist subscriber, which will store latest current velocity of the ego v...
bool should_broadcast_warnings_
carma_ros2_utils::SubPtr< carma_planning_msgs::msg::GuidanceState > guidance_state_sub_
void georeferenceCallback(const std_msgs::msg::String::UniquePtr msg)
Subscription callback for the georeference.
rclcpp::TimerBase::SharedPtr approaching_emergency_vehicle_status_timer_
const std::string APPROACHING_ERV_STATUS_PARAMS
std::string get_version_id() override
Returns the version id of this plugin.
rclcpp::TimerBase::SharedPtr warning_broadcast_timer_
carma_msgs::msg::UIInstructions generateApproachingErvStatusMessage()
Function to generate a carma_msgs::msg::UIInstructions message that describes whether there is curren...
std::vector< int > future_route_lanelet_ids_
bool has_received_route_state_
bool is_maintaining_non_reduced_speed_
Class defining the state transition table behavior for the ApproachingEmergencyVehiclePlugin.
StrategicPlugin base class which can be extended by user provided plugins which wish to implement the...
constexpr double METERS_PER_SEC_TO_MILES_PER_HOUR
std::shared_ptr< const WorldModel > WorldModelConstPtr
Stuct containing the algorithm configuration values for approaching_emergency_vehicle_plugin.
Convenience struct for storing the parameters of an upcoming lane change to ensure that the same para...
bool is_right_lane_change
lanelet::ConstLanelet starting_lanelet
lanelet::ConstLanelet ending_lanelet