Skip to content
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

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
35 changes: 34 additions & 1 deletion moveit_ros/planning/planning_pipeline/src/planning_pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -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_)
{
Expand All @@ -288,11 +295,24 @@ bool PlanningPipeline::generatePlan(const planning_scene::PlanningSceneConstPtr&
req_adapter->getDescription().c_str(), status.message.c_str());
break;
}

// check for timeout
Copy link
Contributor

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

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)
Expand Down Expand Up @@ -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)
Copy link
Contributor

Choose a reason for hiding this comment

The 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 allowed_planning_time 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The 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
Expand All @@ -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;
}
}
}
}
Expand Down
Loading