Вызовите создать функцию шаблона. Эта функция генерирует файл определения класса для вас, чтобы изменить для вашей собственной реализации.
Класс и определение свойства
Первая часть шаблона задает определение класса и любые свойства для класса. Выведите из nav.StateSpace
класс. В данном примере создайте свойство для равномерных и нормальных распределений. Можно задать любые дополнительные пользовательские свойства здесь.
classdef MyCustomStateSpace < nav.StateSpace & ...
matlabshared.planning.internal.EnforceScalarHandle
properties
UniformDistribution
NormalDistribution
% Specify additional properties here
end
Сохраните свой пользовательский класс пространства состояний и гарантируйте, что ваше имя файла совпадает с именем класса.
Конструктор класса
Используйте конструктора, чтобы определить имя пространства состояний, количество переменных состояния, и задать его контуры. В качестве альтернативы можно добавить входные параметры в функцию и передать переменные в том, когда вы создаете объект.
Для каждой переменной состояния задайте [min max]
значения для границ состояния.
Вызовите конструктора базового класса.
В данном примере вы указываете, что значения свойств нормального и равномерного распределения с помощью предопределили NormalDistribution
и UniformDistribution
классы.
Задайте любые другие пользовательские значения свойств здесь.
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
определение метода. Скопируйте все значения своих пользовательских переменных в новый объект, таким образом, copyObj
глубокая копия. Поведение по умолчанию, данное в этом примере, создает новую копию объекта с тем же именем, границами состояния и распределениями.
function copyObj = copy(obj)
copyObj = feval(class(obj));
copyObj.StateBounds = obj.StateBounds;
copyObj.UniformDistribution = obj.UniformDistribution.copy;
copyObj.NormalDistribution = obj.NormalDistribution.copy;
end
Осуществите границы состояния
Задайте, как гарантировать, что состояния всегда в границах состояния. В данном примере значения состояния насыщаются в минимальных или максимальных значениях для границ состояния.
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
Произведите однородно
Задайте поведение для выборки через равномерное распределение. поддержите несколько синтаксисов, чтобы ограничить равномерное распределение к соседнему состоянию на определенном расстоянии и выборке несколько состояний.
STATE = sampleUniform(OBJ)
STATE = sampleUniform(OBJ,NUMSAMPLES)
STATE = sampleUniform(OBJ,NEARSTATE,DIST)
STATE = sampleUniform(OBJ,NEARSTATE,DIST,NUMSAMPLES)
В данном примере используйте функцию валидации, чтобы обработать varargin
введите, который обрабатывает различные входные параметры.
function state = sampleUniform(obj, varargin)
narginchk(1,4);
[numSamples, stateBounds] = obj.validateSampleUniformInput(varargin{:});
obj.UniformDistribution.RandomVariableLimits = stateBounds;
state = obj.UniformDistribution.sample(numSamples);
end
Выборка от распределения Гаусса
Задайте поведение для выборки через Распределение Гаусса. Поддержите несколько синтаксисов для выборки одного состояния или нескольких состояний.
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
Интерполируйте между состояниями
Задайте, как интерполировать между двумя состояниями в вашем пространстве состояний. Используйте вход, fraction
, определить, как произвести вдоль пути между двумя состояниями. В данном примере задайте основной метод линейной интерполяции с помощью различия между состояниями.
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
Вычислите расстояние между состояниями
Задайте, как вычислить расстояние между двумя состояниями в вашем пространстве состояний. Используйте state1
и state2
входные параметры, чтобы задать положения начала и конца. Оба входных параметров могут быть одним состоянием (вектор-строка) или несколько состояний (матрица векторов-строк). В данном примере вычислите расстояние на основе Евклидова расстояния между каждой парой положений состояния.
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
Отключите разделы класса и методы.
Сохраните свое определение класса пространства состояний. Можно теперь использовать конструктора класса, чтобы создать объект для пространства состояний.