В этом примере показано, как создать карту среды с использованием показаний датчика дальности и позиций робота для робота с дифференциальным приводом. Вы создаете карту из показаний датчиков диапазона, которые моделируются с помощью rangeSensor объект. differentialDriveKinematics модель движения моделирует перемещение робота по комнате на основе команд скорости. rangeSensor выдает показания дальности в зависимости от позы робота при следовании по пути.
Загрузить набор примеров двоичных сеток занятости из exampleMaps, в том числе simpleMap, который используется в этом примере.
load exampleMaps.matСоздание эталонной двоичной карты занятости с помощью simpleMap с разрешением 1. Показать рисунок и сохранить маркер перемещения рисунка.
refMap = binaryOccupancyMap(simpleMap,1); refFigure = figure('Name','SimpleMap'); show(refMap);

Создайте пустую карту с теми же размерами, что и выбранная карта с разрешением 10. Показать рисунок и сохранить маркер перемещения рисунка. Зафиксируйте оси по размеру карты.
[mapdimx,mapdimy] = size(simpleMap); map = binaryOccupancyMap(mapdimy,mapdimx,10); mapFigure = figure('Name','Unknown Map'); show(map);

Создайте модель кинематического движения дифференциального привода. Модель движения представляет движение моделируемого робота с дифференциальным приводом. Эта модель использует скорости левого и правого колес или линейные и угловые скорости для курса робота. В этом примере используйте скорость и курс транспортного средства для VehicleInputs.
diffDrive = differentialDriveKinematics("VehicleInputs","VehicleSpeedHeadingRate");
Создайте чистый контроллер преследования. Этот контроллер генерирует входы скорости для моделируемого робота, чтобы следовать по нужному пути. Задайте требуемую линейную скорость и максимальную угловую скорость в метрах в секунду и радианах в секунду соответственно.
controller = controllerPurePursuit('DesiredLinearVelocity',2,'MaxAngularVelocity',3);
Создайте датчик с максимальным диапазоном 10 метров. Этот датчик моделирует показания диапазона на основе заданной позы и карты. Эталонная карта используется с этим датчиком диапазона для моделирования сбора показаний датчика в неизвестной среде.
sensor = rangeSensor; sensor.Range = [0,10];
Создайте путь для перемещения по карте для сбора показаний датчика дальности.
path = [4 6; 6.5 12.5; 4 22; 12 14; 22 22; 16 12; 20 10; 14 6; 22 3];
Постройте график траектории на рисунке ссылочной карты.
figure(refFigure); hold on plot(path(:,1),path(:,2), 'o-'); hold off
Задайте путь в качестве ППМ контроллера чистого преследования.
controller.Waypoints = path;
Задайте начальную позу и конечное местоположение цели на основе пути. Создание глобальных переменных для хранения текущей позы и индекса для отслеживания итераций.
initPose = [path(1,1) path(1,2), pi/2]; goal = [path(end,1) path(end,2)]'; poses(:,1) = initPose';
Используйте предоставленную функцию помощника exampleHelperDiffDriveControl. Вспомогательная функция содержит основной цикл навигации по пути, получения показаний диапазона и отображения среды.
exampleHelperDiffDriveControl имеет следующий рабочий процесс:
Просканируйте эталонную карту с помощью датчика дальности и текущей позы. При этом моделируются обычные показания диапазона для вождения в неизвестной среде.
Обновите карту с помощью показаний диапазона.
Получите управляющие команды от чистого контроллера слежения, чтобы перейти к следующему ППМ.
Расчет производной движения робота на основе команд управления.
Приращение позы робота на основе производной.
Вы должны видеть, как робот передвигается по пустой карте и заполняет стены, когда датчик дальности обнаруживает их.
exampleHelperDiffDriveCtrl(diffDrive,controller,initPose,goal,refMap,map,refFigure,mapFigure,sensor)


Goal position reached
exampleHelperDiffDriveControl имеет следующий рабочий процесс:
Просканируйте эталонную карту с помощью датчика дальности и текущей позы. При этом моделируются обычные показания диапазона для вождения в неизвестной среде.
Обновите карту с помощью показаний диапазона.
Получите управляющие команды от чистого контроллера слежения, чтобы перейти к следующему ППМ.
Расчет производной движения робота на основе команд управления.
Приращение позы робота на основе производной.
function exampleHelperDiffDriveControl(diffDrive,ppControl,initPose,goal,map1,map2,fig1,fig2,lidar) sampleTime = 0.05; % Sample time [s] t = 0:sampleTime:100; % Time array poses = zeros(3,numel(t)); % Pose matrix poses(:,1) = initPose'; % Set iteration rate r = rateControl(1/sampleTime); % Get the axes from the figures ax1 = fig1.CurrentAxes; ax2 = fig2.CurrentAxes; for idx = 1:numel(t) position = poses(:,idx)'; currPose = position(1:2); % End if pathfollowing is vehicle has reached goal position within tolerance of 0.2m dist = norm(goal'-currPose); if (dist < .2) disp("Goal position reached") break; end % Update map by taking sensor measurements figure(2) [ranges, angles] = lidar(position, map1); scan = lidarScan(ranges,angles); validScan = removeInvalidData(scan,'RangeLimits',[0,lidar.Range(2)]); insertRay(map2,position,validScan,lidar.Range(2)); show(map2); % Run the Pure Pursuit controller and convert output to wheel speeds [vRef,wRef] = ppControl(poses(:,idx)); % Perform forward discrete integration step vel = derivative(diffDrive, poses(:,idx), [vRef wRef]); poses(:,idx+1) = poses(:,idx) + vel*sampleTime; % Update visualization plotTrvec = [poses(1:2, idx+1); 0]; plotRot = axang2quat([0 0 1 poses(3, idx+1)]); % Delete image of the last robot to prevent displaying multiple robots if idx > 1 items = get(ax1, 'Children'); delete(items(1)); end %plot robot onto known map plotTransforms(plotTrvec', plotRot, 'MeshFilePath', 'groundvehicle.stl', 'View', '2D', 'FrameSize', 1, 'Parent', ax1); %plot robot on new map plotTransforms(plotTrvec', plotRot, 'MeshFilePath', 'groundvehicle.stl', 'View', '2D', 'FrameSize', 1, 'Parent', ax2); % waiting to iterate at the proper rate waitfor(r); end end