Skip to content

Commit 823899f

Browse files
committed
Propagate errors from planners
1 parent 2ffacf8 commit 823899f

File tree

6 files changed

+43
-12
lines changed

6 files changed

+43
-12
lines changed

core/src/solvers/cartesian_path.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ tl::expected<bool, std::string> CartesianPath::plan(const planning_scene::Planni
7171
const moveit::core::LinkModel* link = jmg->getOnlyOneEndEffectorTip();
7272
if (!link) {
7373
RCLCPP_WARN_STREAM(LOGGER, "no unique tip for joint model group: " << jmg->getName());
74-
return false;
74+
return tl::make_unexpected("no unique tip for joint model group: " + jmg->getName());
7575
}
7676

7777
// reach pose of forward kinematics
@@ -116,7 +116,10 @@ tl::expected<bool, std::string> CartesianPath::plan(const planning_scene::Planni
116116
timing->computeTimeStamps(*result, props.get<double>("max_velocity_scaling_factor"),
117117
props.get<double>("max_acceleration_scaling_factor"));
118118

119-
return achieved_fraction >= props.get<double>("min_fraction");
119+
if (achieved_fraction >= props.get<double>("min_fraction")) {
120+
return tl::make_unexpected("Min fraction not met. Achieved fraction : " + std::to_string(achieved_fraction));
121+
}
122+
return true;
120123
}
121124
} // namespace solvers
122125
} // namespace task_constructor

core/src/solvers/joint_interpolation.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ tl::expected<bool, std::string> JointInterpolationPlanner::plan(
7777
// add first point
7878
result->addSuffixWayPoint(from->getCurrentState(), 0.0);
7979
if (from->isStateColliding(from_state, jmg->getName()) || !from_state.satisfiesBounds(jmg))
80-
return false;
80+
return tl::make_unexpected("Start state in collision or not within bounds");
8181

8282
moveit::core::RobotState waypoint(from_state);
8383
double delta = d < 1e-6 ? 1.0 : props.get<double>("max_step") / d;
@@ -86,13 +86,13 @@ tl::expected<bool, std::string> JointInterpolationPlanner::plan(
8686
result->addSuffixWayPoint(waypoint, t);
8787

8888
if (from->isStateColliding(waypoint, jmg->getName()) || !waypoint.satisfiesBounds(jmg))
89-
return false;
89+
return tl::make_unexpected("One of the waypoint's state is in collision or not within bounds");
9090
}
9191

9292
// add goal point
9393
result->addSuffixWayPoint(to_state, 1.0);
9494
if (from->isStateColliding(to_state, jmg->getName()) || !to_state.satisfiesBounds(jmg))
95-
return false;
95+
return tl::make_unexpected("Goal state in collision or not within bounds");
9696

9797
auto timing = props.get<TimeParameterizationPtr>("time_parameterization");
9898
timing->computeTimeStamps(*result, props.get<double>("max_velocity_scaling_factor"),
@@ -140,12 +140,12 @@ JointInterpolationPlanner::plan(const planning_scene::PlanningSceneConstPtr& fro
140140
// TODO(v4hn): planners need a way to add feedback to failing plans
141141
// in case of an invalid solution feedback should include unwanted collisions or violated constraints
142142
RCLCPP_WARN(LOGGER, "IK failed for pose target");
143-
return false;
143+
return tl::make_unexpected("IK failed for pose target");
144144
}
145145
to->getCurrentStateNonConst().update();
146146

147147
if (std::chrono::steady_clock::now() >= deadline)
148-
return false;
148+
return tl::make_unexpected("Timed out");
149149

150150
return plan(from, to, jmg, timeout, result, path_constraints);
151151
}

core/src/solvers/pipeline_planner.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,10 +224,16 @@ tl::expected<bool, std::string> PipelinePlanner::plan(const planning_scene::Plan
224224
// Choose the first solution trajectory as response
225225
result = solution.trajectory;
226226
last_successful_planner_ = solution.planner_id;
227-
return bool(result);
227+
if (!bool(result)) // If the plan was not a success
228+
{
229+
return tl::make_unexpected(solution.error_code.source + " returned error code " +
230+
moveit::core::errorCodeToString(solution.error_code) +
231+
". Reason : " + solution.error_code.message); // Maybe print the error code too
232+
}
233+
return true;
228234
}
229235
}
230-
return false;
236+
return tl::make_unexpected("No solutions generated from Pipeline Planner");
231237
}
232238
std::string PipelinePlanner::getPlannerId() const {
233239
return last_successful_planner_.empty() ? std::string("Unknown") : last_successful_planner_;

core/src/stages/connect.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ void Connect::compute(const InterfaceState& from, const InterfaceState& to) {
148148
intermediate_scenes.push_back(start);
149149

150150
bool success = false;
151+
std::string error_message = "";
151152
std::vector<double> positions;
152153
for (const GroupPlannerVector::value_type& pair : planner_) {
153154
// set intermediate goal state
@@ -164,6 +165,10 @@ void Connect::compute(const InterfaceState& from, const InterfaceState& to) {
164165
if (planner_solution_maybe.has_value()) {
165166
success = planner_solution_maybe.value();
166167
}
168+
std::string error_message = "";
169+
if (!success) {
170+
error_message += planner_solution_maybe.error();
171+
}
167172
trajectory_planner_vector.push_back(PlannerIdTrajectoryPair({ pair.second->getPlannerId(), trajectory }));
168173

169174
if (!success)
@@ -179,7 +184,7 @@ void Connect::compute(const InterfaceState& from, const InterfaceState& to) {
179184
if (!solution) // success == false or merging failed: store sequentially
180185
solution = makeSequential(trajectory_planner_vector, intermediate_scenes, from, to);
181186
if (!success) // error during sequential planning
182-
solution->markAsFailure();
187+
solution->markAsFailure("Hardcode an error message");
183188

184189
connect(from, to, solution);
185190
}

core/src/stages/move_relative.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ bool MoveRelative::compute(const InterfaceState& state, planning_scene::Planning
195195

196196
robot_trajectory::RobotTrajectoryPtr robot_trajectory;
197197
bool success = false;
198+
std::string error_message = "";
198199

199200
if (getJointStateFromOffset(direction, dir, jmg, scene->getCurrentStateNonConst())) {
200201
// plan to joint-space target
@@ -203,6 +204,9 @@ bool MoveRelative::compute(const InterfaceState& state, planning_scene::Planning
203204
if (planner_solution_maybe.has_value()) {
204205
success = planner_solution_maybe.value();
205206
}
207+
if (!success) {
208+
error_message = planner_solution_maybe.error();
209+
}
206210
solution.setPlannerId(planner_->getPlannerId());
207211
} else {
208212
// Cartesian targets require an IK reference frame
@@ -295,6 +299,9 @@ bool MoveRelative::compute(const InterfaceState& state, planning_scene::Planning
295299
if (planner_solution_maybe.has_value()) {
296300
success = planner_solution_maybe.value();
297301
}
302+
if (!success) {
303+
error_message = planner_solution_maybe.error();
304+
}
298305
solution.setPlannerId(planner_->getPlannerId());
299306

300307
if (robot_trajectory) { // the following requires a robot_trajectory returned from planning
@@ -338,8 +345,11 @@ bool MoveRelative::compute(const InterfaceState& state, planning_scene::Planning
338345
robot_trajectory->reverse();
339346
solution.setTrajectory(robot_trajectory);
340347

341-
if (!success)
348+
if (!success && solution.comment().empty()) {
349+
solution.markAsFailure(error_message);
350+
} else if (!success) {
342351
solution.markAsFailure();
352+
}
343353
return true;
344354
}
345355
return false;

core/src/stages/move_to.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ bool MoveTo::compute(const InterfaceState& state, planning_scene::PlanningSceneP
205205
const auto& path_constraints = props.get<moveit_msgs::msg::Constraints>("path_constraints");
206206
robot_trajectory::RobotTrajectoryPtr robot_trajectory;
207207
bool success = false;
208+
std::string error_message = "";
208209

209210
if (getJointStateGoal(goal, jmg, scene->getCurrentStateNonConst())) {
210211
// plan to joint-space target
@@ -213,6 +214,9 @@ bool MoveTo::compute(const InterfaceState& state, planning_scene::PlanningSceneP
213214
if (planner_solution_maybe.has_value()) {
214215
success = planner_solution_maybe.value();
215216
}
217+
if (!success) {
218+
error_message = planner_solution_maybe.error();
219+
}
216220
solution.setPlannerId(planner_->getPlannerId());
217221
} else { // Cartesian goal
218222
// Where to go?
@@ -250,6 +254,9 @@ bool MoveTo::compute(const InterfaceState& state, planning_scene::PlanningSceneP
250254
if (planner_solution_maybe.has_value()) {
251255
success = planner_solution_maybe.value();
252256
}
257+
if (!success) {
258+
error_message = planner_solution_maybe.error();
259+
}
253260
solution.setPlannerId(planner_->getPlannerId());
254261
}
255262

@@ -266,7 +273,7 @@ bool MoveTo::compute(const InterfaceState& state, planning_scene::PlanningSceneP
266273
solution.setTrajectory(robot_trajectory);
267274

268275
if (!success)
269-
solution.markAsFailure();
276+
solution.markAsFailure(error_message);
270277

271278
return true;
272279
}

0 commit comments

Comments
 (0)