18#define GET_MANEUVER_PROPERTY(mvr, property)                                                                           \ 
   19                  ((mvr).type == carma_planning_msgs::msg::Maneuver::LANE_CHANGE    ? (mvr).lane_change_maneuver.property :            \ 
   20                  ((mvr).type == carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING ? (mvr).lane_following_maneuver.property :         \ 
   21                  ((mvr).type == carma_planning_msgs::msg::Maneuver::STOP_AND_WAIT ? (mvr).stop_and_wait_maneuver.property :           \ 
   22                                                                      throw new std::invalid_argument("GET_MANEUVER_"  \
 
   33namespace std_ph = std::placeholders;
 
   45      case carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING:
 
   46          return mvr.lane_following_maneuver.end_speed;
 
   47      case carma_planning_msgs::msg::Maneuver::LANE_CHANGE:
 
   48          return mvr.lane_change_maneuver.end_speed;
 
   49      case carma_planning_msgs::msg::Maneuver::STOP_AND_WAIT:
 
   52          RCLCPP_ERROR_STREAM(rclcpp::get_logger(
"stop_and_dwell_strategic_plugin"), 
"Requested end speed from unsupported maneuver type");
 
  109  RCLCPP_INFO_STREAM(rclcpp::get_logger(
"stop_and_dwell_strategic_plugin"),
"Done loading parameters: " << 
config_);
 
  112  current_pose_sub_ = create_subscription<geometry_msgs::msg::PoseStamped>(
"current_pose", 1, 
 
  116  guidance_state_sub_ = create_subscription<carma_planning_msgs::msg::GuidanceState>(
"guidance_state", 5, 
 
  123  return CallbackReturn::SUCCESS;
 
  128  auto error_double = update_params<double>({
 
  135  rcl_interfaces::msg::SetParametersResult result;
 
  137  result.successful = !error_double;
 
  144  return CallbackReturn::SUCCESS;
 
  150  if (!req.prior_plan.maneuvers.empty())
 
  152    RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"stop_and_dwell_strategic_plugin"), 
"Provided with initial plan...");
 
  160    RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"stop_and_dwell_strategic_plugin"), 
"No initial plan provided...");
 
  162    state.
stamp = req.header.stamp;
 
  164    state.
speed = req.veh_logitudinal_velocity;
 
  165    state.
lane_id = stoi(req.veh_lane_id);
 
  168  RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"stop_and_dwell_strategic_plugin"), 
"state.stamp: " << 
std::to_string(state.
stamp.seconds()));
 
  169  RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"stop_and_dwell_strategic_plugin"), 
"state.downtrack : " << state.
downtrack );
 
  170  RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"stop_and_dwell_strategic_plugin"), 
"state.speed: " << state.
speed);
 
  171  RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"stop_and_dwell_strategic_plugin"), 
"state.lane_id: " << state.
lane_id);
 
  183  geometry_msgs::msg::PoseStamped pose_msg = geometry_msgs::msg::PoseStamped(*msg.get());
 
  186    lanelet::BasicPoint2d current_loc(pose_msg.pose.position.x, pose_msg.pose.position.y);
 
  188    RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"stop_and_dwell_strategic_plugin"), 
"Downtrack from current pose: " << 
current_downtrack_);
 
  194                                                                                      double end_downtrack,
 
  195                                                                                      bool shortest_path_only,
 
  196                                                                                      bool bounds_inclusive)
 const 
  198  std::vector<lanelet::ConstLanelet> crossed_lanelets =
 
  199      wm_->getLaneletsBetween(start_downtrack, end_downtrack, shortest_path_only, bounds_inclusive);
 
  201  if (crossed_lanelets.empty())
 
  203    throw std::invalid_argument(
"getLaneletsBetweenWithException called but inputs do not cross any lanelets going " 
  208  return crossed_lanelets;
 
  214  if (!req->prior_plan.maneuvers.empty())
 
  216    RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
logger_name_), 
"Provided with initial plan...");
 
  224    RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
logger_name_), 
"No initial plan provided...");
 
  226    state.
stamp = rclcpp::Time(req->header.stamp, RCL_SYSTEM_TIME);
 
  228    state.
speed = req->veh_logitudinal_velocity;
 
  229    state.
lane_id = stoi(req->veh_lane_id);
 
  232  RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
logger_name_), 
"extractInitialState >>>> state.downtrack : " << state.
downtrack );
 
  233  RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
logger_name_), 
"extractInitialState >>>> state.speed: " << state.
speed);
 
  234  RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
logger_name_), 
"extractInitialState >>>> state.lane_id: " << state.
lane_id);
 
  240  std::shared_ptr<rmw_request_id_t> srv_header, 
 
  241  carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req, 
 
  242  carma_planning_msgs::srv::PlanManeuvers::Response::SharedPtr resp)
 
  244  std::chrono::system_clock::time_point execution_start_time = std::chrono::system_clock::now();  
 
  246  RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
logger_name_), 
"<<<<<<<<<<<<<<<<< STARTING STOP_AND_DWELL_STRATEGIC_PLUIGN!!!!!!!!! >>>>>>>>>>>>>>>>");
 
  248  if (!
wm_->getRoute())
 
  250    RCLCPP_ERROR_STREAM(rclcpp::get_logger(
logger_name_), 
"Could not plan maneuvers as route was not available");
 
  254  RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
logger_name_), 
"Finding car information");
 
  259  auto bus_stop_list = 
wm_->getBusStopsAlongRoute({ req->veh_x, req->veh_y });
 
  261  RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
logger_name_), 
"Found bus stops of size: " << bus_stop_list .size());
 
  263  if(bus_stop_list.empty())
 
  265    RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
logger_name_), 
"Bus stops list is empty");
 
  269  lanelet::BusStopRulePtr nearest_bus_stop = bus_stop_list.front();
 
  271  double bus_stop_downtrack_  = 
wm_->routeTrackPos(nearest_bus_stop->stopAndWaitLine().front().front().basicPoint2d()).downtrack;
 
  274  RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
logger_name_), 
"distance_remaining_to_bus_stop: " << distance_remaining_to_bus_stop <<
 
  275                    ", current_state.downtrack: " << current_state.
downtrack);
 
  279    resp->new_plan.maneuvers = {};
 
  280    RCLCPP_WARN_STREAM(rclcpp::get_logger(
logger_name_), 
"Already passed bus stop, sending empty maneuvers");
 
  284  constexpr double HALF_MPH_IN_MPS = 0.22352;  
 
  297      auto starting_lane_id = crossed_lanelets.front().id();
 
  298      auto ending_lane_id = crossed_lanelets.back().id();
 
  305      std::vector<lanelet::Id> lane_ids = lanelet::utils::transform(crossed_lanelets, [](
const auto& ll) { 
return ll.id(); });
 
  317      auto starting_lane_id = crossed_lanelets.front().id();
 
  318      auto ending_lane_id = crossed_lanelets.back().id();
 
  319      rclcpp::Time start_time = now();
 
  326      double time_to_stop = (distance_remaining_to_bus_stop - desired_distance_to_stop)/
speed_limit_;
 
  327      rclcpp::Time timestamp_to_stop = now() + rclcpp::Duration::from_nanoseconds(time_to_stop * 1e9);
 
  330      std::vector<lanelet::Id> lane_ids = lanelet::utils::transform(crossed_lanelets, [](
const auto& ll) { 
return ll.id(); });
 
  332      auto starting_lane_id = crossed_lanelets_stop.front().id();
 
  333      auto ending_lane_id = crossed_lanelets_stop.back().id();
 
  339  std::chrono::system_clock::time_point execution_end_time = std::chrono::system_clock::now();  
 
  341  auto execution_duration = execution_end_time - execution_start_time;
 
  342  RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
logger_name_), 
"ExecutionTime stop_and_dwell_strategic_plugin: " << std::chrono::duration<double>(execution_duration).count());
 
  347                                                                          double start_speed, 
double target_speed,
 
  348                                                                          rclcpp::Time start_time, 
double time_to_stop,
 
  349                                                                          std::vector<lanelet::Id> lane_ids)
 
  351  carma_planning_msgs::msg::Maneuver maneuver_msg;
 
  352  carma_planning_msgs::msg::Maneuver empty_msg;
 
  353  maneuver_msg.type = carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING;
 
  355  maneuver_msg.lane_following_maneuver.parameters.presence_vector = 
 
  356  carma_planning_msgs::msg::ManeuverParameters::HAS_TACTICAL_PLUGIN;
 
  357  maneuver_msg.lane_following_maneuver.parameters.negotiation_type = carma_planning_msgs::msg::ManeuverParameters::NO_NEGOTIATION;
 
  359  maneuver_msg.lane_following_maneuver.start_dist = start_dist;
 
  360  maneuver_msg.lane_following_maneuver.end_dist = end_dist;
 
  361  maneuver_msg.lane_following_maneuver.start_speed = start_speed;
 
  362  maneuver_msg.lane_following_maneuver.end_speed = target_speed;
 
  363  maneuver_msg.lane_following_maneuver.start_time = start_time;
 
  364  maneuver_msg.lane_following_maneuver.end_time =  start_time + rclcpp::Duration::from_nanoseconds(time_to_stop*1e9);
 
  365  maneuver_msg.lane_following_maneuver.lane_ids =
 
  366      lanelet::utils::transform(lane_ids, [](
auto id) { 
return std::to_string(
id); });
 
  368  RCLCPP_INFO_STREAM(rclcpp::get_logger(
"stop_and_dwell_strategic_plugin"), 
"Creating lane follow start dist: " << start_dist << 
" end dist: " << end_dist);
 
  375  lanelet::Optional<carma_wm::TrafficRulesConstPtr> traffic_rules = 
wm_->getTrafficRules();
 
  378    return (*traffic_rules)->speedLimit(llt).speedLimit.value();
 
  382    throw std::invalid_argument(
"Valid traffic rules object could not be built");
 
  388                                                                        const lanelet::Id& starting_lane_id,
 
  389                                                                        const lanelet::Id& ending_lane_id, 
double stopping_accel,
 
  390                                                                        rclcpp::Time start_time, rclcpp::Time end_time)
 const 
  392  carma_planning_msgs::msg::Maneuver maneuver_msg;
 
  393  maneuver_msg.type = carma_planning_msgs::msg::Maneuver::STOP_AND_WAIT;
 
  395  maneuver_msg.stop_and_wait_maneuver.parameters.presence_vector =
 
  396      carma_planning_msgs::msg::ManeuverParameters::HAS_TACTICAL_PLUGIN | carma_planning_msgs::msg::ManeuverParameters::HAS_FLOAT_META_DATA;
 
  397  maneuver_msg.stop_and_wait_maneuver.parameters.negotiation_type = carma_planning_msgs::msg::ManeuverParameters::NO_NEGOTIATION;
 
  399  maneuver_msg.stop_and_wait_maneuver.start_speed = start_speed;
 
  400  maneuver_msg.stop_and_wait_maneuver.start_dist = current_dist;
 
  401  maneuver_msg.stop_and_wait_maneuver.end_dist = end_dist;
 
  402  maneuver_msg.stop_and_wait_maneuver.start_time = start_time;
 
  403  maneuver_msg.stop_and_wait_maneuver.end_time = end_time;
 
  404  maneuver_msg.stop_and_wait_maneuver.starting_lane_id = 
std::to_string(starting_lane_id);
 
  405  maneuver_msg.stop_and_wait_maneuver.ending_lane_id = 
std::to_string(ending_lane_id);
 
  408  maneuver_msg.stop_and_wait_maneuver.parameters.float_valued_meta_data.push_back(stopping_accel);
 
  410  RCLCPP_INFO_STREAM(rclcpp::get_logger(
"stop_and_dwell_strategic_plugin"), 
"Creating stop and wait start dist: " << current_dist << 
" end dist: " << end_dist);
 
  427#include "rclcpp_components/register_node_macro.hpp" 
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...
 
StopAndDwellStrategicPlugin(const rclcpp::NodeOptions &)
Default constructor for RouteFollowingPlugin class.
 
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, double stopping_accel, rclcpp::Time start_time, rclcpp::Time end_time) const
 
void guidance_state_cb(const carma_planning_msgs::msg::GuidanceState::UniquePtr msg)
Callback for the Guidance State.
 
carma_wm::WorldModelConstPtr wm_
World Model pointer.
 
std::string get_version_id()
Returns the version id of this plugin.
 
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.
 
double findSpeedLimit(const lanelet::ConstLanelet &llt) const
Given a Lanelet, find it's associated Speed Limit.
 
carma_ros2_utils::CallbackReturn on_activate_plugin()
Method which is triggered when this plugin is moved from the INACTIVE to ACTIVE states....
 
VehicleState extractInitialState(const carma_planning_msgs::srv::PlanManeuvers::Request &req) const
Helper method to extract the initial vehicle state from the planning request method based on if the p...
 
double current_downtrack_
 
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::GuidanceState > guidance_state_sub_
 
carma_ros2_utils::CallbackReturn on_configure_plugin()
Method which is triggered when this plugin is moved from the UNCONFIGURED to INACTIVE states....
 
StopAndDwellStrategicPluginConfig config_
Config containing configurable algorithm parameters.
 
bool get_availability()
Get the availability status of this plugin based on the current operating environment....
 
double bus_stop_downtrack_
 
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,...
 
void currentPoseCb(geometry_msgs::msg::PoseStamped::UniquePtr msg)
callback function for current pose
 
double max_comfort_accel_
 
double max_comfort_decel_norm_
 
carma_planning_msgs::msg::Maneuver composeLaneFollowingManeuverMessage(double start_dist, double end_dist, double start_speed, double target_speed, rclcpp::Time start_time, double time_to_stop, std::vector< lanelet::Id > lane_ids)
Compose a lane keeping maneuver message based on input params.
 
rclcpp::Time time_to_move_
 
double max_comfort_decel_
 
carma_ros2_utils::SubPtr< geometry_msgs::msg::PoseStamped > current_pose_sub_
 
auto to_string(const UtmZone &zone) -> std::string
 
double getManeuverEndSpeed(const carma_planning_msgs::msg::Maneuver &mvr)
Anonymous function to extract maneuver end speed which can not be optained with GET_MANEUVER_PROPERY ...
 
#define GET_MANEUVER_PROPERTY(mvr, property)
 
Struct to store the configuration settings for the WzStrategicPlugin class.
 
double activation_distance
Activation distance of stop and dwell plugin.
 
std::string strategic_plugin_name
The name to use for this plugin during comminications with the arbitrator.
 
double vehicle_decel_limit
The maximum allowable vehicle deceleration limit in m/s.
 
std::string stop_and_wait_plugin_name
The name of the plugin to use for stop and wait trajectory planning.
 
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 deceleration_fraction
Double: Safety multiplier (must be less than 1.0) of planned allowable vehicle deceleration to use wh...
 
double vehicle_decel_limit_multiplier
A multiplier to apply to the maximum allowable vehicle deceleration limit so we plan under our capabi...
 
double desired_distance_to_stop_buffer
Double: Desired distance to stop buffer in meters.
 
double vehicle_accel_limit
The maximum allowable vehicle acceleration limit in m/s.
 
double bus_line_exit_zone_length
 
std::string vehicle_id
License plate of the vehicle.
 
std::string lane_following_plugin_name
The name of the tactical plugin to use for Lane Following trajectory planning.
 
double stop_line_buffer
A buffer infront of the stopping location which will still be considered a valid stop.
 
double dwell_time
Dwell time is the time to stop at the bus stop.
 
double vehicle_accel_limit_multiplier
A multiplier to apply to the maximum allowable vehicle acceleration limit so we plan under our capabi...
 
Struct representing a vehicle state for the purposes of planning.