Skip to content

Commit 36d9d3e

Browse files
authored
Rework PipelinePlanner creation (#249)
- Moved Task::createPlanner into PipelinePlanner::create - Handle mutiple planner pipeline configs as introduced in moveit/moveit#2127
1 parent 4ee7188 commit 36d9d3e

File tree

4 files changed

+76
-53
lines changed

4 files changed

+76
-53
lines changed

core/include/moveit/task_constructor/solvers/pipeline_planner.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,23 @@ MOVEIT_CLASS_FORWARD(PipelinePlanner)
5555
class PipelinePlanner : public PlannerInterface
5656
{
5757
public:
58-
PipelinePlanner();
58+
struct Specification
59+
{
60+
moveit::core::RobotModelConstPtr model;
61+
std::string ns{ "move_group" };
62+
std::string pipeline{ "ompl" };
63+
std::string adapter_param{ "request_adapters" };
64+
};
65+
66+
static planning_pipeline::PlanningPipelinePtr create(const moveit::core::RobotModelConstPtr& model) {
67+
Specification spec;
68+
spec.model = model;
69+
return create(spec);
70+
}
71+
72+
static planning_pipeline::PlanningPipelinePtr create(const Specification& spec);
73+
74+
PipelinePlanner(const std::string& pipeline = "ompl");
5975

6076
PipelinePlanner(const planning_pipeline::PlanningPipelinePtr& planning_pipeline);
6177

@@ -73,6 +89,7 @@ class PipelinePlanner : public PlannerInterface
7389
const moveit_msgs::Constraints& path_constraints = moveit_msgs::Constraints()) override;
7490

7591
protected:
92+
std::string pipeline_name_;
7693
planning_pipeline::PlanningPipelinePtr planner_;
7794
};
7895
} // namespace solvers

core/include/moveit/task_constructor/task.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,6 @@ class Task : protected WrapperBase
7373
public:
7474
PRIVATE_CLASS(Task)
7575

76-
// +1 TODO: move into MoveIt core
77-
static planning_pipeline::PlanningPipelinePtr
78-
createPlanner(const moveit::core::RobotModelConstPtr& model, const std::string& ns = "move_group",
79-
const std::string& planning_plugin_param_name = "planning_plugin",
80-
const std::string& adapter_plugins_param_name = "request_adapters");
8176
Task(const std::string& ns = "", bool introspection = true,
8277
ContainerBase::pointer&& container = std::make_unique<SerialContainer>("task pipeline"));
8378
Task(Task&& other); // NOLINT(performance-noexcept-move-constructor)

core/src/solvers/pipeline_planner.cpp

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,60 @@ namespace moveit {
4848
namespace task_constructor {
4949
namespace solvers {
5050

51-
PipelinePlanner::PipelinePlanner() {
51+
struct PlannerCache
52+
{
53+
using PlannerID = std::tuple<std::string, std::string>;
54+
using PlannerMap = std::map<PlannerID, std::weak_ptr<planning_pipeline::PlanningPipeline> >;
55+
using ModelList = std::list<std::pair<std::weak_ptr<const robot_model::RobotModel>, PlannerMap> >;
56+
ModelList cache_;
57+
58+
PlannerMap::mapped_type& retrieve(const robot_model::RobotModelConstPtr& model, const PlannerID& id) {
59+
// find model in cache_ and remove expired entries while doing so
60+
ModelList::iterator model_it = cache_.begin();
61+
while (model_it != cache_.end()) {
62+
if (model_it->first.expired()) {
63+
model_it = cache_.erase(model_it);
64+
continue;
65+
}
66+
if (model_it->first.lock() == model)
67+
break;
68+
++model_it;
69+
}
70+
if (model_it == cache_.end()) // if not found, create a new PlannerMap for this model
71+
model_it = cache_.insert(cache_.begin(), std::make_pair(model, PlannerMap()));
72+
73+
return model_it->second.insert(std::make_pair(id, PlannerMap::mapped_type())).first->second;
74+
}
75+
};
76+
77+
planning_pipeline::PlanningPipelinePtr PipelinePlanner::create(const PipelinePlanner::Specification& spec) {
78+
static PlannerCache cache;
79+
80+
constexpr char const* PLUGIN_PARAMETER_NAME = "planning_plugin";
81+
82+
std::string pipeline_ns = spec.ns + "/planning_pipelines/" + spec.pipeline;
83+
// fallback to old structure for pipeline parameters in MoveIt
84+
if (!ros::NodeHandle(pipeline_ns).hasParam(PLUGIN_PARAMETER_NAME)) {
85+
ROS_WARN("Failed to find '%s/%s'. %s", pipeline_ns.c_str(), PLUGIN_PARAMETER_NAME,
86+
"Attempting to load pipeline from old parameter structure. Please update your MoveIt config.");
87+
pipeline_ns = spec.ns;
88+
}
89+
90+
PlannerCache::PlannerID id(pipeline_ns, spec.adapter_param);
91+
92+
std::weak_ptr<planning_pipeline::PlanningPipeline>& entry = cache.retrieve(spec.model, id);
93+
planning_pipeline::PlanningPipelinePtr planner = entry.lock();
94+
if (!planner) {
95+
// create new entry
96+
planner = std::make_shared<planning_pipeline::PlanningPipeline>(spec.model, ros::NodeHandle(pipeline_ns),
97+
PLUGIN_PARAMETER_NAME, spec.adapter_param);
98+
// store in cache
99+
entry = planner;
100+
}
101+
return planner;
102+
}
103+
104+
PipelinePlanner::PipelinePlanner(const std::string& pipeline_name) : pipeline_name_{ pipeline_name } {
52105
auto& p = properties();
53106
p.declare<std::string>("planner", "", "planner id");
54107

@@ -73,7 +126,10 @@ PipelinePlanner::PipelinePlanner(const planning_pipeline::PlanningPipelinePtr& p
73126

74127
void PipelinePlanner::init(const core::RobotModelConstPtr& robot_model) {
75128
if (!planner_) {
76-
planner_ = Task::createPlanner(robot_model);
129+
Specification spec;
130+
spec.model = robot_model;
131+
spec.pipeline = pipeline_name_;
132+
planner_ = create(spec);
77133
} else if (robot_model != planner_->getRobotModel()) {
78134
throw std::runtime_error(
79135
"The robot model of the planning pipeline isn't the same as the task's robot model -- "

core/src/task.cpp

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -126,51 +126,6 @@ Task& Task::operator=(Task&& other) { // NOLINT(performance-noexcept-move-const
126126
return *this;
127127
}
128128

129-
struct PlannerCache
130-
{
131-
using PlannerID = std::tuple<std::string, std::string, std::string>;
132-
using PlannerMap = std::map<PlannerID, std::weak_ptr<planning_pipeline::PlanningPipeline> >;
133-
using ModelList = std::list<std::pair<std::weak_ptr<const robot_model::RobotModel>, PlannerMap> >;
134-
ModelList cache_;
135-
136-
PlannerMap::mapped_type& retrieve(const robot_model::RobotModelConstPtr& model, const PlannerID& id) {
137-
// find model in cache_ and remove expired entries while doing so
138-
ModelList::iterator model_it = cache_.begin();
139-
while (model_it != cache_.end()) {
140-
if (model_it->first.expired()) {
141-
model_it = cache_.erase(model_it);
142-
continue;
143-
}
144-
if (model_it->first.lock() == model)
145-
break;
146-
++model_it;
147-
}
148-
if (model_it == cache_.end()) // if not found, create a new PlannerMap for this model
149-
model_it = cache_.insert(cache_.begin(), std::make_pair(model, PlannerMap()));
150-
151-
return model_it->second.insert(std::make_pair(id, PlannerMap::mapped_type())).first->second;
152-
}
153-
};
154-
155-
planning_pipeline::PlanningPipelinePtr Task::createPlanner(const robot_model::RobotModelConstPtr& model,
156-
const std::string& ns,
157-
const std::string& planning_plugin_param_name,
158-
const std::string& adapter_plugins_param_name) {
159-
static PlannerCache cache;
160-
PlannerCache::PlannerID id(ns, planning_plugin_param_name, adapter_plugins_param_name);
161-
162-
std::weak_ptr<planning_pipeline::PlanningPipeline>& entry = cache.retrieve(model, id);
163-
planning_pipeline::PlanningPipelinePtr planner = entry.lock();
164-
if (!planner) {
165-
// create new entry
166-
planner = std::make_shared<planning_pipeline::PlanningPipeline>(
167-
model, ros::NodeHandle(ns), planning_plugin_param_name, adapter_plugins_param_name);
168-
// store in cache
169-
entry = planner;
170-
}
171-
return planner;
172-
}
173-
174129
Task::~Task() {
175130
auto impl = pimpl();
176131
impl->introspection_.reset(); // stop introspection

0 commit comments

Comments
 (0)