Skip to content

Commit 802c392

Browse files
feat(mission_planner): add guard for reroute (#3841)
1 parent 94d2d5c commit 802c392

File tree

2 files changed

+96
-24
lines changed

2 files changed

+96
-24
lines changed

planning/mission_planner/src/mission_planner/mission_planner.cpp

+89-24
Original file line numberDiff line numberDiff line change
@@ -170,59 +170,78 @@ void MissionPlanner::change_route(const LaneletRoute & route)
170170
normal_route_ = std::make_shared<LaneletRoute>(route);
171171
}
172172

173-
LaneletRoute MissionPlanner::create_route(const SetRoute::Service::Request::SharedPtr req)
173+
LaneletRoute MissionPlanner::create_route(
174+
const std_msgs::msg::Header & header,
175+
const std::vector<autoware_adapi_v1_msgs::msg::RouteSegment> & route_segments,
176+
const geometry_msgs::msg::Pose & goal_pose, const bool allow_goal_modification)
174177
{
175-
PoseStamped goal_pose;
176-
goal_pose.header = req->header;
177-
goal_pose.pose = req->goal;
178+
PoseStamped goal_pose_stamped;
179+
goal_pose_stamped.header = header;
180+
goal_pose_stamped.pose = goal_pose;
178181

179182
// Convert route.
180183
LaneletRoute route;
181184
route.start_pose = odometry_->pose.pose;
182-
route.goal_pose = transform_pose(goal_pose).pose;
183-
for (const auto & segment : req->segments) {
185+
route.goal_pose = transform_pose(goal_pose_stamped).pose;
186+
for (const auto & segment : route_segments) {
184187
route.segments.push_back(convert(segment));
185188
}
186-
route.header.stamp = req->header.stamp;
189+
route.header.stamp = header.stamp;
187190
route.header.frame_id = map_frame_;
188191
route.uuid.uuid = generate_random_id();
189-
route.allow_modification = req->option.allow_goal_modification;
192+
route.allow_modification = allow_goal_modification;
190193

191194
return route;
192195
}
193196

194-
LaneletRoute MissionPlanner::create_route(const SetRoutePoints::Service::Request::SharedPtr req)
197+
LaneletRoute MissionPlanner::create_route(
198+
const std_msgs::msg::Header & header, const std::vector<geometry_msgs::msg::Pose> & waypoints,
199+
const geometry_msgs::msg::Pose & goal_pose, const bool allow_goal_modification)
195200
{
196-
using ResponseCode = autoware_adapi_v1_msgs::srv::SetRoute::Response;
197-
198201
// Use temporary pose stamped for transform.
199202
PoseStamped pose;
200-
pose.header = req->header;
203+
pose.header = header;
201204

202205
// Convert route points.
203206
PlannerPlugin::RoutePoints points;
204207
points.push_back(odometry_->pose.pose);
205-
for (const auto & waypoint : req->waypoints) {
208+
for (const auto & waypoint : waypoints) {
206209
pose.pose = waypoint;
207210
points.push_back(transform_pose(pose).pose);
208211
}
209-
pose.pose = req->goal;
212+
pose.pose = goal_pose;
210213
points.push_back(transform_pose(pose).pose);
211214

212215
// Plan route.
213216
LaneletRoute route = planner_->plan(points);
214-
if (route.segments.empty()) {
215-
throw component_interface_utils::ServiceException(
216-
ResponseCode::ERROR_PLANNER_FAILED, "The planned route is empty.");
217-
}
218-
route.header.stamp = req->header.stamp;
217+
route.header.stamp = header.stamp;
219218
route.header.frame_id = map_frame_;
220219
route.uuid.uuid = generate_random_id();
221-
route.allow_modification = req->option.allow_goal_modification;
220+
route.allow_modification = allow_goal_modification;
222221

223222
return route;
224223
}
225224

225+
LaneletRoute MissionPlanner::create_route(const SetRoute::Service::Request::SharedPtr req)
226+
{
227+
const auto & header = req->header;
228+
const auto & route_segments = req->segments;
229+
const auto & goal_pose = req->goal;
230+
const auto & allow_goal_modification = req->option.allow_goal_modification;
231+
232+
return create_route(header, route_segments, goal_pose, allow_goal_modification);
233+
}
234+
235+
LaneletRoute MissionPlanner::create_route(const SetRoutePoints::Service::Request::SharedPtr req)
236+
{
237+
const auto & header = req->header;
238+
const auto & waypoints = req->waypoints;
239+
const auto & goal_pose = req->goal;
240+
const auto & allow_goal_modification = req->option.allow_goal_modification;
241+
242+
return create_route(header, waypoints, goal_pose, allow_goal_modification);
243+
}
244+
226245
void MissionPlanner::change_state(RouteState::Message::_state_type state)
227246
{
228247
state_.stamp = now();
@@ -249,6 +268,10 @@ void MissionPlanner::on_set_route(
249268
throw component_interface_utils::ServiceException(
250269
ResponseCode::ERROR_ROUTE_EXISTS, "The route is already set.");
251270
}
271+
if (!planner_->ready()) {
272+
throw component_interface_utils::ServiceException(
273+
ResponseCode::ERROR_PLANNER_UNREADY, "The planner is not ready.");
274+
}
252275
if (!odometry_) {
253276
throw component_interface_utils::ServiceException(
254277
ResponseCode::ERROR_PLANNER_UNREADY, "The vehicle pose is not received.");
@@ -257,6 +280,12 @@ void MissionPlanner::on_set_route(
257280
// Convert request to a new route.
258281
const auto route = create_route(req);
259282

283+
// Check planned routes
284+
if (route.segments.empty()) {
285+
throw component_interface_utils::ServiceException(
286+
ResponseCode::ERROR_PLANNER_FAILED, "The planned route is empty.");
287+
}
288+
260289
// Update route.
261290
change_route(route);
262291
change_state(RouteState::Message::SET);
@@ -287,6 +316,12 @@ void MissionPlanner::on_set_route_points(
287316
// Plan route.
288317
const auto route = create_route(req);
289318

319+
// Check planned routes
320+
if (route.segments.empty()) {
321+
throw component_interface_utils::ServiceException(
322+
ResponseCode::ERROR_PLANNER_FAILED, "The planned route is empty.");
323+
}
324+
290325
// Update route.
291326
change_route(route);
292327
change_state(RouteState::Message::SET);
@@ -329,28 +364,45 @@ void MissionPlanner::on_change_route(
329364
throw component_interface_utils::ServiceException(
330365
ResponseCode::ERROR_INVALID_STATE, "The route hasn't set yet. Cannot reroute.");
331366
}
367+
if (!planner_->ready()) {
368+
throw component_interface_utils::ServiceException(
369+
ResponseCode::ERROR_PLANNER_UNREADY, "The planner is not ready.");
370+
}
332371
if (!odometry_) {
333372
throw component_interface_utils::ServiceException(
334373
ResponseCode::ERROR_PLANNER_UNREADY, "The vehicle pose is not received.");
335374
}
375+
if (!normal_route_) {
376+
throw component_interface_utils::ServiceException(
377+
ResponseCode::ERROR_PLANNER_UNREADY, "Normal route is not set.");
378+
}
336379

337380
// set to changing state
338381
change_state(RouteState::Message::CHANGING);
339382

340383
// Convert request to a new route.
341384
const auto new_route = create_route(req);
342385

386+
// Check planned routes
387+
if (new_route.segments.empty()) {
388+
change_route(*normal_route_);
389+
change_state(RouteState::Message::SET);
390+
res->status.success = false;
391+
throw component_interface_utils::ServiceException(
392+
ResponseCode::ERROR_PLANNER_FAILED, "The planned route is empty.");
393+
}
394+
343395
// check route safety
344396
if (checkRerouteSafety(*normal_route_, new_route)) {
345397
// sucess to reroute
346398
change_route(new_route);
347-
change_state(RouteState::Message::SET);
348399
res->status.success = true;
400+
change_state(RouteState::Message::SET);
349401
} else {
350402
// failed to reroute
351403
change_route(*normal_route_);
352-
change_state(RouteState::Message::SET);
353404
res->status.success = false;
405+
change_state(RouteState::Message::SET);
354406
throw component_interface_utils::ServiceException(
355407
ResponseCode::ERROR_REROUTE_FAILED, "New route is not safe. Reroute failed.");
356408
}
@@ -375,23 +427,36 @@ void MissionPlanner::on_change_route_points(
375427
throw component_interface_utils::ServiceException(
376428
ResponseCode::ERROR_PLANNER_UNREADY, "The vehicle pose is not received.");
377429
}
430+
if (!normal_route_) {
431+
throw component_interface_utils::ServiceException(
432+
ResponseCode::ERROR_PLANNER_UNREADY, "Normal route is not set.");
433+
}
378434

379435
change_state(RouteState::Message::CHANGING);
380436

381437
// Plan route.
382438
const auto new_route = create_route(req);
383439

440+
// Check planned routes
441+
if (new_route.segments.empty()) {
442+
change_state(RouteState::Message::SET);
443+
change_route(*normal_route_);
444+
res->status.success = false;
445+
throw component_interface_utils::ServiceException(
446+
ResponseCode::ERROR_PLANNER_FAILED, "The planned route is empty.");
447+
}
448+
384449
// check route safety
385450
if (checkRerouteSafety(*normal_route_, new_route)) {
386451
// sucess to reroute
387452
change_route(new_route);
388-
change_state(RouteState::Message::SET);
389453
res->status.success = true;
454+
change_state(RouteState::Message::SET);
390455
} else {
391456
// failed to reroute
392457
change_route(*normal_route_);
393-
change_state(RouteState::Message::SET);
394458
res->status.success = false;
459+
change_state(RouteState::Message::SET);
395460
throw component_interface_utils::ServiceException(
396461
ResponseCode::ERROR_REROUTE_FAILED, "New route is not safe. Reroute failed.");
397462
}

planning/mission_planner/src/mission_planner/mission_planner.hpp

+7
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,13 @@ class MissionPlanner : public rclcpp::Node
7878
void change_route(const LaneletRoute & route);
7979
LaneletRoute create_route(const SetRoute::Service::Request::SharedPtr req);
8080
LaneletRoute create_route(const SetRoutePoints::Service::Request::SharedPtr req);
81+
LaneletRoute create_route(
82+
const std_msgs::msg::Header & header,
83+
const std::vector<autoware_adapi_v1_msgs::msg::RouteSegment> & route_segments,
84+
const geometry_msgs::msg::Pose & goal_pose, const bool allow_goal_modification);
85+
LaneletRoute create_route(
86+
const std_msgs::msg::Header & header, const std::vector<geometry_msgs::msg::Pose> & waypoints,
87+
const geometry_msgs::msg::Pose & goal_pose, const bool allow_goal_modification);
8188

8289
RouteState::Message state_;
8390
component_interface_utils::Publisher<RouteState>::SharedPtr pub_state_;

0 commit comments

Comments
 (0)