-
Notifications
You must be signed in to change notification settings - Fork 528
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make planning pipeline respect the allowed_planning_time #2692
base: main
Are you sure you want to change the base?
Changes from 1 commit
3930be6
e37e314
69b6de8
06377f7
167fb5e
99bf09c
cffe188
af3e30e
f903bd0
c2a5184
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,6 +37,9 @@ | |
#include <moveit/planning_pipeline/planning_pipeline.h> | ||
#include <fmt/format.h> | ||
#include <moveit/utils/logger.hpp> | ||
#include <chrono> | ||
#include <ratio> | ||
#include <stdexcept> | ||
|
||
namespace | ||
{ | ||
|
@@ -267,10 +270,14 @@ bool PlanningPipeline::generatePlan(const planning_scene::PlanningSceneConstPtr& | |
// --------------------------------- | ||
// Solve the motion planning problem | ||
// --------------------------------- | ||
|
||
planning_interface::MotionPlanRequest mutable_request = req; | ||
try | ||
{ | ||
using clock = std::chrono::system_clock; | ||
const auto timeout_error = std::runtime_error("allowed_planning_time exceeded"); | ||
const auto plan_start_time = clock::now(); | ||
const double allowed_planning_time = req.allowed_planning_time; | ||
|
||
// Call plan request adapter chain | ||
for (const auto& req_adapter : planning_request_adapter_vector_) | ||
{ | ||
|
@@ -288,11 +295,24 @@ bool PlanningPipeline::generatePlan(const planning_scene::PlanningSceneConstPtr& | |
req_adapter->getDescription().c_str(), status.message.c_str()); | ||
break; | ||
} | ||
|
||
// check for timeout | ||
if (std::chrono::duration<double>(clock::now() - plan_start_time).count() >= allowed_planning_time) | ||
{ | ||
throw timeout_error; | ||
sjahr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
|
||
// modify planner request to notice plugins of their corresponding max_allowed_time | ||
// NOTE: currently just evenly distributing the remaining time | ||
const double max_single_planner_time = std::chrono::duration<double>(clock::now() - plan_start_time).count() / | ||
pipeline_parameters_.planning_plugins.size(); | ||
mutable_request.allowed_planning_time = max_single_planner_time; | ||
|
||
// Call planners | ||
for (const auto& planner_name : pipeline_parameters_.planning_plugins) | ||
{ | ||
auto planner_start_time = clock::now(); | ||
const auto& planner = planner_map_.at(planner_name); | ||
// Update reference trajectory with latest solution (if available) | ||
if (res.trajectory) | ||
|
@@ -323,6 +343,13 @@ bool PlanningPipeline::generatePlan(const planning_scene::PlanningSceneConstPtr& | |
RCLCPP_ERROR(node_->get_logger(), "Planner '%s' failed", planner->getDescription().c_str()); | ||
break; | ||
} | ||
|
||
// TODO: should this be optional since the plugins already checked for timeout? | ||
// check for timeout | ||
if (std::chrono::duration<double>(clock::now() - planner_start_time).count() >= max_single_planner_time) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe I would even make sense to use the same check here as for the adapters if (std::chrono::duration<double>(clock::now() - plan_start_time).count() >= allowed_planning_time) I think we might not care too much about the individual elements exceeding their allocated individual budget (for now) but for the overall planning process to not exceed the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed. Especially because some planners will take longer, so splitting the timeout evenly seems risky. |
||
{ | ||
throw timeout_error; | ||
} | ||
} | ||
|
||
// Call plan response adapter chain | ||
|
@@ -342,6 +369,12 @@ bool PlanningPipeline::generatePlan(const planning_scene::PlanningSceneConstPtr& | |
res_adapter->getDescription().c_str()); | ||
break; | ||
} | ||
|
||
// check for timeout | ||
if (std::chrono::duration<double>(clock::now() - plan_start_time).count() >= allowed_planning_time) | ||
{ | ||
throw timeout_error; | ||
} | ||
} | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a note here that it is assumed that the request adapters only consume a very small fraction of the allowed planning time and thus they don't get a budget assigned. The timeout check is mainly a sanity check