Loading...
Searching...
No Matches
HybridSystemPlanning.cpp
1/*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2010, Rice University
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of the Rice University 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
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *********************************************************************/
34
35/* Author: Elizabeth Fudge */
36
37#include <ompl/base/goals/GoalState.h>
38#include <ompl/base/spaces/SE2StateSpace.h>
39#include <ompl/base/spaces/DiscreteStateSpace.h>
40#include <ompl/control/spaces/RealVectorControlSpace.h>
41#include <ompl/control/SimpleSetup.h>
42#include <ompl/config.h>
43#include <iostream>
44#include <limits>
45#include <boost/math/constants/constants.hpp>
46
47namespace ob = ompl::base;
48namespace oc = ompl::control;
49
50void propagate(const oc::SpaceInformation *si, const ob::State *state, const oc::Control *control,
51 const double duration, ob::State *result)
52{
53 static double timeStep = .01;
54 int nsteps = ceil(duration / timeStep);
55 double dt = duration / nsteps;
56 const double *u = control->as<oc::RealVectorControlSpace::ControlType>()->values;
57
62
63 si->getStateSpace()->copyState(result, state);
64 for (int i = 0; i < nsteps; i++)
65 {
66 se2.setX(se2.getX() + dt * velocity.values[0] * cos(se2.getYaw()));
67 se2.setY(se2.getY() + dt * velocity.values[0] * sin(se2.getYaw()));
68 se2.setYaw(se2.getYaw() + dt * u[0]);
69 velocity.values[0] = velocity.values[0] + dt * (u[1] * gear.value);
70
71 // 'guards' - conditions to change gears
72 if (gear.value > 0)
73 {
74 if (gear.value < 3 && velocity.values[0] > 10 * (gear.value + 1))
75 gear.value++;
76 else if (gear.value > 1 && velocity.values[0] < 10 * gear.value)
77 gear.value--;
78 }
79 if (!si->satisfiesBounds(result))
80 return;
81 }
82}
83
84// The free space consists of two narrow corridors connected at right angle.
85// To make the turn, the car will have to downshift.
86bool isStateValid(const oc::SpaceInformation *si, const ob::State *state)
87{
88 const auto *se2 = state->as<ob::CompoundState>()->as<ob::SE2StateSpace::StateType>(0);
89 return si->satisfiesBounds(state) && (se2->getX() < -80. || se2->getY() > 80.);
90}
91
92int main(int /*argc*/, char ** /*argv*/)
93{
94 // plan for hybrid car in SE(2) with discrete gears
95 auto SE2(std::make_shared<ob::SE2StateSpace>());
96 auto velocity(std::make_shared<ob::RealVectorStateSpace>(1));
97 // set the range for gears: [-1,3] inclusive
98 auto gear(std::make_shared<ob::DiscreteStateSpace>(-1, 3));
99 ob::StateSpacePtr stateSpace = SE2 + velocity + gear;
100
101 // set the bounds for the R^2 part of SE(2)
102 ob::RealVectorBounds bounds(2);
103 bounds.setLow(-100);
104 bounds.setHigh(100);
105 SE2->setBounds(bounds);
106
107 // set the bounds for the velocity
108 ob::RealVectorBounds velocityBound(1);
109 velocityBound.setLow(0);
110 velocityBound.setHigh(60);
111 velocity->setBounds(velocityBound);
112
113 // create start and goal states
114 ob::ScopedState<> start(stateSpace);
115 ob::ScopedState<> goal(stateSpace);
116
117 // Both start and goal are states with high velocity with the car in third gear.
118 // However, to make the turn, the car cannot stay in third gear and will have to
119 // shift to first gear.
120 start[0] = start[1] = -90.; // position
121 start[2] = boost::math::constants::pi<double>() / 2; // orientation
122 start[3] = 40.; // velocity
123 start->as<ob::CompoundState>()->as<ob::DiscreteStateSpace::StateType>(2)->value = 3; // gear
124
125 goal[0] = goal[1] = 90.; // position
126 goal[2] = 0.; // orientation
127 goal[3] = 40.; // velocity
128 goal->as<ob::CompoundState>()->as<ob::DiscreteStateSpace::StateType>(2)->value = 3; // gear
129
130 oc::ControlSpacePtr cmanifold(std::make_shared<oc::RealVectorControlSpace>(stateSpace, 2));
131
132 // set the bounds for the control manifold
133 ob::RealVectorBounds cbounds(2);
134 // bounds for steering input
135 cbounds.setLow(0, -1.);
136 cbounds.setHigh(0, 1.);
137 // bounds for brake/gas input
138 cbounds.setLow(1, -20.);
139 cbounds.setHigh(1, 20.);
140 cmanifold->as<oc::RealVectorControlSpace>()->setBounds(cbounds);
141
142 oc::SimpleSetup setup(cmanifold);
143 const oc::SpaceInformation *si = setup.getSpaceInformation().get();
144 setup.setStartAndGoalStates(start, goal, 5.);
145 setup.setStateValidityChecker([si](const ob::State *state) { return isStateValid(si, state); });
146 setup.setStatePropagator([si](const ob::State *state, const oc::Control *control, const double duration,
147 ob::State *result) { propagate(si, state, control, duration, result); });
148 setup.getSpaceInformation()->setPropagationStepSize(.1);
149 setup.getSpaceInformation()->setMinMaxControlDuration(2, 3);
150
151 // try to solve the problem
152 if (setup.solve(30))
153 {
154 // print the (approximate) solution path: print states along the path
155 // and controls required to get from one state to the next
156 oc::PathControl &path(setup.getSolutionPath());
157
158 // print out full state on solution path
159 // (format: x, y, theta, v, u0, u1, dt)
160 for (unsigned int i = 0; i < path.getStateCount(); ++i)
161 {
162 const ob::State *state = path.getState(i);
163 const auto *se2 = state->as<ob::CompoundState>()->as<ob::SE2StateSpace::StateType>(0);
164 const auto *velocity = state->as<ob::CompoundState>()->as<ob::RealVectorStateSpace::StateType>(1);
165 const auto *gear = state->as<ob::CompoundState>()->as<ob::DiscreteStateSpace::StateType>(2);
166 std::cout << se2->getX() << ' ' << se2->getY() << ' ' << se2->getYaw() << ' ' << velocity->values[0] << ' '
167 << gear->value << ' ';
168 if (i == 0)
169 // null controls applied for zero seconds to get to start state
170 std::cout << "0 0 0";
171 else
172 {
173 // print controls and control duration needed to get from state i-1 to state i
174 const double *u = path.getControl(i - 1)->as<oc::RealVectorControlSpace::ControlType>()->values;
175 std::cout << u[0] << ' ' << u[1] << ' ' << path.getControlDuration(i - 1);
176 }
177 std::cout << std::endl;
178 }
179 if (!setup.haveExactSolutionPath())
180 {
181 std::cout << "Solution is approximate. Distance to actual goal is "
182 << setup.getProblemDefinition()->getSolutionDifference() << std::endl;
183 }
184 }
185
186 return 0;
187}
ompl::base::CompoundState StateType
Define the type of state allocated by this state space.
Definition StateSpace.h:577
Definition of a compound state.
Definition State.h:87
const T * as(unsigned int index) const
Cast a component of this instance to a desired type.
Definition State.h:95
The definition of a discrete state.
The lower and upper bounds for an Rn space.
A state in SE(2): (x, y, yaw).
Definition of a scoped state.
Definition ScopedState.h:57
void setStateValidityChecker(const StateValidityCheckerPtr &svc)
Set the instance of the state validity checker to use. Parallel implementations of planners assume th...
Definition of an abstract state.
Definition State.h:50
const T * as() const
Cast this instance to a desired type.
Definition State.h:66
Definition of an abstract control.
Definition Control.h:48
Definition of a control path.
Definition PathControl.h:61
A control space representing Rn.
Create the set of classes typically needed to solve a control problem.
Definition SimpleSetup.h:63
Space information containing necessary information for planning with controls. setup() needs to be ca...
This namespace contains sampling based planning routines shared by both planning under geometric cons...
This namespace contains sampling based planning routines used by planning under differential constrai...
Definition Control.h:45
std::chrono::system_clock::duration duration
Representation of a time duration.
Definition Time.h:55