ompl_control_solver.cpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2018-2020, University of Edinburgh, University of Oxford
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 met:
7 //
8 // * Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of nor the names of its contributors may be used to
14 // endorse or promote products derived from this software without specific
15 // prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 // POSSIBILITY OF SUCH DAMAGE.
28 //
29 
31 
32 namespace exotica
33 {
35 {
36  if (pointer->type() != "exotica::DynamicTimeIndexedShootingProblem")
37  {
38  ThrowNamed("This ControlRRTSolver can't solve problem of type '" << pointer->type() << "'!");
39  }
41  prob_ = std::static_pointer_cast<DynamicTimeIndexedShootingProblem>(pointer);
42  dynamics_solver_ = prob_->GetScene()->GetDynamicsSolver();
43 
44  const int NX = prob_->GetScene()->get_num_state();
45  if (init_.StateLimits.size() != NX)
46  ThrowNamed("State limits are of size " << init_.StateLimits.size() << ", should be of size " << NX);
47 
48  if (debug_) HIGHLIGHT_NAMED(algorithm_, "initialized");
49 }
50 
52 {
53  int T = prob_->get_T();
54  const int NU = prob_->GetScene()->get_num_controls();
55  const int NX = prob_->GetScene()->get_num_state();
56  const double dt = dynamics_solver_->get_dt();
57  if (init_.Seed != -1) ompl::RNG::setSeed(init_.Seed);
58 
59  std::shared_ptr<ob::RealVectorStateSpace> space(std::make_shared<ob::RealVectorStateSpace>(NX));
60 
61  // state_bounds_ = std::make_unique<ob::RealVectorBounds>(NX);
62  ob::RealVectorBounds state_bounds_(NX);
63 
64  for (int i = 0; i < NX; ++i)
65  {
66  state_bounds_.setLow(i, -init_.StateLimits(i));
67  state_bounds_.setHigh(i, init_.StateLimits(i));
68  }
69 
70  space->setBounds(state_bounds_);
71 
72  // create a control space
73  std::shared_ptr<oc::RealVectorControlSpace> cspace(std::make_shared<oc::RealVectorControlSpace>(space, NU));
74 
75  // set the bounds for the control space
76  // control_bounds_ = std::make_unique<ob::RealVectorBounds>(NU);
77  ob::RealVectorBounds control_bounds_(NU);
78  const Eigen::MatrixXd control_limits = dynamics_solver_->get_control_limits();
79 
80  for (int i = 0; i < NU; ++i)
81  {
82  control_bounds_.setLow(i, control_limits.col(0)(i));
83  control_bounds_.setHigh(i, control_limits.col(1)(i));
84  }
85 
86  cspace->setBounds(control_bounds_);
87 
88  // define a simple setup class
89  setup_.reset(new oc::SimpleSetup(cspace));
90  oc::SpaceInformationPtr si = setup_->getSpaceInformation();
91 
92  si->setPropagationStepSize(dt);
93  setup_->setStateValidityChecker([this, si](const ob::State *state) { return isStateValid(si, state); });
94 
95  std::shared_ptr<OMPLStatePropagator> propagator(std::make_shared<OMPLStatePropagator>(si, dynamics_solver_));
96 
97  setup_->setStatePropagator(propagator);
98 
99  const Eigen::VectorXd start_eig = prob_->ApplyStartState();
100  const Eigen::MatrixXd goal_eig = prob_->get_X_star().col(T - 1);
101 
102  // start_state_ = std::make_unique<ob::ScopedState<ob::RealVectorStateSpace>>(space);
103  // goal_state_ = std::make_unique<ob::ScopedState<ob::RealVectorStateSpace>>(space);
104 
105  ob::ScopedState<ob::RealVectorStateSpace> start_state_(space);
106  ob::ScopedState<ob::RealVectorStateSpace> goal_state_(space);
107 
108  for (int i = 0; i < NX; ++i)
109  {
110  // (*start_state_)[i] = start_eig(i);
111  // (*goal_state_)[i] = goal_eig(i);
112  start_state_[i] = start_eig(i);
113  goal_state_[i] = goal_eig(i);
114  }
115 
116  setup_->setStartAndGoalStates(start_state_, goal_state_, init_.ConvergenceTolerance);
117 
118  ob::PlannerPtr optimizingPlanner(planner_allocator_(si));
119  setup_->setPlanner(optimizingPlanner);
120 
121  setup_->setup();
122  propagator->setIntegrationTimeStep(si->getPropagationStepSize());
123 }
124 
125 void OMPLControlSolver::Solve(Eigen::MatrixXd &solution)
126 {
127  if (!prob_) ThrowNamed("Solver has not been initialized!");
128  Timer planning_timer, backward_pass_timer, line_search_timer;
129 
130  int T = prob_->get_T();
131  const int NU = prob_->GetScene()->get_num_controls();
132  const int NX = prob_->GetScene()->get_num_state();
133  const Eigen::VectorXd x_star = prob_->get_X_star().col(T - 1);
134 
135  const double dt = dynamics_solver_->get_dt();
136 
137  Setup();
138  ob::PlannerStatus solved = setup_->solve(init_.MaxIterationTime);
139 
140  if (solved)
141  {
142  std::vector<oc::Control *> controls = setup_->getSolutionPath().getControls();
143  std::vector<ob::State *> states = setup_->getSolutionPath().getStates();
144  std::vector<double> durations = setup_->getSolutionPath().getControlDurations();
145 
146  Eigen::VectorXd sol_goal_state = Eigen::Map<Eigen::VectorXd>(
147  states.back()->as<ob::RealVectorStateSpace::StateType>()->values, NX);
148 
149  T = 0;
150  for (std::size_t t = 0; t < controls.size(); ++t)
151  T += static_cast<int>(durations[t] / dt);
152  T += 1;
153 
154  if ((x_star - sol_goal_state).norm() > init_.ConvergenceTolerance && debug_)
155  WARNING_NAMED(algorithm_, "Goal not satisfied.");
156 
157  // additional solution criteria
158  if (T <= 2 || ((x_star - sol_goal_state).norm() > init_.ConvergenceTolerance &&
159  !init_.ApproximateSolution))
160  {
161  if (debug_) HIGHLIGHT_NAMED(algorithm_, "No solution found.");
162  prob_->termination_criterion = TerminationCriterion::Divergence;
163  return;
164  }
165  else if (debug_)
166  HIGHLIGHT_NAMED(algorithm_, "Found solution.");
167 
168  prob_->set_T(T);
169  prob_->PreUpdate();
170 
171  solution.resize(T - 1, NU);
172 
173  int t = 0;
174  for (std::size_t i = 0; i < controls.size(); ++i)
175  {
176  double *oc_u = controls[i]->as<oc::RealVectorControlSpace::ControlType>()->values;
177  Eigen::VectorXd u = Eigen::Map<Eigen::VectorXd>(oc_u, NU);
178 
179  for (int k = 0; k < static_cast<int>(durations[i] / dt); ++k)
180  {
181  solution.row(t) = u.transpose();
182  prob_->Update(u, t);
183 
184  ++t;
185  }
186  }
187 
188  prob_->termination_criterion = TerminationCriterion::IterationLimit;
189  planning_time_ = planning_timer.GetDuration();
190  }
191  else
192  {
193  HIGHLIGHT_NAMED(algorithm_, "No solution found.");
194  prob_->termination_criterion = TerminationCriterion::Divergence;
195  }
196 }
197 
198 } // namespace exotica
void Solve(Eigen::MatrixXd &solution) override
Solves the problem.
void SpecifyProblem(PlanningProblemPtr pointer) override
Binds the solver to a specific problem which must be pre-initalised.
std::vector< double > values
#define WARNING_NAMED(name, x)
std::unique_ptr< oc::SimpleSetup > setup_
virtual void SpecifyProblem(PlanningProblemPtr pointer)
OMPLControlSolverInitializer init_
!< Shared pointer to the dynamics solver.
DynamicTimeIndexedShootingProblemPtr prob_
#define ThrowNamed(m)
DynamicsSolverPtr dynamics_solver_
!< Shared pointer to the planning problem.
bool isStateValid(const oc::SpaceInformationPtr si, const ob::State *state)
#define HIGHLIGHT_NAMED(name, x)
ConfiguredPlannerAllocator planner_allocator_
double GetDuration() const
std::shared_ptr< PlanningProblem > PlanningProblemPtr


exotica_ompl_control_solver
Author(s): Traiko Dinev
autogenerated on Sat Apr 10 2021 02:35:42