gpp_plugin.hpp
Go to the documentation of this file.
1 /*
2  * MIT License
3  *
4  * Copyright (c) 2020 Dima Dorezyuk
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 
25 #pragma once
26 
30 #include <geometry_msgs/PoseStamped.h>
33 #include <pluginlib/class_loader.h>
34 #include <ros/ros.h>
35 
36 #include <memory>
37 #include <string>
38 #include <utility>
39 #include <vector>
40 
41 namespace gpp_plugin {
42 
48 template <typename _Plugin>
50  using type = _Plugin;
51  static const std::string package;
52  static const std::string base_class;
53 };
54 
55 // define shortcuts to the resource types
60 
61 // clang-format off
62 
63 // below the definition of the different plugins.
64 // we put it into the header, since this is part of the interface.
65 // extend here, if you want to load other types.
66 
67 // Preplanning specialization
68 template <>
69 const std::string PluginDefinition<PrePlanningInterface>::package = "gpp_interface";
70 
71 template <>
72 const std::string PluginDefinition<PrePlanningInterface>::base_class = "gpp_interface::PrePlanningInterface";
73 
74 // Preplanning specialization
75 template <>
76 const std::string PluginDefinition<PostPlanningInterface>::package = "gpp_interface";
77 
78 template <>
79 const std::string PluginDefinition<PostPlanningInterface>::base_class = "gpp_interface::PostPlanningInterface";
80 
81 // nav-core specialization
82 template <>
83 const std::string PluginDefinition<BaseGlobalPlanner>::package = "nav_core";
84 
85 template <>
86 const std::string PluginDefinition<BaseGlobalPlanner>::base_class = "nav_core::BaseGlobalPlanner";
87 
88 // mbf-costmap-core specialization
89 template <>
90 const std::string PluginDefinition<CostmapPlanner>::package = "mbf_costmap_core";
91 
92 template <>
93 const std::string PluginDefinition<CostmapPlanner>::base_class = "mbf_costmap_core::CostmapPlanner";
94 
95 // clang-format on
96 
97 // below the plugin loading machinery. the implementation is moved into cpp,
98 // since we provide the (only valid) template arguments at compile time.
99 
111 template <typename _Plugin>
112 struct PluginManager : public pluginlib::ClassLoader<_Plugin> {
113  // the defintion with compile-time package and base_class tags
116 
117  // this will get you a linker error, if you try to load unknown plugins
119 
120  virtual pluginlib::UniquePtr<_Plugin>
121  createCustomInstance(const std::string& _type) {
122  return Base::createUniqueInstance(_type);
123  }
124 };
125 
136  std::string name;
137  bool on_success_break = false;
138  bool on_failure_break = true;
139 };
140 
147 template <typename _Plugin>
148 struct PluginGroup {
149  // this class owns the plugin
150  using PluginPtr = typename pluginlib::UniquePtr<_Plugin>;
151 
152  using NamedPlugin = std::pair<PluginParameter, PluginPtr>;
153  using PluginMap = std::vector<NamedPlugin>;
154 
155  inline const PluginMap&
156  getPlugins() const noexcept {
157  return plugins_;
158  }
159 
160  inline const std::string&
161  getName() const noexcept {
162  return name_;
163  }
164 
165  inline const bool&
166  getDefaultValue() const noexcept {
167  return default_value_;
168  }
169 
170 protected:
172  std::string name_ = "undefined";
174 };
175 
189 template <typename _Plugin, typename _Functor>
190 bool
191 _runPlugins(const PluginGroup<_Plugin>& _grp, const _Functor& _func,
192  const std::atomic_bool& _cancel) {
193  const auto& plugins = _grp.getPlugins();
194  const std::string name = "[" + _grp.getName() + "]: ";
195  for (const auto& plugin : plugins) {
196  // allow the user to cancel the job
197  if (_cancel) {
198  ROS_INFO_STREAM(name << "cancelled");
199  return false;
200  }
201 
202  // tell my name
203  ROS_INFO_STREAM(name << "runs " << plugin.first.name);
204 
205  // run the impl, but don't die
206  if (!plugin.second || !_func(*plugin.second)) {
207  // we have failed - we can either abort or ignore
208  ROS_WARN_STREAM(name << "failed at " << plugin.first.name);
209  if (plugin.first.on_failure_break)
210  return false;
211  }
212  else if (plugin.first.on_success_break)
213  return true;
214  }
215  return _grp.getDefaultValue();
216 }
217 
219 template <typename _Plugin, typename _Functor>
220 bool
221 runPlugins(const PluginGroup<_Plugin>& _grp, const _Functor& _func,
222  const std::atomic_bool& _cancel) {
223  const auto result = _runPlugins(_grp, _func, _cancel);
224  // print a conditional warning
225  ROS_WARN_STREAM_COND(!result, "[gpp]: failed at group " << _grp.getName());
226  return result;
227 }
296 template <typename _Plugin>
297 struct ArrayPluginManager : public PluginManager<_Plugin>,
298  public PluginGroup<_Plugin> {
299  void
300  load(const std::string& _resource, ros::NodeHandle& _nh);
301 };
302 
303 // compile time specification of the ArrayPluginManager
307 
317  // define the interface types
318  using Pose = geometry_msgs::PoseStamped;
319  using Path = std::vector<Pose>;
321  using ImplPlanner = pluginlib::UniquePtr<CostmapPlanner>;
322 
326  explicit BaseGlobalPlannerWrapper(ImplPlanner&& _impl);
327 
328  bool
329  makePlan(const Pose& start, const Pose& goal, Path& plan) override;
330 
331  bool
332  makePlan(const Pose& start, const Pose& goal, Path& plan,
333  double& cost) override;
334 
335  void
336  initialize(std::string name, Map* costmap_ros) override;
337 
338 private:
340 };
341 
351 
352  // dont call this yourself
353  pluginlib::UniquePtr<BaseGlobalPlanner>
354  createCustomInstance(const std::string& _type) override;
355 
356 private:
358 };
359 
410 struct GppPlugin : public BaseGlobalPlanner, public CostmapPlanner {
411  // define our interface types
412  using Pose = geometry_msgs::PoseStamped;
413  using Path = std::vector<Pose>;
415 
416  bool
417  makePlan(const Pose& _start, const Pose& _goal, Path& _plan) override;
418 
419  bool
420  makePlan(const Pose& _start, const Pose& _goal, Path& _plan,
421  double& _cost) override;
422 
423  uint32_t
424  makePlan(const Pose& start, const Pose& goal, double tolerance, Path& plan,
425  double& cost, std::string& message) override;
426  void
427  initialize(std::string name, Map* costmap_ros) override;
428 
429  bool
430  cancel() override;
431 
432 private:
433  bool
434  prePlanning(Pose& _start, Pose& _goal);
435 
436  bool
437  postPlanning(const Pose& _start, const Pose& _goal, Path& _path,
438  double& _cost);
439 
440  bool
441  globalPlanning(const Pose& _start, const Pose& _goal, Path& _plan,
442  double& _cost);
443 
444  std::atomic_bool cancel_;
445 
446  // nav_core conforming members
447  std::string name_;
448  Map* costmap_ = nullptr;
449 
453 };
454 
455 } // namespace gpp_plugin
gpp_plugin::PluginGroup::plugins_
PluginMap plugins_
Definition: gpp_plugin.hpp:173
class_loader.h
gpp_plugin::PluginDefinition
POD defining the meta information required to load a plugin.
Definition: gpp_plugin.hpp:49
gpp_plugin::BaseGlobalPlannerWrapper::BaseGlobalPlannerWrapper
BaseGlobalPlannerWrapper(ImplPlanner &&_impl)
our c'tor
Definition: gpp_plugin.cpp:151
ros.h
gpp_plugin::BaseGlobalPlannerWrapper::impl_
ImplPlanner impl_
Definition: gpp_plugin.hpp:339
gpp_plugin::CostmapPlannerManager::createCustomInstance
pluginlib::UniquePtr< BaseGlobalPlanner > createCustomInstance(const std::string &_type) override
Definition: gpp_plugin.cpp:185
gpp_plugin::PluginDefinition::type
_Plugin type
Definition: gpp_plugin.hpp:50
gpp_plugin::PluginGroup::name_
std::string name_
Definition: gpp_plugin.hpp:172
gpp_plugin::GppPlugin::post_planning_
PostPlanningManager post_planning_
Definition: gpp_plugin.hpp:451
pre_planning_interface.hpp
gpp_plugin::GppPlugin::cancel
bool cancel() override
Definition: gpp_plugin.cpp:292
gpp_plugin::PluginDefinition::base_class
static const std::string base_class
Definition: gpp_plugin.hpp:52
gpp_plugin::GppPlugin::global_planning_
CostmapPlannerManager global_planning_
Definition: gpp_plugin.hpp:452
gpp_plugin::BaseGlobalPlannerWrapper
Wrappes the CostmapPlaner API into the traditional BaseGlobalPlanner API.
Definition: gpp_plugin.hpp:316
gpp_plugin::PluginGroup< PrePlanningInterface >::PluginPtr
typename pluginlib::UniquePtr< PrePlanningInterface > PluginPtr
Definition: gpp_plugin.hpp:150
costmap_2d_ros.h
gpp_plugin::PluginGroup::getPlugins
const PluginMap & getPlugins() const noexcept
Definition: gpp_plugin.hpp:156
gpp_plugin::_runPlugins
bool _runPlugins(const PluginGroup< _Plugin > &_grp, const _Functor &_func, const std::atomic_bool &_cancel)
Execution logic to run all plugins within one group.
Definition: gpp_plugin.hpp:191
gpp_plugin::PluginGroup::getName
const std::string & getName() const noexcept
Definition: gpp_plugin.hpp:161
gpp_plugin::PluginParameter::name
std::string name
Definition: gpp_plugin.hpp:136
gpp_plugin::PluginGroup< PrePlanningInterface >::NamedPlugin
std::pair< PluginParameter, PluginPtr > NamedPlugin
Definition: gpp_plugin.hpp:152
package
string package
gpp_plugin::BaseGlobalPlannerWrapper::initialize
void initialize(std::string name, Map *costmap_ros) override
Definition: gpp_plugin.cpp:173
ROS_WARN_STREAM
#define ROS_WARN_STREAM(args)
gpp_plugin::PluginDefinition::package
static const std::string package
Definition: gpp_plugin.hpp:51
gpp_plugin::runPlugins
bool runPlugins(const PluginGroup< _Plugin > &_grp, const _Functor &_func, const std::atomic_bool &_cancel)
as _runPlugins but with a warning on failure
Definition: gpp_plugin.hpp:221
mbf_costmap_core::CostmapPlanner
gpp_plugin::CostmapPlannerManager
Loads either CostmapPlanner or BaseGlobalPlanner plugins under a uniform interface.
Definition: gpp_plugin.hpp:349
gpp_interface::PostPlanningInterface
gpp_plugin::PluginGroup< PrePlanningInterface >::PluginMap
std::vector< NamedPlugin > PluginMap
Definition: gpp_plugin.hpp:153
post_planning_interface.hpp
gpp_plugin::BaseGlobalPlannerWrapper::Pose
geometry_msgs::PoseStamped Pose
Definition: gpp_plugin.hpp:318
gpp_plugin::PluginGroup::getDefaultValue
const bool & getDefaultValue() const noexcept
Definition: gpp_plugin.hpp:166
gpp_plugin::ArrayPluginManager
Loads an array of plugins.
Definition: gpp_plugin.hpp:297
gpp_plugin::PluginParameter::on_success_break
bool on_success_break
Definition: gpp_plugin.hpp:137
ROS_WARN_STREAM_COND
#define ROS_WARN_STREAM_COND(cond, args)
gpp_plugin::BaseGlobalPlannerWrapper::makePlan
bool makePlan(const Pose &start, const Pose &goal, Path &plan) override
Definition: gpp_plugin.cpp:159
gpp_plugin::BaseGlobalPlannerWrapper::Path
std::vector< Pose > Path
Definition: gpp_plugin.hpp:319
pluginlib::ClassLoader
costmap_planner.h
ROS_INFO_STREAM
#define ROS_INFO_STREAM(args)
gpp_plugin::PluginManager::createCustomInstance
virtual pluginlib::UniquePtr< _Plugin > createCustomInstance(const std::string &_type)
Definition: gpp_plugin.hpp:121
gpp_plugin::GppPlugin::prePlanning
bool prePlanning(Pose &_start, Pose &_goal)
Definition: gpp_plugin.cpp:227
gpp_plugin::GppPlugin::globalPlanning
bool globalPlanning(const Pose &_start, const Pose &_goal, Path &_plan, double &_cost)
Definition: gpp_plugin.cpp:244
gpp_plugin::GppPlugin::initialize
void initialize(std::string name, Map *costmap_ros) override
Definition: gpp_plugin.cpp:213
gpp_plugin::PluginGroup::default_value_
bool default_value_
Definition: gpp_plugin.hpp:171
gpp_plugin::GppPlugin::cancel_
std::atomic_bool cancel_
Definition: gpp_plugin.hpp:444
gpp_plugin::PluginManager
Base class for loading a plugin with a valid PluginDefinition.
Definition: gpp_plugin.hpp:112
gpp_interface::PrePlanningInterface
gpp_plugin::CostmapPlannerManager::manager_
PluginManager< CostmapPlanner > manager_
Definition: gpp_plugin.hpp:357
gpp_plugin::GppPlugin::makePlan
bool makePlan(const Pose &_start, const Pose &_goal, Path &_plan) override
Definition: gpp_plugin.cpp:253
gpp_plugin::PluginParameter::on_failure_break
bool on_failure_break
Definition: gpp_plugin.hpp:138
base_global_planner.h
gpp_plugin::GppPlugin::name_
std::string name_
Definition: gpp_plugin.hpp:447
gpp_plugin::GppPlugin::postPlanning
bool postPlanning(const Pose &_start, const Pose &_goal, Path &_path, double &_cost)
Definition: gpp_plugin.cpp:235
gpp_plugin::GppPlugin::Path
std::vector< Pose > Path
Definition: gpp_plugin.hpp:413
gpp_plugin::GppPlugin::costmap_
Map * costmap_
Definition: gpp_plugin.hpp:448
gpp_plugin
Definition: gpp_plugin.hpp:41
gpp_plugin::CostmapPlannerManager::~CostmapPlannerManager
~CostmapPlannerManager()
Definition: gpp_plugin.cpp:177
gpp_plugin::PluginGroup
Common interface to a plugin group.
Definition: gpp_plugin.hpp:148
gpp_plugin::GppPlugin::Pose
geometry_msgs::PoseStamped Pose
Definition: gpp_plugin.hpp:412
gpp_plugin::ArrayPluginManager::load
void load(const std::string &_resource, ros::NodeHandle &_nh)
Definition: gpp_plugin.cpp:84
nav_core::BaseGlobalPlanner
gpp_plugin::PluginManager::PluginManager
PluginManager()
Definition: gpp_plugin.hpp:118
gpp_plugin::BaseGlobalPlannerWrapper::ImplPlanner
pluginlib::UniquePtr< CostmapPlanner > ImplPlanner
Definition: gpp_plugin.hpp:321
gpp_plugin::GppPlugin
Combine pre-planning, planning and post-planning to customize the your path.
Definition: gpp_plugin.hpp:410
gpp_plugin::PluginParameter
Parameters defining how to execute a plugin.
Definition: gpp_plugin.hpp:135
costmap_2d::Costmap2DROS
gpp_plugin::GppPlugin::pre_planning_
PrePlanningManager pre_planning_
Definition: gpp_plugin.hpp:450
ros::NodeHandle


gpp_plugin
Author(s):
autogenerated on Wed Mar 2 2022 00:21:23