Loading...
Searching...
No Matches
StateSampling.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: Mark Moll */
36
37#include <ompl/base/SpaceInformation.h>
38#include <ompl/base/spaces/SE3StateSpace.h>
39#include <ompl/base/samplers/ObstacleBasedValidStateSampler.h>
40#include <ompl/geometric/planners/prm/PRM.h>
41#include <ompl/geometric/SimpleSetup.h>
42
43#include <ompl/config.h>
44#include <iostream>
45#include <thread>
46
47namespace ob = ompl::base;
48namespace og = ompl::geometric;
49
51
52// This is a problem-specific sampler that automatically generates valid
53// states; it doesn't need to call SpaceInformation::isValid. This is an
54// example of constrained sampling. If you can explicitly describe the set valid
55// states and can draw samples from it, then this is typically much more
56// efficient than generating random samples from the entire state space and
57// checking for validity.
58class MyValidStateSampler : public ob::ValidStateSampler
59{
60public:
61 MyValidStateSampler(const ob::SpaceInformation *si) : ValidStateSampler(si)
62 {
63 name_ = "my sampler";
64 }
65 // Generate a sample in the valid part of the R^3 state space
66 // Valid states satisfy the following constraints:
67 // -1<= x,y,z <=1
68 // if .25 <= z <= .5, then |x|>.8 and |y|>.8
69 bool sample(ob::State *state) override
70 {
71 double *val = static_cast<ob::RealVectorStateSpace::StateType *>(state)->values;
72 double z = rng_.uniformReal(-1, 1);
73
74 if (z > .25 && z < .5)
75 {
76 double x = rng_.uniformReal(0, 1.8), y = rng_.uniformReal(0, .2);
77 switch (rng_.uniformInt(0, 3))
78 {
79 case 0:
80 val[0] = x - 1;
81 val[1] = y - 1;
82 break;
83 case 1:
84 val[0] = x - .8;
85 val[1] = y + .8;
86 break;
87 case 2:
88 val[0] = y - 1;
89 val[1] = x - 1;
90 break;
91 case 3:
92 val[0] = y + .8;
93 val[1] = x - .8;
94 break;
95 }
96 }
97 else
98 {
99 val[0] = rng_.uniformReal(-1, 1);
100 val[1] = rng_.uniformReal(-1, 1);
101 }
102 val[2] = z;
103 assert(si_->isValid(state));
104 return true;
105 }
106 // We don't need this in the example below.
107 bool sampleNear(ob::State * /*state*/, const ob::State * /*near*/, const double /*distance*/) override
108 {
109 throw ompl::Exception("MyValidStateSampler::sampleNear", "not implemented");
110 return false;
111 }
112
113protected:
114 ompl::RNG rng_;
115};
116
118
119// this function is needed, even when we can write a sampler like the one
120// above, because we need to check path segments for validity
121bool isStateValid(const ob::State *state)
122{
124 // Let's pretend that the validity check is computationally relatively
125 // expensive to emphasize the benefit of explicitly generating valid
126 // samples
127 std::this_thread::sleep_for(ompl::time::seconds(.0005));
128 // Valid states satisfy the following constraints:
129 // -1<= x,y,z <=1
130 // if .25 <= z <= .5, then |x|>.8 and |y|>.8
131 return !(fabs(pos[0]) < .8 && fabs(pos[1]) < .8 && pos[2] > .25 && pos[2] < .5);
132}
133
134// return an obstacle-based sampler
135ob::ValidStateSamplerPtr allocOBValidStateSampler(const ob::SpaceInformation *si)
136{
137 // we can perform any additional setup / configuration of a sampler here,
138 // but there is nothing to tweak in case of the ObstacleBasedValidStateSampler.
139 return std::make_shared<ob::ObstacleBasedValidStateSampler>(si);
140}
141
142// return an instance of my sampler
143ob::ValidStateSamplerPtr allocMyValidStateSampler(const ob::SpaceInformation *si)
144{
145 return std::make_shared<MyValidStateSampler>(si);
146}
147
148void plan(int samplerIndex)
149{
150 // construct the state space we are planning in
151 auto space(std::make_shared<ob::RealVectorStateSpace>(3));
152
153 // set the bounds
154 ob::RealVectorBounds bounds(3);
155 bounds.setLow(-1);
156 bounds.setHigh(1);
157 space->setBounds(bounds);
158
159 // define a simple setup class
160 og::SimpleSetup ss(space);
161
162 // set state validity checking for this space
163 ss.setStateValidityChecker(isStateValid);
164
165 // create a start state
166 ob::ScopedState<> start(space);
167 start[0] = start[1] = start[2] = 0;
168
169 // create a goal state
170 ob::ScopedState<> goal(space);
171 goal[0] = goal[1] = 0.;
172 goal[2] = 1;
173
174 // set the start and goal states
175 ss.setStartAndGoalStates(start, goal);
176
177 // set sampler (optional; the default is uniform sampling)
178 if (samplerIndex == 1)
179 // use obstacle-based sampling
180 ss.getSpaceInformation()->setValidStateSamplerAllocator(allocOBValidStateSampler);
181 else if (samplerIndex == 2)
182 // use my sampler
183 ss.getSpaceInformation()->setValidStateSamplerAllocator(allocMyValidStateSampler);
184
185 // create a planner for the defined space
186 auto planner(std::make_shared<og::PRM>(ss.getSpaceInformation()));
187 ss.setPlanner(planner);
188
189 // attempt to solve the problem within ten seconds of planning time
190 ob::PlannerStatus solved = ss.solve(10.0);
191 if (solved)
192 {
193 std::cout << "Found solution:" << std::endl;
194 // print the path to screen
195 ss.getSolutionPath().print(std::cout);
196 }
197 else
198 std::cout << "No solution found" << std::endl;
199}
200
201int main(int /*argc*/, char ** /*argv*/)
202{
203 std::cout << "Using default uniform sampler:" << std::endl;
204 plan(0);
205 std::cout << "\nUsing obstacle-based sampler:" << std::endl;
206 plan(1);
207 std::cout << "\nUsing my sampler:" << std::endl;
208 plan(2);
209
210 return 0;
211}
The lower and upper bounds for an Rn space.
Definition of a scoped state.
Definition ScopedState.h:57
The base class for space information. This contains all the information about the space planning is d...
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
Abstract definition of a state sampler.
virtual bool sample(State *state)=0
Sample a state. Return false in case of failure.
virtual bool sampleNear(State *state, const State *near, double distance)=0
Sample a state near another, within specified distance. Return false, in case of failure.
Create the set of classes typically needed to solve a geometric problem.
Definition SimpleSetup.h:63
This namespace contains sampling based planning routines shared by both planning under geometric cons...
This namespace contains code that is specific to planning under geometric constraints.
duration seconds(double sec)
Return the time duration representing a given number of seconds.
Definition Time.h:64
A class to store the exit status of Planner::solve().