exponenta event banner

Создание кода для планирования и выполнения траекторий без столкновений с помощью манипулятора KINOVA Gen3

В этом примере показано, как генерировать код для ускорения планирования и выполнения траекторий роботов без столкновений с замкнутым контуром с использованием модельного прогнозирующего управления (MPC). Дополнительные сведения об использовании MPC для планирования движения роботов-манипуляторов см. в примере Планирование и выполнение траекторий без столкновений с помощью KINOVA Gen3 Manuulator (Robotics System Toolbox).

Изменения для создания кода

Чтобы включить генерацию кода, адаптируйте код в окне Планирование и выполнение траекторий без коллизий с помощью KINOVA Gen3 Manapulator (Robotics System Toolbox), следуя приведенным ниже шагам.

  • Убедитесь, что все вспомогательные нелинейные функции MPC хранятся в виде отдельных программных файлов вместо анонимных функций. В этом примере требуются следующие вспомогательные файлы.

- Пользовательская функция затрат: nlmpcCostFunctionKINOVACodeGen.m

- пользовательские ограничения неравенства: nlmpcIneqConFunctionKINOVACodeGen.m

- Функция состояния: nlmpcModelKINOVACodeGen.m

- Функция вывода: nlmpcOutputKINOVACodeGen.m

- Якобиан пользовательской функции затрат: nlmpcJacobianCostKINOVACodeGen.m

- Якобян о пользовательских ограничениях неравенства: nlmpcJacobianConstraintKINOVACodeGen.m

- Якобян государственной функции: nlmpcJacobianModelKINOVACodeGen.m

- Якобиан выходной функции: nlmpcJacobianOutputKINOVACodeGen.m

  • Используйте Parameters имущества nlmpcmoveopt (и, когда mex файл, onlineData структура), чтобы передать контроллеру любой параметр, который может измениться во время выполнения (то есть на каждом шаге времени) или между последовательными запусками. Например, чтобы включить обновление препятствий в соответствии с новыми показаниями датчика на каждом временном шаге, значения текущего препятствия представляют (posesNow) добавляются к params переменная ячейки. Аналогично, для обновления целевой позы робота в оперативном режиме, целевая поза (poseFinal) добавляется к Parameters список. Все параметры должны быть числовыми значениями. На каждом шаге времени обновляется значение params затем копируется в Parameters свойства любого из nlmpcmoveopt объект (если nlmpcmove используется) или в onlineData структура (если используется файл MEX).

  • Использовать persistent переменные для передачи в переменные, которые не являются числовыми и не изменяются извне во время выполнения. Например, rigidBodyTree(Панель инструментов системы робототехники) robot и массив ячеек collisionMesh(Панель инструментов системы робототехники) world создаются и сохраняются как постоянные переменные при первом выполнении вспомогательной функции с использованием следующего кода.

persistent robot world    
if isempty(robot)
    robot = loadrobot('kinovaGen3', 'DataFormat', 'column');  
    [world, ~] = helperCreateObstaclesKINOVA(posesNow);
end 
  • Убедитесь, что все функции, используемые в вспомогательных файлах, поддерживают создание кода. Список встроенных функций MATLAB, поддерживаемых для создания кода, см. на этой странице. Чтобы проверить, поддерживает ли пользовательская функция генерацию кода, используйте coder.screener (Симулинк). Например, попробуйте запустить coder.screener('nlmpcIneqConFunctionKINOVA'). Этот пример требует, чтобы loadrobot (инструментарий робототехнической системы) и checkCollision (Robotics System Toolbox) поддерживает создание кода.

  • Использовать getCodeGenerationData и buildMEX для создания кода для nlmpc с указанными свойствами. Заменить nlmpcmove в исходном примере с созданным файлом MEX для вычисления оптимальных действий управления.

Описание робота и позы

Загрузите модель дерева жесткого тела (RBT) KINOVA Gen3.

robot = loadrobot('kinovaGen3', 'DataFormat', 'column');

Получи количество стыков.

numJoints = numel(homeConfiguration(robot));

Укажите рамку робота, к которой присоединен конечный эффектор.

endEffector = "EndEffector_Link"; 

Укажите начальные и требуемые конечные эффекторные позы. Используйте обратную кинематику для решения начальной конфигурации робота, заданной в нужной позе.

% Initial end-effector pose
taskInit = trvec2tform([[0.4 0 0.2]])*axang2tform([0 1 0 pi]);

% Compute current robot joint configuration using inverse kinematics
ik = inverseKinematics('RigidBodyTree', robot);
ik.SolverParameters.AllowRandomRestart = false;
weights = [1 1 1 1 1 1];
currentRobotJConfig = ik(endEffector, taskInit, weights, robot.homeConfiguration);
currentRobotJConfig = wrapToPi(currentRobotJConfig);

% Final (desired) end-effector pose
taskFinal = trvec2tform([0.35 0.55 0.35])*axang2tform([0 1 0 pi]);  
anglesFinal = rotm2eul(taskFinal(1:3,1:3),'XYZ');
poseFinal = [taskFinal(1:3,4);anglesFinal']; % 6x1 vector for final pose: [x, y, z, phi, theta, psi]

Сети столкновений и препятствия

Чтобы проверить и избежать конфликтов во время управления, необходимо настроить конфликт world как набор объектов коллизий. В этом примере используется collisionSphere (Robotics System Toolbox) объекты как препятствия для предотвращения. Для планирования с использованием статических, а не движущихся объектов задайте isMovingObst кому false.

isMovingObst = true;

Размеры и расположения препятствий инициализируются в helperCreateMovingObstaclesKINOVACodeGen функция помощника. Чтобы добавить дополнительные статические препятствия, добавьте объекты столкновения в world массив.

if isMovingObst == true
    helperCreateMovingObstaclesKINOVACodeGen
else
    posesNow = [0.4 0.4 0.25 ; 0.3 0.3 0.4];
end
[world, numObstacles] = helperCreateObstaclesKINOVACodeGen(posesNow);

Визуализация робота при начальной конфигурации. Вы также должны видеть препятствия в окружающей среде.

x0 = [currentRobotJConfig', zeros(1,numJoints)];
helperInitialVisualizerKINOVACodeGen;

Figure contains an axes. The axes contains 11 objects of type patch, line. These objects represent base_link, Shoulder_Link, HalfArm1_Link, HalfArm2_Link, ForeArm_Link, Wrist1_Link, Wrist2_Link, Bracelet_Link, EndEffector_Link, Shoulder_Link_mesh, HalfArm1_Link_mesh, HalfArm2_Link_mesh, ForeArm_Link_mesh, Wrist1_Link_mesh, Wrist2_Link_mesh, Bracelet_Link_mesh, base_link_mesh.

Укажите безопасное расстояние от препятствий. Это значение используется в функции ограничения неравенства нелинейного контроллера MPC.

safetyDistance = 0.01; 

Расчетный контроллер прогнозирования нелинейной модели

Можно спроектировать контроллер прогнозирования нелинейной модели с помощью helperDesignNLMPCobjKINOVACodeGen вспомогательный файл, который создает nlmpc объект контроллера. Для просмотра файла в командной строке MATLAB введите edit helperDesignNLMPCobjKINOVACodeGen.

helperDesignNLMPCobjKINOVACodeGen;

Планирование траектории с замкнутым контуром

Смоделировать робота максимум на 50 шагов с правильными исходными условиями.

Инициализация параметров моделирования

maxIters = 50;
u0 = zeros(1,numJoints);
mv = u0';
time = 0;
goalReached = false;

Создать код для объекта nlmpc

useMex = true;
buildMex = true;
if useMex
    [coredata, onlinedata] = getCodeGenerationData(nlobj,x0',u0',paras);
    if buildMex
        mexfcn = buildMEX(nlobj,'kinovaMex',coredata,onlinedata);
    end
end
Generating MEX function "kinovaMex" from nonlinear MPC to speed up simulation.
Code generation successful.

MEX function "kinovaMex" successfully generated.

Инициализация массива данных для управления

positions = zeros(numJoints,maxIters);
positions(:,1) = x0(1:numJoints)';

velocities = zeros(numJoints,maxIters);
velocities(:,1) = x0(numJoints+1:end)';

accelerations = zeros(numJoints,maxIters);
accelerations(:,1) = u0';

timestamp = zeros(1,maxIters);
timestamp(:,1) = time;

Создать траекторию

Использовать созданный файл MEX kinovaMex вместо nlmpcmove функция ускорения формирования траектории замкнутого контура. Укажите опции создания траектории в диалоговом режиме с помощью аргумента onlineData.

Каждая итерация вычисляет положение, скорость и ускорение соединений, чтобы избежать препятствий при их движении к цели. helperCheckGoalReachedKINOVACodeGen сценарий проверяет, достиг ли робот цели. helperUpdateMovingObstaclesKINOVACodeGen сценарий перемещает местоположения препятствий на основе временного шага.

options = nlmpcmoveopt;

for timestep=1:maxIters
    disp(['Calculating control at timestep ', num2str(timestep)]);
    % Optimize next trajectory point 
    if ~useMex
        options.Parameters = paras;
        [mv,options,info] = nlmpcmove(nlobj,x0,mv,[],[], options);
    else
        onlinedata.Parameters = paras; 
        [mv,onlinedata,info] = kinovaMex(x0',mv,onlinedata);
    end
    if info.ExitFlag < 0
        disp('Failed to compute a feasible trajectory. Aborting...')
        break;
    end
    % Update states and time for next iteration
    x0 = info.Xopt(2,:);
    time = time + nlobj.Ts;
    % Store trajectory points
    positions(:,timestep+1) = x0(1:numJoints)';
    velocities(:,timestep+1) = x0(numJoints+1:end)';
    accelerations(:,timestep+1) = info.MVopt(2,:)';
    timestamp(timestep+1) = time;
    % Check if goal is achieved 
    helperCheckGoalReachedKINOVACodeGen;
    if goalReached
        break;
    end
    % Update obstacle pose if it is moving
    if isMovingObst
        helperUpdateMovingObstaclesKINOVACodeGen;
    end
end
Calculating control at timestep 1
Calculating control at timestep 2
Calculating control at timestep 3
Calculating control at timestep 4
Calculating control at timestep 5
Calculating control at timestep 6
Calculating control at timestep 7
Calculating control at timestep 8
Target configuration reached.

Выполнение запланированной траектории с использованием низкочеткого управления роботами и моделирования

Обрезать векторы траектории на основе временных шагов, рассчитанных на основе плана.

tFinal = timestep+1;
positions = positions(:,1:tFinal);
velocities = velocities(:,1:tFinal);
accelerations = accelerations(:,1:tFinal);
timestamp = timestamp(:,1:tFinal);

visTimeStep = 0.2;

Использовать jointSpaceMotionModel объект для отслеживания траектории с помощью управления расчетным крутящим моментом. helperTimeBasedStateInputsKINOVA функция генерирует производные входы для ode15s Решатель ОДУ для моделирования движения робота по расчетной траектории.

motionModel = jointSpaceMotionModel('RigidBodyTree', robot);

% Control robot to target trajectory points in simulation using low-fidelity model
initState = [positions(:,1);velocities(:,1)];
targetStates = [positions;velocities;accelerations]';    
[t,robotStates] = ode15s(@(t,state) helperTimeBasedStateInputsKINOVA(motionModel, timestamp, targetStates, t, state), [timestamp(1):visTimeStep:timestamp(end)], initState);

Визуализация движения робота.

helperFinalVisualizerKINOVACodeGen;

Figure contains an axes. The axes contains 52 objects of type patch, line. These objects represent base_link, Shoulder_Link, HalfArm1_Link, HalfArm2_Link, ForeArm_Link, Wrist1_Link, Wrist2_Link, Bracelet_Link, EndEffector_Link, Shoulder_Link_mesh, HalfArm1_Link_mesh, HalfArm2_Link_mesh, ForeArm_Link_mesh, Wrist1_Link_mesh, Wrist2_Link_mesh, Bracelet_Link_mesh, base_link_mesh.

Как и ожидалось, робот успешно движется по запланированной траектории и избегает препятствий.

См. также

|

Связанные темы