ompl_kinematic_planner.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018, The Regents of the University of California (Regents).
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above
13  * copyright notice, this list of conditions and the following
14  * disclaimer in the documentation and/or other materials provided
15  * with the distribution.
16  *
17  * 3. Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Please contact the author(s) of this library if you have any questions.
34  * Authors: David Fridovich-Keil ( dfk@eecs.berkeley.edu )
35  */
36 
38 //
39 // OMPL kinematic planner wrapper, templated on the state type and the specific
40 // type of OMPL planner to be used under the hood.
41 //
43 
44 #ifndef FASTRACK_PLANNING_OMPL_KINEMATIC_PLANNER_H
45 #define FASTRACK_PLANNING_OMPL_KINEMATIC_PLANNER_H
46 
48 
49 #include <ompl/geometric/planners/bitstar/BITstar.h>
50 #include <ompl/geometric/planners/rrt/RRTConnect.h>
51 
52 #include <ompl/base/SpaceInformation.h>
53 #include <ompl/base/TypedSpaceInformation.h>
54 #include <ompl/base/spaces/RealVectorStateSpace.h>
55 #include <ompl/geometric/SimpleSetup.h>
56 
57 #include <ompl/geometric/planners/bitstar/BITstar.h>
58 #include <ompl/geometric/planners/rrt/RRTConnect.h>
59 
60 namespace fastrack {
61 namespace planning {
62 
63 namespace ob = ompl::base;
64 namespace og = ompl::geometric;
65 
66 template <typename P, typename S, typename E, typename B, typename SB>
67 class OmplKinematicPlanner : public KinematicPlanner<S, E, B, SB> {
68  public:
70  explicit OmplKinematicPlanner() : KinematicPlanner<S, E, B, SB>() {
71  // Set OMPL log level.
72  ompl::msg::setLogLevel(ompl::msg::LogLevel::LOG_ERROR);
73  }
74 
75  private:
76  // Plan a trajectory from the given start to goal states starting
77  // at the given time.
78  // NOTE! The states in the output trajectory are essentially configurations.
79  Trajectory<S> Plan(const S& start, const S& goal,
80  double start_time = 0.0) const;
81 
82  // Convert between OMPL states and configurations.
83  S FromOmplState(const ob::State* state) const;
84 }; //\class KinematicPlanner
85 
86 // ---------------------------- IMPLEMENTATION ------------------------------ //
87 
88 // Convert between OMPL states and configurations.
89 template <typename P, typename S, typename E, typename B, typename SB>
91  const ob::State* state) const {
92  // Catch null state.
93  if (!state)
94  throw std::runtime_error("OmplKinematicPlanner: null OMPL state.");
95 
96  // Cast state to proper type.
97  const ob::RealVectorStateSpace::StateType* cast_state =
98  static_cast<const ob::RealVectorStateSpace::StateType*>(state);
99 
100  // Populate configuration.
101  VectorXd config(S::ConfigurationDimension());
102  for (size_t ii = 0; ii < S::ConfigurationDimension(); ii++)
103  config(ii) = cast_state->values[ii];
104 
105  return S(config);
106 }
107 
108 // Plan a trajectory from the given start to goal states starting
109 // at the given time.
110 template <typename P, typename S, typename E, typename B, typename SB>
112  const S& start, const S& goal, double start_time) const {
113  // Unpack start and goal configurations.
114  const VectorXd start_config = start.Configuration();
115  const VectorXd goal_config = goal.Configuration();
116 
117  // Check that both start and stop are in bounds.
118  if (!this->env_.AreValid(start.OccupiedPositions(), this->bound_)) {
119  ROS_WARN_THROTTLE(1.0, "Start point was in collision or out of bounds.");
120  return Trajectory<S>();
121  }
122 
123  if (!this->env_.AreValid(goal.OccupiedPositions(), this->bound_)) {
124  ROS_WARN_THROTTLE(1.0, "Goal point was in collision or out of bounds.");
125  return Trajectory<S>();
126  }
127 
128  // Create the OMPL state space corresponding to this environment.
129  auto ompl_space(
130  std::make_shared<ob::RealVectorStateSpace>(S::ConfigurationDimension()));
131 
132  // Set bounds for the environment.
133  const VectorXd lower = S::GetConfigurationLower();
134  const VectorXd upper = S::GetConfigurationUpper();
135 
136  ob::RealVectorBounds ompl_bounds(S::ConfigurationDimension());
137  for (size_t ii = 0; ii < S::ConfigurationDimension(); ii++) {
138  ompl_bounds.setLow(ii, lower(ii));
139  ompl_bounds.setHigh(ii, upper(ii));
140  }
141 
142  ompl_space->setBounds(ompl_bounds);
143 
144  // Create a SimpleSetup instance and set the state validity checker function.
145  og::SimpleSetup ompl_setup(ompl_space);
146  ompl_setup.setStateValidityChecker([&](const ob::State* state) {
147  return this->env_.AreValid(FromOmplState(state).OccupiedPositions(),
148  this->bound_);
149  });
150 
151  // Set the start and goal states.
152  ob::ScopedState<ob::RealVectorStateSpace> ompl_start(ompl_space);
153  ob::ScopedState<ob::RealVectorStateSpace> ompl_goal(ompl_space);
154  for (size_t ii = 0; ii < S::ConfigurationDimension(); ii++) {
155  ompl_start[ii] = start_config(ii);
156  ompl_goal[ii] = goal_config(ii);
157  }
158 
159  ompl_setup.setStartAndGoalStates(ompl_start, ompl_goal);
160 
161  // Set the planner.
162  ob::PlannerPtr ompl_planner(new P(ompl_setup.getSpaceInformation()));
163  ompl_setup.setPlanner(ompl_planner);
164 
165  // Solve. Parameter is the amount of time (in seconds) used by the solver.
166  const ob::PlannerStatus solved = ompl_setup.solve(this->max_runtime_);
167 
168  if (!solved) {
169  ROS_WARN("OMPL Planner could not compute a solution.");
170  return Trajectory<S>();
171  }
172 
173  // Unpack the solution and assign timestamps.
174  const og::PathGeometric& solution = ompl_setup.getSolutionPath();
175 
176  // Populate the Trajectory with states and time stamps.
177  // NOTE! These states are essentially just configurations.
178  std::vector<S> states;
179  std::vector<double> times;
180 
181  double time = start_time;
182  for (size_t ii = 0; ii < solution.getStateCount(); ii++) {
183  const S state = FromOmplState(solution.getState(ii));
184 
185  // Increment time by the duration it takes us to get from the previous
186  // configuration to this one.
187  if (ii > 0) time += this->dynamics_.BestPossibleTime(states.back(), state);
188 
189  times.push_back(time);
190  states.push_back(state);
191  }
192 
193  return Trajectory<S>(states, times);
194 }
195 
196 } //\namespace planning
197 } //\namespace fastrack
198 
199 #endif
S FromOmplState(const ob::State *state) const
Trajectory< S > Plan(const S &start, const S &goal, double start_time=0.0) const
Definition: box.h:53


fastrack
Author(s): David Fridovich-Keil
autogenerated on Mon Aug 3 2020 21:28:37