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.
stop_and_dwell_strategic_plugin.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2023 LEIDOS.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
14 * the License.
15 */
17
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_" \
23 "PROPERTY " \
24 "(property) " \
25 "called on " \
26 "maneuver with " \
27 "invalid type " \
28 "id"))))
29
30
32{
33namespace std_ph = std::placeholders;
34
35namespace {
41 double getManeuverEndSpeed(const carma_planning_msgs::msg::Maneuver& mvr)
42 {
43 switch(mvr.type)
44 {
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:
50 return 0;
51 default:
52 RCLCPP_ERROR_STREAM(rclcpp::get_logger("stop_and_dwell_strategic_plugin"), "Requested end speed from unsupported maneuver type");
53 return 0;
54 }
55 }
56} // namespace anonymous
57
59 : carma_guidance_plugins::StrategicPlugin(options), config_(StopAndDwellStrategicPluginConfig())
60{
61 // Declare parameters
62 config_.vehicle_decel_limit_multiplier = declare_parameter<double>("vehicle_decel_limit_multiplier", config_.vehicle_decel_limit_multiplier);
63 config_.vehicle_accel_limit_multiplier = declare_parameter<double>("vehicle_accel_limit_multiplier", config_.vehicle_accel_limit_multiplier);
64 config_.stop_line_buffer = declare_parameter<double>("stop_line_buffer", config_.stop_line_buffer);
65 config_.bus_line_exit_zone_length = declare_parameter<double>("bus_line_exit_zone_length", config_.bus_line_exit_zone_length);
66 config_.strategic_plugin_name = declare_parameter<std::string>("strategic_plugin_name", config_.strategic_plugin_name);
67 config_.lane_following_plugin_name = declare_parameter<std::string>("lane_following_plugin_name", config_.lane_following_plugin_name);
68 config_.vehicle_id = declare_parameter<std::string>("vehicle_id", config_.vehicle_id);
69 config_.veh_length = declare_parameter<double>("vehicle_length", config_.veh_length);
70 config_.vehicle_decel_limit = declare_parameter<double>("vehicle_deceleration_limit", config_.vehicle_decel_limit);
71 config_.vehicle_accel_limit = declare_parameter<double>("vehicle_acceleration_limit", config_.vehicle_accel_limit);
72 config_.activation_distance = declare_parameter<double>("activation_distance", config_.activation_distance);
73 config_.dwell_time = declare_parameter<double>("dwell_time", config_.dwell_time);
74 config_.deceleration_fraction = declare_parameter<double>("deceleration_fraction", config_.deceleration_fraction);
75 config_.desired_distance_to_stop_buffer = declare_parameter<double>("desired_distance_to_stop_buffer", config_.desired_distance_to_stop_buffer);
76
80};
81
82carma_ros2_utils::CallbackReturn StopAndDwellStrategicPlugin::on_configure_plugin()
83{
84 // reset config
86 // Declare parameters
87 get_parameter<double>("vehicle_decel_limit_multiplier", config_.vehicle_decel_limit_multiplier);
88 get_parameter<double>("vehicle_accel_limit_multiplier", config_.vehicle_accel_limit_multiplier);
89 get_parameter<double>("stop_line_buffer", config_.stop_line_buffer);
90 get_parameter<double>("bus_line_exit_zone_length", config_.bus_line_exit_zone_length);
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>("vehicle_id", config_.vehicle_id);
94 get_parameter<double>("vehicle_length", config_.veh_length);
95 get_parameter<double>("vehicle_deceleration_limit", config_.vehicle_decel_limit);
96 get_parameter<double>("vehicle_acceleration_limit", config_.vehicle_accel_limit);
97 get_parameter<double>("activation_distance", config_.activation_distance);
98 get_parameter<double>("dwell_time", config_.dwell_time);
99 get_parameter<double>("deceleration_fraction", config_.deceleration_fraction);
100 get_parameter<double>("desired_distance_to_stop_buffer", config_.desired_distance_to_stop_buffer);
101
105
106 // Register runtime parameter update callback
107 add_on_set_parameters_callback(std::bind(&StopAndDwellStrategicPlugin::parameter_update_callback, this, std_ph::_1));
108
109 RCLCPP_INFO_STREAM(rclcpp::get_logger("stop_and_dwell_strategic_plugin"),"Done loading parameters: " << config_);
110
111 // Current Pose Subscriber
112 current_pose_sub_ = create_subscription<geometry_msgs::msg::PoseStamped>("current_pose", 1,
113 std::bind(&StopAndDwellStrategicPlugin::currentPoseCb,this,std_ph::_1));
114
115 // Guidance State subscriber
116 guidance_state_sub_ = create_subscription<carma_planning_msgs::msg::GuidanceState>("guidance_state", 5,
117 std::bind(&StopAndDwellStrategicPlugin::guidance_state_cb, this, std::placeholders::_1));
118
119 // set world model point form wm listener
121
122 // Return success if everthing initialized successfully
123 return CallbackReturn::SUCCESS;
124}
125
126rcl_interfaces::msg::SetParametersResult StopAndDwellStrategicPlugin::parameter_update_callback(const std::vector<rclcpp::Parameter> &parameters)
127{
128 auto error_double = update_params<double>({
129 {"vehicle_decel_limit_multiplier", config_.vehicle_decel_limit_multiplier},
130 {"vehicle_accel_limit_multiplier", config_.vehicle_accel_limit_multiplier},
131 {"stop_line_buffer", config_.stop_line_buffer},
132 {"bus_line_exit_zone_length", config_.bus_line_exit_zone_length}
133 }, parameters); // vehicle_acceleration_limit not updated as it's global param
134
135 rcl_interfaces::msg::SetParametersResult result;
136
137 result.successful = !error_double;
138
139 return result;
140}
141
142carma_ros2_utils::CallbackReturn StopAndDwellStrategicPlugin::on_activate_plugin()
143{
144 return CallbackReturn::SUCCESS;
145}
146
147VehicleState StopAndDwellStrategicPlugin::extractInitialState(const carma_planning_msgs::srv::PlanManeuvers::Request& req) const
148{
149 VehicleState state;
150 if (!req.prior_plan.maneuvers.empty())
151 {
152 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_and_dwell_strategic_plugin"), "Provided with initial plan...");
153 state.stamp = GET_MANEUVER_PROPERTY(req.prior_plan.maneuvers.back(), end_time);
154 state.speed = getManeuverEndSpeed(req.prior_plan.maneuvers.back());
155 state.downtrack = GET_MANEUVER_PROPERTY(req.prior_plan.maneuvers.back(), end_dist);
156 state.lane_id = getLaneletsBetweenWithException(state.downtrack, state.downtrack, true).front().id();
157 }
158 else
159 {
160 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_and_dwell_strategic_plugin"), "No initial plan provided...");
161
162 state.stamp = req.header.stamp;
163 state.downtrack = req.veh_downtrack;
164 state.speed = req.veh_logitudinal_velocity;
165 state.lane_id = stoi(req.veh_lane_id);
166 }
167
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);
172
173 return state;
174}
175
176void StopAndDwellStrategicPlugin::guidance_state_cb(const carma_planning_msgs::msg::GuidanceState::UniquePtr msg)
177{
179}
180
181void StopAndDwellStrategicPlugin::currentPoseCb(geometry_msgs::msg::PoseStamped::UniquePtr msg)
182{
183 geometry_msgs::msg::PoseStamped pose_msg = geometry_msgs::msg::PoseStamped(*msg.get());
185 {
186 lanelet::BasicPoint2d current_loc(pose_msg.pose.position.x, pose_msg.pose.position.y);
187 current_downtrack_ = wm_->routeTrackPos(current_loc).downtrack;
188 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("stop_and_dwell_strategic_plugin"), "Downtrack from current pose: " << current_downtrack_);
189 }
190
191}
192
193std::vector<lanelet::ConstLanelet> StopAndDwellStrategicPlugin::getLaneletsBetweenWithException(double start_downtrack,
194 double end_downtrack,
195 bool shortest_path_only,
196 bool bounds_inclusive) const
197{
198 std::vector<lanelet::ConstLanelet> crossed_lanelets =
199 wm_->getLaneletsBetween(start_downtrack, end_downtrack, shortest_path_only, bounds_inclusive);
200
201 if (crossed_lanelets.empty())
202 {
203 throw std::invalid_argument("getLaneletsBetweenWithException called but inputs do not cross any lanelets going "
204 "from: " +
205 std::to_string(start_downtrack) + " to: " + std::to_string(end_downtrack));
206 }
207
208 return crossed_lanelets;
209}
210
211VehicleState StopAndDwellStrategicPlugin::extractInitialState(carma_planning_msgs::srv::PlanManeuvers::Request::SharedPtr req) const
212{
213 VehicleState state;
214 if (!req->prior_plan.maneuvers.empty())
215 {
216 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(logger_name_), "Provided with initial plan...");
217 state.stamp = GET_MANEUVER_PROPERTY(req->prior_plan.maneuvers.back(), end_time);
218 state.downtrack = GET_MANEUVER_PROPERTY(req->prior_plan.maneuvers.back(), end_dist);
219 state.speed = getManeuverEndSpeed(req->prior_plan.maneuvers.back());
220 state.lane_id = getLaneletsBetweenWithException(state.downtrack, state.downtrack, true).front().id();
221 }
222 else
223 {
224 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(logger_name_), "No initial plan provided...");
225
226 state.stamp = rclcpp::Time(req->header.stamp, RCL_SYSTEM_TIME);
227 state.downtrack = req->veh_downtrack;
228 state.speed = req->veh_logitudinal_velocity;
229 state.lane_id = stoi(req->veh_lane_id);
230 }
231 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(logger_name_), "extractInitialState >>>> state.stamp: " << std::to_string(state.stamp.seconds()));
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);
235
236 return state;
237}
238
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)
243{
244 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
245
246 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(logger_name_), "<<<<<<<<<<<<<<<<< STARTING STOP_AND_DWELL_STRATEGIC_PLUIGN!!!!!!!!! >>>>>>>>>>>>>>>>");
247
248 if (!wm_->getRoute())
249 {
250 RCLCPP_ERROR_STREAM(rclcpp::get_logger(logger_name_), "Could not plan maneuvers as route was not available");
251 return;
252 }
253
254 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(logger_name_), "Finding car information");
255
256 // Extract vehicle data from request
257 VehicleState current_state = extractInitialState(req);
258
259 auto bus_stop_list = wm_->getBusStopsAlongRoute({ req->veh_x, req->veh_y });
260
261 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(logger_name_), "Found bus stops of size: " << bus_stop_list .size());
262
263 if(bus_stop_list.empty())
264 {
265 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(logger_name_), "Bus stops list is empty");
266 return;
267 }
268
269 lanelet::BusStopRulePtr nearest_bus_stop = bus_stop_list.front();
270
271 double bus_stop_downtrack_ = wm_->routeTrackPos(nearest_bus_stop->stopAndWaitLine().front().front().basicPoint2d()).downtrack;
272 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(logger_name_), "bus_stop_downtrack_ : " << bus_stop_downtrack_ );
273 double distance_remaining_to_bus_stop = bus_stop_downtrack_ - current_state.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);
276
277 if (distance_remaining_to_bus_stop < -config_.bus_line_exit_zone_length)
278 {
279 resp->new_plan.maneuvers = {};
280 RCLCPP_WARN_STREAM(rclcpp::get_logger(logger_name_), "Already passed bus stop, sending empty maneuvers");
281 return;
282 }
283
284 constexpr double HALF_MPH_IN_MPS = 0.22352;
285
286 if (current_state.speed < HALF_MPH_IN_MPS && fabs(bus_stop_downtrack_ - current_state.downtrack ) < config_.stop_line_buffer)
287 {
288 if(first_stop_)
289 {
290 time_to_move_ = now() + rclcpp::Duration(config_.dwell_time * 1e9);
291 first_stop_ = false;
292 }
293
294 if(time_to_move_ <= now())
295 {
296 std::vector<lanelet::ConstLanelet> crossed_lanelets = getLaneletsBetweenWithException(current_state.downtrack, bus_stop_downtrack_, true, true);
297 auto starting_lane_id = crossed_lanelets.front().id();
298 auto ending_lane_id = crossed_lanelets.back().id();
299 resp->new_plan.maneuvers.push_back(composeStopAndWaitManeuverMessage(current_state.downtrack ,bus_stop_downtrack_,current_state.speed,starting_lane_id,ending_lane_id,max_comfort_decel_norm_ ,now(),now() + rclcpp::Duration(config_.min_maneuver_planning_period * 1e9) ));
300 }
301 else
302 {
303 double maneuver_end_distance = bus_stop_downtrack_ + config_.bus_line_exit_zone_length;
304 std::vector<lanelet::ConstLanelet> crossed_lanelets = getLaneletsBetweenWithException(current_state.downtrack, maneuver_end_distance, true, true);
305 std::vector<lanelet::Id> lane_ids = lanelet::utils::transform(crossed_lanelets, [](const auto& ll) { return ll.id(); });
306 speed_limit_ = findSpeedLimit(crossed_lanelets.front());
307 resp->new_plan.maneuvers.push_back(composeLaneFollowingManeuverMessage(current_state.downtrack ,maneuver_end_distance,current_state.speed,speed_limit_,now(),config_.min_maneuver_planning_period,lane_ids));
308 }
309 }
310 else if ( current_state.downtrack>= ( bus_stop_downtrack_ - config_.activation_distance ))
311 {
312 double desired_distance_to_stop = pow(current_state.speed, 2)/(2 * max_comfort_decel_norm_ * config_.deceleration_fraction) + config_.desired_distance_to_stop_buffer;
313
314 if(current_state.downtrack >= ( bus_stop_downtrack_ - desired_distance_to_stop))
315 {
316 std::vector<lanelet::ConstLanelet> crossed_lanelets = getLaneletsBetweenWithException(current_state.downtrack, bus_stop_downtrack_, true, true);
317 auto starting_lane_id = crossed_lanelets.front().id();
318 auto ending_lane_id = crossed_lanelets.back().id();
319 rclcpp::Time start_time = now();
320 rclcpp::Time end_time = now() + rclcpp::Duration(config_.min_maneuver_planning_period * 1e9) ;
321 //Stop at desired distance before bus stop
322 resp->new_plan.maneuvers.push_back(composeStopAndWaitManeuverMessage(current_state.downtrack ,bus_stop_downtrack_,current_state.speed,starting_lane_id,ending_lane_id,max_comfort_decel_norm_ ,start_time,end_time));
323 }
324 else
325 {
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);
328 std::vector<lanelet::ConstLanelet> crossed_lanelets = getLaneletsBetweenWithException(current_state.downtrack, (bus_stop_downtrack_ - desired_distance_to_stop) , true, true);
329 std::vector<lanelet::ConstLanelet> crossed_lanelets_stop = getLaneletsBetweenWithException((bus_stop_downtrack_ - desired_distance_to_stop), bus_stop_downtrack_, true, true);
330 std::vector<lanelet::Id> lane_ids = lanelet::utils::transform(crossed_lanelets, [](const auto& ll) { return ll.id(); });
331
332 auto starting_lane_id = crossed_lanelets_stop.front().id();
333 auto ending_lane_id = crossed_lanelets_stop.back().id();
334
335 resp->new_plan.maneuvers.push_back(composeLaneFollowingManeuverMessage(current_state.downtrack ,(bus_stop_downtrack_ - desired_distance_to_stop),current_state.speed,speed_limit_,now(), time_to_stop,lane_ids));
336 resp->new_plan.maneuvers.push_back(composeStopAndWaitManeuverMessage((bus_stop_downtrack_ - desired_distance_to_stop),bus_stop_downtrack_,speed_limit_,starting_lane_id,ending_lane_id,max_comfort_decel_norm_ ,timestamp_to_stop ,(timestamp_to_stop + rclcpp::Duration(config_.min_maneuver_planning_period * 1e9))));
337 }
338 }
339 std::chrono::system_clock::time_point execution_end_time = std::chrono::system_clock::now(); // Planning complete
340
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());
343 return;
344}
345
346carma_planning_msgs::msg::Maneuver StopAndDwellStrategicPlugin::composeLaneFollowingManeuverMessage(double start_dist, double end_dist,
347 double start_speed, double target_speed,
348 rclcpp::Time start_time, double time_to_stop,
349 std::vector<lanelet::Id> lane_ids)
350{
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;
354 maneuver_msg.lane_following_maneuver.parameters.planning_strategic_plugin = config_.strategic_plugin_name;
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;
358 maneuver_msg.lane_following_maneuver.parameters.planning_tactical_plugin = config_.lane_following_plugin_name;
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); });
367
368 RCLCPP_INFO_STREAM(rclcpp::get_logger("stop_and_dwell_strategic_plugin"), "Creating lane follow start dist: " << start_dist << " end dist: " << end_dist);
369return maneuver_msg;
370}
371
372
373double StopAndDwellStrategicPlugin::findSpeedLimit(const lanelet::ConstLanelet& llt) const
374{
375 lanelet::Optional<carma_wm::TrafficRulesConstPtr> traffic_rules = wm_->getTrafficRules();
376 if (traffic_rules)
377 {
378 return (*traffic_rules)->speedLimit(llt).speedLimit.value();
379 }
380 else
381 {
382 throw std::invalid_argument("Valid traffic rules object could not be built");
383 }
384}
385
386carma_planning_msgs::msg::Maneuver StopAndDwellStrategicPlugin::composeStopAndWaitManeuverMessage(double current_dist, double end_dist,
387 double start_speed,
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
391{
392 carma_planning_msgs::msg::Maneuver maneuver_msg;
393 maneuver_msg.type = carma_planning_msgs::msg::Maneuver::STOP_AND_WAIT;
394 maneuver_msg.stop_and_wait_maneuver.parameters.planning_strategic_plugin = config_.strategic_plugin_name;
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;
398 maneuver_msg.stop_and_wait_maneuver.parameters.planning_tactical_plugin = config_.stop_and_wait_plugin_name;
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);
406 // Set the meta data for the stop location buffer
407 maneuver_msg.stop_and_wait_maneuver.parameters.float_valued_meta_data.push_back(config_.stop_line_buffer);
408 maneuver_msg.stop_and_wait_maneuver.parameters.float_valued_meta_data.push_back(stopping_accel);
409
410 RCLCPP_INFO_STREAM(rclcpp::get_logger("stop_and_dwell_strategic_plugin"), "Creating stop and wait start dist: " << current_dist << " end dist: " << end_dist);
411
412 return maneuver_msg;
413}
414
416{
417 return true;
418}
419
421{
422 return "v1.0";
423}
424
425} // namespace stop_and_dwell_strategic_plugin
426
427#include "rclcpp_components/register_node_macro.hpp"
428
429// Register the component with class_loader
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.
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...
rcl_interfaces::msg::SetParametersResult parameter_update_callback(const std::vector< rclcpp::Parameter > &parameters)
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....
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
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.
carma_ros2_utils::SubPtr< geometry_msgs::msg::PoseStamped > current_pose_sub_
auto to_string(const UtmZone &zone) -> std::string
Definition: utm_zone.cpp:21
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.
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.
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 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.