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(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(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.