Фильтр частиц является рекурсивным байесовским алгоритмом оценки, основанным на дискретизации, который реализован в stateEstimatorPF
объект. В этом примере робот, подобный автомобилю с дистанционным управлением, отслеживается в окружении на открытом воздухе. Измерение положения робота обеспечивается бортовым GPS, который является шумным. Существуют известные команды движения, отправленные роботу, но робот не будет выполнять точное командное движение из-за механической слабости или неточности модели. В этом примере будет показано, как использовать stateEstimatorPF
уменьшить эффекты шума в данных измерений и получить более точную оценку положения робота. Кинематическая модель робота, подобного автомобилю, описывается следующей нелинейной системой. Фильтр частиц идеально подходит для оценки состояния таких систем, так как он может иметь дело с присущими ему нелинейностями.
Сценарий: Подобный автомобилю робот управляет и постоянно изменяет свою скорость и угол поворота. Положение робота измеряется некоторой шумной внешней системой, например GPS или системой Vicon. Вдоль пути она будет проходить через кровельный участок, где измерения не могут быть сделаны.
Вход:
Шумное измерение на частичном положении робота (, , ). Обратите внимание, что это не полное измерение состояния. Нет измерений на ориентации переднего колеса () а также все скорости (, , , ).
Линейные и угловые скорости, отправленная роботу (, ). Обратите внимание, что между командным движением и фактическим движением робота будет некоторое различие.
Цель: Оценить частичное положение (, , ) робота, похожего на автомобиль. Еще раз обратите внимание, что ориентация колеса () не включена в оценку. С точки зрения наблюдателя, полное состояние автомобиля только [ , , , , , ].
Подход: Использование stateEstimatorPF
обработать два шумных входов (ни один из входов не надежен сам по себе) и сделать лучшую оценку текущего (частичного) положения.
На этапе предсказания мы обновляем состояния частиц с помощью упрощенной, одноколесной модели робота, как показано ниже. Обратите внимание, что системная модель, используемая для оценки состояния, не является точным представлением фактической системы. Это приемлемо, пока различие между моделями хорошо улавливается в системном шуме (как представлено роем частиц). Для получения дополнительной информации см. predict
.
На правильном этапе вес важности (вероятность) частицы определяется ее нормой ошибки от измерения тока (), так как у нас есть только измерения по этим трем компонентам. Для получения дополнительной информации см. correct
.
rng('default'); % for repeatable result dt = 0.05; % time step initialPose = [0 0 0 0]'; carbot = ExampleHelperCarBot(initialPose, dt);
Этот раздел конфигурирует фильтр частиц, используя 5000 частиц. Первоначально все частицы случайным образом отбираются из нормального распределения со средним значением в начальном состоянии и единичной ковариацией. Каждая частица содержит 6 переменных состояния (, , , , , ). Обратите внимание, что третья переменная отмечена как Circular, поскольку это ориентация автомобиля. Также очень важно задать две функции обратного вызова StateTransitionFcn
и MeasurementLikelihoodFcn
. Эти две функции непосредственно определяют эффективность фильтра частиц. Детали этих двух функций можно найти в последних двух разделах этого примера.
pf = stateEstimatorPF; initialize(pf, 5000, [initialPose(1:3)', 0, 0, 0], eye(6), 'CircularVariables',[0 0 1 0 0 0]); pf.StateEstimationMethod = 'mean'; pf.ResamplingMethod = 'systematic'; % StateTransitionFcn defines how particles evolve without measurement pf.StateTransitionFcn = @exampleHelperCarBotStateTransition; % MeasurementLikelihoodFcn defines how measurement affect the our estimation pf.MeasurementLikelihoodFcn = @exampleHelperCarBotMeasurementLikelihood; % Last best estimation for x, y and theta lastBestGuess = [0 0 0];
Обратите внимание, что в этом примере командные линейные и угловые скорости для робота являются произвольно выбранными зависящими от времени функциями. Кроме того, обратите внимание, что синхронизация с фиксированной скоростью цикла реализуется через rateControl
.
Запуск цикла с частотой 20 Гц в течение 20 секунд с помощью поддержки с фиксированной скоростью.
r = rateControl(1/dt);
Сбросьте объект с фиксированной скоростью, чтобы перезапустить таймер. Сбросьте таймер непосредственно перед запуском зависящего от времени кода.
reset(r); simulationTime = 0; while simulationTime < 20 % if time is not up % Generate motion command that is to be sent to the robot % NOTE there will be some discrepancy between the commanded motion and the % motion actually executed by the robot. uCmd(1) = 0.7*abs(sin(simulationTime)) + 0.1; % linear velocity uCmd(2) = 0.08*cos(simulationTime); % angular velocity drive(carbot, uCmd); % Predict the carbot pose based on the motion model [statePred, covPred] = predict(pf, dt, uCmd); % Get GPS reading measurement = exampleHelperCarBotGetGPSReading(carbot); % If measurement is available, then call correct, otherwise just use % predicted result if ~isempty(measurement) [stateCorrected, covCorrected] = correct(pf, measurement'); else stateCorrected = statePred; covCorrected = covPred; end lastBestGuess = stateCorrected(1:3); % Update plot if ~isempty(get(groot,'CurrentFigure')) % if figure is not prematurely killed updatePlot(carbot, pf, lastBestGuess, simulationTime); else break end waitfor(r); % Update simulation time simulationTime = simulationTime + dt; end
Три рисунка показывают отслеживающую эффективность фильтра частиц.
На первом рисунке фильтр частиц отслеживает автомобиль, и он уезжает от начального положения.
На втором рисунке робот заходит в кровельную область, где невозможно выполнить измерение, и частицы эволюционируют только на основе модели предсказания (отмеченной оранжевым цветом). Можно видеть, что частицы постепенно образуют подковообразный фронт, и предполагаемое положение постепенно отклоняется от фактического.
На третьем рисунке робот выехал из кровельного участка. При новых измерениях предполагаемое положение постепенно сходится назад к фактическому положению.
Основанная на дискретизации функция перехода состояния развивает частицы на основе предписанной модели движения, так что частицы образуют представление распределения предложения. Ниже приведен пример переходной функции состояния, основанной на модели скоростного движения одноколесного робота. Для получения дополнительной информации об этой модели движения, пожалуйста, смотрите главу 5 в [1]. Уменьшите sd1
, sd2
и sd3
чтобы увидеть, как ухудшается эффективность отслеживания. Вот sd1
представляет неопределенность в линейной скорости, sd2
представляет неопределенность в скорость вращения. sd3
является дополнительным возмущением ориентации.
function predictParticles = exampleHelperCarBotStateTransition(pf, prevParticles, dT, u)
thetas = prevParticles(:,3);
w = u(2); v = u(1);
l = length(prevParticles);
% Generate velocity samples sd1 = 0.3; sd2 = 1.5; sd3 = 0.02; vh = v + (sd1)^2*randn(l,1); wh = w + (sd2)^2*randn(l,1); gamma = (sd3)^2*randn(l,1);
% Add a small number to prevent div/0 error wh(abs(wh)<1e-19) = 1e-19;
% Convert velocity samples to pose samples predictParticles(:,1) = prevParticles(:,1) - (vh./wh).*sin(thetas) + (vh./wh).*sin(thetas + wh*dT); predictParticles(:,2) = prevParticles(:,2) + (vh./wh).*cos(thetas) - (vh./wh).*cos(thetas + wh*dT); predictParticles(:,3) = prevParticles(:,3) + wh*dT + gamma*dT; predictParticles(:,4) = (- (vh./wh).*sin(thetas) + (vh./wh).*sin(thetas + wh*dT))/dT; predictParticles(:,5) = ( (vh./wh).*cos(thetas) - (vh./wh).*cos(thetas + wh*dT))/dT; predictParticles(:,6) = wh + gamma;
end
Функция правдоподобия измерения вычисляет вероятность для каждой предсказанной частицы на основе нормы ошибки между частицей и измерением. Вес важности для каждой частицы будет назначаться на основе вычисленной вероятности. В этом конкретном примере predictParticles
является матрицей N x 6 (N - количество частиц), и measurement
является вектором 1 x 3.
function likelihood = exampleHelperCarBotMeasurementLikelihood(pf, predictParticles, measurement)
% The measurement contains all state variables predictMeasurement = predictParticles;
% Calculate observed error between predicted and actual measurement % NOTE in this example, we don't have full state observation, but only % the measurement of current pose, therefore the measurementErrorNorm % is only based on the pose error. measurementError = bsxfun(@minus, predictMeasurement(:,1:3), measurement); measurementErrorNorm = sqrt(sum(measurementError.^2, 2));
% Normal-distributed noise of measurement % Assuming measurements on all three pose components have the same error distribution measurementNoise = eye(3);
% Convert error norms into likelihood measure. % Evaluate the PDF of the multivariate normal distribution likelihood = 1/sqrt((2*pi).^3 * det(measurementNoise)) * exp(-0.5 * measurementErrorNorm);
end
[1] С. Трун, У. Бургард, Д. Фокс, Вероятностная робототехника, MIT Press, 2006