Loading...
Searching...
No Matches
SpaceInformation.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: Ioan Sucan */
36
37#include "ompl/control/SpaceInformation.h"
38#include "ompl/control/SimpleDirectedControlSampler.h"
39#include "ompl/control/SteeredControlSampler.h"
40#include "ompl/util/Exception.h"
41#include <cassert>
42#include <utility>
43#include <limits>
44
45ompl::control::SpaceInformation::SpaceInformation(const base::StateSpacePtr &stateSpace, ControlSpacePtr controlSpace)
46 : base::SpaceInformation(stateSpace), controlSpace_(std::move(controlSpace))
47{
49}
50
52{
53 params_.declareParam<unsigned int>(
54 "min_control_duration", [this](unsigned int n) { setMinControlDuration(n); },
55 [this] { return getMinControlDuration(); });
56 params_.declareParam<unsigned int>(
57 "max_control_duration", [this](unsigned int n) { setMaxControlDuration(n); },
58 [this] { return getMaxControlDuration(); });
59 params_.declareParam<double>(
60 "propagation_step_size", [this](double s) { setPropagationStepSize(s); },
61 [this] { return getPropagationStepSize(); });
62}
63
65{
67 declareParams(); // calling base::SpaceInformation::setup() clears the params
69 throw Exception("State propagator not defined");
70 if (minSteps_ > maxSteps_)
71 throw Exception("The minimum number of steps cannot be larger than the maximum number of steps");
72 if (minSteps_ == 0 && maxSteps_ == 0)
73 {
74 minSteps_ = 1;
75 maxSteps_ = 10;
76 OMPL_WARN("Assuming propagation will always have between %d and %d steps", minSteps_, maxSteps_);
77 }
78 if (minSteps_ < 1)
79 throw Exception("The minimum number of steps must be at least 1");
80
81 if (stepSize_ < std::numeric_limits<double>::epsilon())
82 {
84 if (stepSize_ < std::numeric_limits<double>::epsilon())
85 throw Exception("The propagation step size must be larger than 0");
86 OMPL_WARN("The propagation step size is assumed to be %f", stepSize_);
87 }
88
89 controlSpace_->setup();
90 if (controlSpace_->getDimension() <= 0)
91 throw Exception("The dimension of the control space we plan in must be > 0");
92}
93
94ompl::control::DirectedControlSamplerPtr ompl::control::SpaceInformation::allocDirectedControlSampler() const
95{
96 if (dcsa_)
97 return dcsa_(this);
98 if (statePropagator_->canSteer())
99 return std::make_shared<SteeredControlSampler>(this);
100 else
101 return std::make_shared<SimpleDirectedControlSampler>(this);
102}
103
109
115
117{
118 class FnStatePropagator : public StatePropagator
119 {
120 public:
121 FnStatePropagator(SpaceInformation *si, StatePropagatorFn fn) : StatePropagator(si), fn_(std::move(fn))
122 {
123 }
124
125 void propagate(const base::State *state, const Control *control, const double duration,
126 base::State *result) const override
127 {
128 fn_(state, control, duration, result);
129 }
130
131 protected:
133 };
134
135 setStatePropagator(std::make_shared<FnStatePropagator>(this, fn));
136}
137
142
144{
146 return statePropagator_->canPropagateBackward();
147 return false;
148}
149
151 base::State *result) const
152{
153 if (steps == 0)
154 {
155 if (result != state)
156 copyState(result, state);
157 }
158 else
159 {
160 double signedStepSize = steps > 0 ? stepSize_ : -stepSize_;
161 steps = abs(steps);
162
163 statePropagator_->propagate(state, control, signedStepSize, result);
164 for (int i = 1; i < steps; ++i)
165 statePropagator_->propagate(result, control, signedStepSize, result);
166 }
167}
168
170 int steps, base::State *result) const
171{
172 if (steps == 0)
173 {
174 if (result != state)
175 copyState(result, state);
176 return 0;
177 }
178
179 double signedStepSize = steps > 0 ? stepSize_ : -stepSize_;
180 steps = abs(steps);
181
182 // perform the first step of propagation
183 statePropagator_->propagate(state, control, signedStepSize, result);
184
185 // if we found a valid state after one step, we can go on
186 if (isValid(result))
187 {
188 base::State *temp1 = result;
189 base::State *temp2 = allocState();
190 base::State *toDelete = temp2;
191 unsigned int r = steps;
192
193 // for the remaining number of steps
194 for (int i = 1; i < steps; ++i)
195 {
196 statePropagator_->propagate(temp1, control, signedStepSize, temp2);
197 if (isValid(temp2))
198 std::swap(temp1, temp2);
199 else
200 {
201 // the last valid state is temp1;
202 r = i;
203 break;
204 }
205 }
206
207 // if we finished the for-loop without finding an invalid state, the last valid state is temp1
208 // make sure result contains that information
209 if (result != temp1)
210 copyState(result, temp1);
211
212 // free the temporary memory
213 freeState(toDelete);
214
215 return r;
216 }
217 // if the first propagation step produced an invalid step, return 0 steps
218 // the last valid state is the starting one (assumed to be valid)
219 if (result != state)
220 copyState(result, state);
221 return 0;
222}
223
225 std::vector<base::State *> &result, bool alloc) const
226{
227 double signedStepSize = steps > 0 ? stepSize_ : -stepSize_;
228 steps = abs(steps);
229
230 if (alloc)
231 {
232 result.resize(steps);
233 for (auto &i : result)
234 i = allocState();
235 }
236 else
237 {
238 if (result.empty())
239 return;
240 steps = std::min(steps, (int)result.size());
241 }
242
243 int st = 0;
244
245 if (st < steps)
246 {
247 statePropagator_->propagate(state, control, signedStepSize, result[st]);
248 ++st;
249
250 while (st < steps)
251 {
252 statePropagator_->propagate(result[st - 1], control, signedStepSize, result[st]);
253 ++st;
254 }
255 }
256}
257
259 int steps, std::vector<base::State *> &result,
260 bool alloc) const
261{
262 double signedStepSize = steps > 0 ? stepSize_ : -stepSize_;
263 steps = abs(steps);
264
265 if (alloc)
266 result.resize(steps);
267 else
268 {
269 if (result.empty())
270 return 0;
271 steps = std::min(steps, (int)result.size());
272 }
273
274 int st = 0;
275
276 if (st < steps)
277 {
278 if (alloc)
279 result[st] = allocState();
280 statePropagator_->propagate(state, control, signedStepSize, result[st]);
281
282 if (isValid(result[st]))
283 {
284 ++st;
285 while (st < steps)
286 {
287 if (alloc)
288 result[st] = allocState();
289 statePropagator_->propagate(result[st - 1], control, signedStepSize, result[st]);
290
291 if (!isValid(result[st]))
292 {
293 if (alloc)
294 {
295 freeState(result[st]);
296 result.resize(st);
297 }
298 break;
299 }
300 ++st;
301 }
302 }
303 else
304 {
305 if (alloc)
306 {
307 freeState(result[st]);
308 result.resize(st);
309 }
310 }
311 }
312
313 return st;
314}
315
317{
319 out << " - control space:" << std::endl;
320 controlSpace_->printSettings(out);
321 out << " - can propagate backward: " << (canPropagateBackward() ? "yes" : "no") << std::endl;
322 out << " - propagation step size: " << stepSize_ << std::endl;
323 out << " - propagation duration: [" << minSteps_ << ", " << maxSteps_ << "]" << std::endl;
324}
The exception type for ompl.
Definition Exception.h:47
void freeState(State *state) const
Free the memory of a state.
virtual void setup()
Perform additional setup tasks (run once, before use). If state validity checking resolution has not ...
double getStateValidityCheckingResolution() const
Get the resolution at which state validity is verified. This call is only applicable if a ompl::base:...
ParamSet params_
Combined parameters for the contained classes.
virtual void printSettings(std::ostream &out=std::cout) const
Print information about the current instance of the state space.
void copyState(State *destination, const State *source) const
Copy a state to another.
double getMaximumExtent() const
Get the maximum extent of the space we are planning in. This is the maximum distance that could be re...
State * allocState() const
Allocate memory for a state.
bool setup_
Flag indicating whether setup() has been called on this instance.
bool isValid(const State *state) const
Check if a given state is valid or not.
A shared pointer wrapper for ompl::control::StatePropagator.
Definition of an abstract state.
Definition State.h:50
A shared pointer wrapper for ompl::control::ControlSpace.
Definition of an abstract control.
Definition Control.h:48
SpaceInformation(const base::StateSpacePtr &stateSpace, ControlSpacePtr controlSpace)
Constructor. Sets the instance of the state and control spaces to plan with.
DirectedControlSamplerPtr allocDirectedControlSampler() const
Allocate an instance of the DirectedControlSampler to use. This will be the default (SimpleDirectedCo...
void printSettings(std::ostream &out=std::cout) const override
Print information about the current instance of the state space.
unsigned int minSteps_
The minimum number of steps to apply a control for.
DirectedControlSamplerAllocator dcsa_
Optional allocator for the DirectedControlSampler. If not specified, the default implementation is us...
unsigned int getMinControlDuration() const
Get the minimum number of steps a control is propagated for.
void setStatePropagator(const StatePropagatorFn &fn)
Set the function that performs state propagation.
double getPropagationStepSize() const
Propagation is performed at integer multiples of a specified step size. This function returns the val...
void setup() override
Perform additional setup tasks (run once, before use).
void setPropagationStepSize(double stepSize)
When controls are applied to states, they are applied for a time duration that is an integer multiple...
ControlSpacePtr controlSpace_
The control space describing the space of controls applicable to states in the state space.
void setDirectedControlSamplerAllocator(const DirectedControlSamplerAllocator &dcsa)
Set the allocator to use for the DirectedControlSampler.
bool canPropagateBackward() const
Some systems can only propagate forward in time (i.e., the steps argument for the propagate() functio...
unsigned int maxSteps_
The maximum number of steps to apply a control for.
void propagate(const base::State *state, const Control *control, int steps, base::State *result) const
Propagate the model of the system forward, starting a a given state, with a given control,...
void setMaxControlDuration(unsigned int maxSteps)
Set the minimum and maximum number of steps a control is propagated for.
void clearDirectedSamplerAllocator()
Reset the DirectedControlSampler to be the default one.
unsigned int getMaxControlDuration() const
Get the maximum number of steps a control is propagated for.
StatePropagatorPtr statePropagator_
The state propagator used to model the motion of the system being planned for.
double stepSize_
The actual duration of each step.
unsigned int propagateWhileValid(const base::State *state, const Control *control, int steps, base::State *result) const
Propagate the model of the system forward, starting at a given state, with a given control,...
void setMinControlDuration(unsigned int minSteps)
Set the minimum number of steps a control is propagated for.
Model the effect of controls on system states.
#define OMPL_WARN(fmt,...)
Log a formatted warning string.
Definition Console.h:66
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::function< DirectedControlSamplerPtr(const SpaceInformation *)> DirectedControlSamplerAllocator
Definition of a function that can allocate a directed control sampler.
std::function< void(const base::State *, const Control *, const double, base::State *)> StatePropagatorFn
A function that achieves state propagation.
STL namespace.