Loading...
Searching...
No Matches
TriangulationDemo.cpp
1#include <ompl/control/SpaceInformation.h>
2#include <ompl/base/goals/GoalState.h>
3#include <ompl/base/spaces/SE2StateSpace.h>
4#include <ompl/control/spaces/RealVectorControlSpace.h>
5#include <ompl/control/planners/kpiece/KPIECE1.h>
6#include <ompl/control/planners/rrt/RRT.h>
7#include <ompl/control/planners/est/EST.h>
8#include <ompl/control/planners/syclop/SyclopRRT.h>
9#include <ompl/control/planners/syclop/SyclopEST.h>
10#include <ompl/control/SimpleSetup.h>
11#include <ompl/config.h>
12#include <ompl/extensions/triangle/TriangularDecomposition.h>
13#include <iostream>
14
15namespace ob = ompl::base;
16namespace oc = ompl::control;
17
18// a decomposition is only needed for SyclopRRT and SyclopEST
19class MyTriangularDecomposition : public oc::TriangularDecomposition
20{
21public:
22 MyTriangularDecomposition(const ob::RealVectorBounds &bounds)
23 : oc::TriangularDecomposition(bounds, createObstacles())
24 {
25 setup();
26 }
27 void project(const ob::State *s, std::vector<double> &coord) const override
28 {
29 coord.resize(2);
30 coord[0] = s->as<ob::SE2StateSpace::StateType>()->getX();
31 coord[1] = s->as<ob::SE2StateSpace::StateType>()->getY();
32 }
33
34 void sampleFullState(const ob::StateSamplerPtr &sampler, const std::vector<double> &coord,
35 ob::State *s) const override
36 {
37 sampler->sampleUniform(s);
38 s->as<ob::SE2StateSpace::StateType>()->setXY(coord[0], coord[1]);
39 }
40
41 std::vector<Polygon> createObstacles()
42 {
43 std::vector<Polygon> obst;
44 Triangle tri;
45 tri.pts[0].x = -0.5;
46 tri.pts[0].y = 0.75;
47 tri.pts[1].x = -0.75;
48 tri.pts[1].y = 0.68;
49 tri.pts[2].x = -0.5;
50 tri.pts[2].y = 0.5;
51 obst.push_back(tri);
52
53 Polygon rect(4);
54 rect.pts[0].x = 0.;
55 rect.pts[0].y = 0.5;
56 rect.pts[1].x = -0.3;
57 rect.pts[1].y = 0.;
58 rect.pts[2].x = 0.;
59 rect.pts[2].y = -0.5;
60 rect.pts[3].x = 0.6;
61 rect.pts[3].y = 0.6;
62 obst.push_back(rect);
63
64 return obst;
65 }
66};
67
68bool triContains(double x, double y, double ax, double ay, double bx, double by, double cx, double cy)
69{
70 if ((x - ax) * (by - ay) - (bx - ax) * (y - ay) > 0.)
71 return false;
72 if ((x - bx) * (cy - by) - (cx - bx) * (y - by) > 0.)
73 return false;
74 if ((x - cx) * (ay - cy) - (ax - cx) * (y - cy) > 0.)
75 return false;
76 return true;
77}
78
79bool isStateValid(const oc::SpaceInformation *si, const ob::State *state)
80{
81 // ob::ScopedState<ob::SE2StateSpace>
82 // cast the abstract state type to the type we expect
83 const auto *se2state = state->as<ob::SE2StateSpace::StateType>();
84
85 // check validity of state defined by pos & rot
86 double x = se2state->getX();
87 double y = se2state->getY();
88 return si->satisfiesBounds(state) && !triContains(x, y, -0.5, 0.75, -0.75, 0.68, -0.5, 0.5) &&
89 !triContains(x, y, 0, 0.5, -0.3, 0, 0, -0.5) && !triContains(x, y, 0, -0.5, 0.6, 0.6, 0, 0.5);
90}
91
92void propagate(const ob::State *start, const oc::Control *control, const double duration, ob::State *result)
93{
94 const auto *se2state = start->as<ob::SE2StateSpace::StateType>();
95 const auto *pos = se2state->as<ob::RealVectorStateSpace::StateType>(0);
96 const auto *rot = se2state->as<ob::SO2StateSpace::StateType>(1);
97 const auto *rctrl = control->as<oc::RealVectorControlSpace::ControlType>();
98
99 result->as<ob::SE2StateSpace::StateType>()->as<ob::RealVectorStateSpace::StateType>(0)->values[0] =
100 (*pos)[0] + (*rctrl)[0] * duration * cos(rot->value);
101
102 result->as<ob::SE2StateSpace::StateType>()->as<ob::RealVectorStateSpace::StateType>(0)->values[1] =
103 (*pos)[1] + (*rctrl)[0] * duration * sin(rot->value);
104
105 result->as<ob::SE2StateSpace::StateType>()->as<ob::SO2StateSpace::StateType>(1)->value = rot->value + (*rctrl)[1];
106}
107
108void planWithSimpleSetup()
109{
110 // construct the state space we are planning in
111 auto space(std::make_shared<ob::SE2StateSpace>());
112
113 // set the bounds for the R^2 part of SE(2)
114 ob::RealVectorBounds bounds(2);
115 bounds.setLow(-1);
116 bounds.setHigh(1);
117
118 space->setBounds(bounds);
119
120 // create a control space
121 auto cspace(std::make_shared<oc::RealVectorControlSpace>(space, 2));
122
123 // set the bounds for the control space
124 ob::RealVectorBounds cbounds(2);
125 cbounds.setLow(-0.3);
126 cbounds.setHigh(0.3);
127
128 cspace->setBounds(cbounds);
129
130 // define a simple setup class
131 oc::SimpleSetup ss(cspace);
132
133 // set the state propagation routine
134 ss.setStatePropagator(propagate);
135
136 // set state validity checking for this space
137 oc::SpaceInformation *si = ss.getSpaceInformation().get();
138 ss.setStateValidityChecker([si](const ob::State *state) { return isStateValid(si, state); });
139
140 // create a start state
142 start->setX(-0.5);
143 start->setY(0.0);
144 start->setYaw(0.0);
145
147 goal->setX(0.5);
148
149 // set the start and goal states
150 ss.setStartAndGoalStates(start, goal, 0.05);
151
152 auto td(std::make_shared<MyTriangularDecomposition>(bounds));
153 // print the triangulation to stdout
154 td->print(std::cout);
155
156 // hand the triangulation to SyclopEST
157 auto planner(std::make_shared<oc::SyclopEST>(ss.getSpaceInformation(), td));
158 // hand the SyclopEST planner to SimpleSetup
159 ss.setPlanner(planner);
160
161 // attempt to solve the problem within ten seconds of planning time
162 ob::PlannerStatus solved = ss.solve(10.0);
163
164 if (solved)
165 {
166 std::cout << "Found solution:" << std::endl;
167 // print the path to screen
168
169 ss.getSolutionPath().asGeometric().print(std::cout);
170 }
171 else
172 std::cout << "No solution found" << std::endl;
173}
174
175int main(int /*argc*/, char ** /*argv*/)
176{
177 std::cout << "OMPL version: " << OMPL_VERSION << std::endl;
178 planWithSimpleSetup();
179 std::cout << std::endl;
180 return 0;
181}
const T * as(unsigned int index) const
Cast a component of this instance to a desired type.
Definition State.h:95
The lower and upper bounds for an Rn space.
A state in SE(2): (x, y, yaw).
The definition of a state in SO(2).
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...
ompl::base::State StateType
Define the type of state allocated by this space.
Definition StateSpace.h:78
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
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...
A TriangularDecomposition is a triangulation that ignores obstacles.
TriangularDecomposition(const base::RealVectorBounds &bounds, std::vector< Polygon > holes=std::vector< Polygon >(), std::vector< Polygon > intRegs=std::vector< Polygon >())
Creates a TriangularDecomposition over the given bounds, which must be 2-dimensional....
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
A class to store the exit status of Planner::solve().