Package: nav
Create state space for path planning
nav.StateSpace
is an interface for state spaces used for path planning.
Derive from this class if you want to define your own state space. This representation allows
for sampling, interpolation, and calculating distances between spaces in the state
space.
To create a sample template for generating your own state space class, call createPlanningTemplate
. For our implementations of the state space class, see
State Spaces.
The nav.StateSpace
class is a handle
class.
creates a state space object with a given name and state bounds.
ssObj
= nav.StateSpace(Name
,NumStateVariables
,Bounds
)NumStateVariables
specifies the number of state variables. This
constructor can only be called from a derived class. Create your own class definition
using createPlanningTemplate
.
NumStateVariables
— Number of variables in state spaceNumber of variables in state space, specified as a positive numeric scalar. This property is the dimension of the state space.
Example: 3
SetAccess - immutable
StateBounds
— Min and max bounds of state variables[min max]
| n-by-2 matrixMin and max bounds of state variables, specified as a [min max]
n-by-2 matrix. This property depends on
NumStateVariables
, where n is the number of
state variables. When specifying on construction, use the Bounds
input.
Example: [-10 10; -10 10; -pi pi]
GetAccess | public |
SetAccess | protected |
Dependent | true |
Data Types: double
Name
— Name of state space objectName of the state space object, specified as a string scalar or character vector.
Example: "customSE2StateSpace"
GetAccess | protected |
SetAccess | protected |
copy | Copy array of handle objects |
distance | Distance between two states |
enforceStateBounds | Limit state to state bounds |
interpolate | Interpolate between states |
sampleGaussian | Sample state using Gaussian distribution |
sampleUniform | Sample state using uniform distribution |
This example shows how to use the createPlanningTemplate
function to generate a template for customizing your own state space definition and sampler to use with path planning algorithms. A simple implementation is provided with the template.
Call the create template function. This function generates a class definition file for you to modify for your own implementation.
createPlanningTemplate
Class and Property Definition
The first part of the template specifies the class definition and any properties for the class. Derive from the nav.StateSpace
class. For this example, create a property for the uniform and normal distributions. You can specify any additional user-defined properties here.
classdef MyCustomStateSpace < nav.StateSpace & ... matlabshared.planning.internal.EnforceScalarHandle properties UniformDistribution NormalDistribution % Specify additional properties here end
Save your custom state space class and ensure your file name matches the class name.
Class Constructor
Use the constructor to set the name of the state space, the number of state variables, and define its boundaries. Alternatively, you can add input arguments to the function and pass the variables in when you create an object.
For each state variable, define the [min max]
values for the state bounds.
Call the constructor of the base class.
For this example, you specify the normal and uniform distribution property values using predefined NormalDistribution
and UniformDistribution
classes.
Specify any other user-defined property values here.
methods function obj = MyCustomStateSpace spaceName = "MyCustomStateSpace"; numStateVariables = 3; stateBounds = [-100 100; % [min max] -100 100; -100 100]; obj@nav.StateSpace(spaceName, numStateVariables, stateBounds); obj.NormalDistribution = matlabshared.tracking.internal.NormalDistribution(numStateVariables); obj.UniformDistribution = matlabshared.tracking.internal.UniformDistribution(numStateVariables); % User-defined property values here end
Copy Semantics
Specify the copy
method definition. Copy all the values of your user-defined variables into a new object, so copyObj
is a deep copy. The default behavior given in this example creates a new copy of the object with the same name, state bounds, and distributions.
function copyObj = copy(obj) copyObj = feval(class(obj)); copyObj.StateBounds = obj.StateBounds; copyObj.UniformDistribution = obj.UniformDistribution.copy; copyObj.NormalDistribution = obj.NormalDistribution.copy; end
Enforce State Bounds
Specify how to ensure states are always within the state bounds. For this example, the state values get saturated at the minimum or maximum values for the state bounds.
function boundedState = enforceStateBounds(obj, state) nav.internal.validation.validateStateMatrix(state, nan, obj.NumStateVariables, "enforceStateBounds", "state"); boundedState = state; boundedState = min(max(boundedState, obj.StateBounds(:,1)'), ... obj.StateBounds(:,2)'); end
Sample Uniformly
Specify the behavior for sampling across a uniform distribution. support multiple syntaxes to constrain the uniform distribution to a nearby state within a certain distance and sample multiple states.
STATE = sampleUniform(OBJ) STATE = sampleUniform(OBJ,NUMSAMPLES) STATE = sampleUniform(OBJ,NEARSTATE,DIST) STATE = sampleUniform(OBJ,NEARSTATE,DIST,NUMSAMPLES)
For this example, use a validation function to process a varargin
input that handles the varying input arguments.
function state = sampleUniform(obj, varargin) narginchk(1,4); [numSamples, stateBounds] = obj.validateSampleUniformInput(varargin{:}); obj.UniformDistribution.RandomVariableLimits = stateBounds; state = obj.UniformDistribution.sample(numSamples); end
Sample from Gaussian Distribution
Specify the behavior for sampling across a Gaussian distribution. Support multiple syntaxes for sampling a single state or multiple states.
STATE = sampleGaussian(OBJ, MEANSTATE, STDDEV) STATE = sampleGaussian(OBJ, MEANSTATE, STDDEV, NUMSAMPLES)
function state = sampleGaussian(obj, meanState, stdDev, varargin) narginchk(3,4); [meanState, stdDev, numSamples] = obj.validateSampleGaussianInput(meanState, stdDev, varargin{:}); obj.NormalDistribution.Mean = meanState; obj.NormalDistribution.Covariance = diag(stdDev.^2); state = obj.NormalDistribution.sample(numSamples); state = obj.enforceStateBounds(state); end
Interpolate Between States
Define how to interpolate between two states in your state space. Use an input, fraction
, to determine how to sample along the path between two states. For this example, define a basic linear interpolation method using the difference between states.
function interpState = interpolate(obj, state1, state2, fraction) narginchk(4,4); [state1, state2, fraction] = obj.validateInterpolateInput(state1, state2, fraction); stateDiff = state2 - state1; interpState = state1 + fraction' * stateDiff; end
Calculate Distance Between States
Specify how to calculate the distance between two states in your state space. Use the state1
and state2
inputs to define the start and end positions. Both inputs can be a single state (row vector) or multiple states (matrix of row vectors). For this example, calculate the distance based on the Euclidean distance between each pair of state positions.
function dist = distance(obj, state1, state2) narginchk(3,3); nav.internal.validation.validateStateMatrix(state1, nan, obj.NumStateVariables, "distance", "state1"); nav.internal.validation.validateStateMatrix(state2, size(state1,1), obj.NumStateVariables, "distance", "state2"); stateDiff = bsxfun(@minus, state2, state1); dist = sqrt( sum( stateDiff.^2, 2 ) ); end
Terminate the methods and class sections.
end end
Save your state space class definition. You can now use the class constructor to create an object for your state space.
nav.StateValidator
| stateSpaceDubins
| stateSpaceReedsShepp
| stateSpaceSE2
You have a modified version of this example. Do you want to open this example with your edits?