Backport: Planning with multiple pipelines in parallel with moveit_cpp#3244
Backport: Planning with multiple pipelines in parallel with moveit_cpp#3244rhaschke merged 26 commits intomoveit:masterfrom
Conversation
|
Thanks for helping in improving MoveIt and open source robotics! |
Codecov ReportBase: 62.03% // Head: 61.82% // Decreases project coverage by
Additional details and impacted files@@ Coverage Diff @@
## master #3244 +/- ##
==========================================
- Coverage 62.03% 61.82% -0.21%
==========================================
Files 377 378 +1
Lines 33268 33373 +105
==========================================
- Hits 20636 20630 -6
- Misses 12632 12743 +111
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
Downgrade log from ERROR to INFO
|
We've been using this a lot and I can attest that it's AWESOME! I'm going to review it over at MoveIt2, though, so I don't review twice. |
rhaschke
left a comment
There was a problem hiding this comment.
I have a handful of remarks. The most important one is the API incompatibility with existing PlannerManager plugins. While you might break API in ROS2, we shouldn't do so in ROS1.
moveit_core/planning_interface/include/moveit/planning_interface/planning_interface.h
Outdated
Show resolved
Hide resolved
| double planning_time_; | ||
| moveit_msgs::MoveItErrorCodes error_code_; | ||
| moveit::core::MoveItErrorCode error_code_; | ||
| moveit_msgs::RobotState start_state_; |
There was a problem hiding this comment.
As far as I could see, both start_state_ and planner_id_ are not actually used. What's the purpose of these fields?
There was a problem hiding this comment.
It is possible to pass an optional solution_selection_callback and/or a stopping_criterion_function both use the produced MotionPlanResponses to make a decision and these to additional fields might be useful to make that decision. For example
bool stoppingCriterionCallBack(
moveit_cpp::PlanningComponent::PlanSolutions const& plan_solutions,
moveit_cpp::PlanningComponent::MultiPipelinePlanRequestParameters const& plan_request_parameters)
for (auto const& solution : solutions)
{
// Stop parallel planning if PILZ found a solution
if (solution.planner_id_ == "LIN")
{
return true;
}
}
return false;
}There was a problem hiding this comment.
I agree for the planner_id_, but all plans share the very same start state, don't they?
Please add a comment, e.g. "planner this solution originates from".
There was a problem hiding this comment.
That's true, it does not matter for the solution selection. I added it since the MotionPlanResponse message has a similar field and it can be useful when the MotionPlanResponse is processed further independent from moveit_cpp/ the planning_component. Do you think we should remove it or is a comment sufficient?
There was a problem hiding this comment.
I'm not sure yet. If the start state is identical for all solutions, saving it here would be a waste of memory.
However, due to different pipeline configs, modifying the start state (or not), the actual start state might differ between solutions (but I don't know by heart). That would be an argument to keep it here...
There was a problem hiding this comment.
I'd remove the underscore from the field names but you're right, the API will be broken by this. I can open a PR for moveit_tutorials to fix this. Would MTC be affected?
I'm not only worried about moveit_tutorials or MTC. The problem is that any user code out there accessing those members will be affected by this change! At least we should provide a deprecation period for transition.
My suggestion is to:
- remove the underscores
- provide additional, deprecated members with the underscore as const references to the new members:
Obviously, those references need to be initialized in the constructor. This will render the struct read-only. So you will need to provide a custom copy constructor and assignment operator as well.
moveit_msgs::RobotState start_state; [[deprecated("Use start_state instead.")]] const moveit_msgs::RobotState& start_state_;
| std::vector<double> processing_time_; | ||
| moveit_msgs::MoveItErrorCodes error_code_; | ||
| moveit::core::MoveItErrorCode error_code_; | ||
| moveit_msgs::RobotState start_state_; |
| const planning_interface::PlannerConfigurationSettings planner_config_settings{ | ||
| group, group, std::map<std::string, std::string>() | ||
| }; | ||
| pconfig[planner_config_settings.name] = planner_config_settings; | ||
| } | ||
| setPlannerConfigurations(pconfig); |
There was a problem hiding this comment.
What's the purpose of setting these empty planner configs?
There was a problem hiding this comment.
Isn't it only empty when the robot model does not have any JointModelGroups? The line above adds for each joint model group settings
There was a problem hiding this comment.
But those settings are simply empty: <std::string, std::string>()
| void setPlannerConfigurations(const planning_interface::PlannerConfigurationMap& pcs) override | ||
| { | ||
| config_settings_ = pcs; | ||
| } |
There was a problem hiding this comment.
Maybe introduce this as the default implementation of PlannerManager?
There was a problem hiding this comment.
Personally, I'd like to remind the person that implements a new planner plugin to think about the planner config and forcing them to implement this function would be a good way. But I can make this a default implementation if you don't like that
There was a problem hiding this comment.
I understand your reasoning and for MoveIt2 it is probably the right way to go.
For MoveIt1, I personally think we should maintain API stability. Other maintainers might have a different opinion.
There was a problem hiding this comment.
Reverting this will be required for CI to pass...
There was a problem hiding this comment.
Ok, let's do it that way then 👍
moveit_ros/planning/moveit_cpp/include/moveit/moveit_cpp/moveit_cpp.h
Outdated
Show resolved
Hide resolved
moveit_ros/planning/moveit_cpp/include/moveit/moveit_cpp/planning_component.h
Outdated
Show resolved
Hide resolved
moveit_ros/planning/planning_pipeline/include/moveit/planning_pipeline/planning_pipeline.h
Outdated
Show resolved
Hide resolved
Co-authored-by: Robert Haschke <rhaschke@users.noreply.github.com>
|
This PR had several clang-tidy warnings. Don't you have clang-tidy checks enabled anymore for MoveIt2? |
|
How did you handle the API-incompatible member renamings in MoveIt2?? |
Since MotionPlanResponse is a struct and all member variables are public the _ underscore naming convention for private member variables is not correctly used here anyway's. In moveit2 we opened an additional issue to fix this but I can included into this pr for simplicity's sake |
|
Yes, moveit2 uses clang-tidy but the related clang-tidy check is disabled moveit/moveit2#214 |
I still don't know how you solved it in MoveIt2. Please add a reference.
Depends on the solution approach you took. I don't yet see how this can be fixed in a fashion not breaking API for somebody. |
279038b to
c72ca11
Compare
rhaschke
left a comment
There was a problem hiding this comment.
There is still a lot of redundancy. Can you handle the missing config settings in moveitcpp instead?
|
|
||
| // Construct default configurations for planning groups that don't have configs already passed in. This is necessary | ||
| // since moveit_cpp can only use planners with a config for a given joint group | ||
| for (const moveit::core::JointModelGroup* group : robot_model_->getJointModelGroups()) | ||
| { | ||
| if (config_settings_.find(group->getName()) == config_settings_.end()) | ||
| { | ||
| planning_interface::PlannerConfigurationSettings empty_config; | ||
| empty_config.name = empty_config.group = group->getName(); | ||
| config_settings_[empty.name] = empty; | ||
| } | ||
| } |
There was a problem hiding this comment.
Why did you decide to initialize settings for "missing" groups here instead of in PlannerManager::initialize as suggested here?
There was a problem hiding this comment.
Sorry, you reviewed to fast, that change did not work. The problem is that initialize() function can easily be overwritten and thus compatibility with moveit_cpp be destroyed. The way I implemented it would have added a default empty config for all planning plugins with setPlannerConfigurations. But that did not work because the robot model is not available in this function.
I think the planner plugins should be modified because the flaw right now is that pconfig is not used correctly (as expected by moveit_cpp) by the plugins. If we hide this implementation detail away in the base class, I fear future plugin implementations will repeat the same error,
There was a problem hiding this comment.
pconfig is not used correctly (as expected by moveit_cpp) by the plugins.
Can you please detail this? As far as I can see, moveit_cpp just generates a "shortcut" map from these configs.
If there are no config settings, why should a plugin declare them as empty? I think we should first agree on the semantics, before implementing anything further...
There was a problem hiding this comment.
My preference would be to use the current solution and open an issue to re-evaluate the PlannerConfigurationSettings, since it is only properly used by OMPL at the moment. Maybe it would be better to remove/refactor it and the pipeline detection in moveit_cpp but I think this is out of the scope of this PR.
There was a problem hiding this comment.
From: moveit/moveit2#1522
When the plan() method of the planning component gets called, all available planning pipelines are searched based on their name [1]. These names are provided by moveit_cpp [2]. The moveit_cpp function that provides the planning pipeline names reads them from an internal map [3]. A planning pipelines needs to have a planner plugin that has a PlannerConfiguration in order to be added to this map [4].
| } | ||
|
|
||
| setPlannerConfigurations(pconfig); | ||
| context_manager_.setPlannerConfigurations(pconfig); |
There was a problem hiding this comment.
Why does the OMPL planner use a different approach to configure settings?
I would expect a similar approach to other planners, i.e. calling setPlannerConfigurations(pconfig).
There was a problem hiding this comment.
I like the way, ompl defined a default setPlannerConfigurations implementation to add empty configs for joint model groups and moved that implementation into the base class. But that did not work
| moveit_msgs::RobotState start_state; | ||
| std::string planner_id; | ||
|
|
||
| [[deprecated("Use trajectory instead.")]] robot_trajectory::RobotTrajectoryPtr& trajectory_; |
There was a problem hiding this comment.
@rhaschke Probably I am doing something wrong, but if I make these references const, the API breaks again. Do I miss something here?
…plementation" This reverts commit c72ca11.
This reverts commit 5fd520f.
This reverts commit 8f96165.
- reverse naming: - underscore_ members stay the default - (deprecated) non_underscore members are added for API compatibility - add deprecated start_state member - avoid code duplication between copy constructor and copy assignment
This is a backport of moveit/moveit2#1710, dropping function getPlanningPipelineNames().
This member is not needed anymore.
rhaschke
left a comment
There was a problem hiding this comment.
If the latest version passes CI, I'm fine with the current state.
|
👍 Thanks a lot for your help to get this merged! |
|
Congrats on getting your first MoveIt pull request merged and improving open source robotics! |
I think it would be a good idea to add some notes on the API change there. @sjahr |
|
@rhaschke @sjahr I might misunderstand something just perusing this thread, but I just ran into these deprecations and they are the inverted logic of what was discussed throughout this thread. It recommends the historical |
|
This PR removed the rather new data structure |
|
Thanks for the explanation. Not great to keep the legacy annotation |
|
Our naming rules enforce the underscore: Why do you claim this notation legacy? |
Somewhat a mix of personal opinion, conventions I know and the |
|
There are Public, Protected, and Private variants for all rules. So we could remove the suffix for public members... I have triggered a corresponding build: https://github.com/ros-planning/moveit/actions/runs/4005320877 |
* Fix old-style-cast * Fix deprecated member names (due to moveit/moveit#3244) * Enable -Werror
Description
This is a backport of the parallel planning API for moveit_cpp from moveit2#1420.
This PR adds:
Usage example:
config.yaml
demo_node.cpp
Checklist