Ускорение алгоритмов робототехники с генерацией кода

Можно сгенерировать код для выбранных алгоритмов Robotics System Toolbox™, чтобы ускорить их выполнение. Настройте алгоритм, который поддерживает генерацию кода как отдельную функцию, которую можно вставить в рабочий процесс. Чтобы использовать генерацию кода, у вас должен быть MATLAB® Coder™ лицензию. Список поддержки генерации кода в Robotics System Toolbox см. в Функции, поддерживающие генерацию кода.

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

Создайте отдельную функцию для алгоритма

Создайте отдельную функцию, ikCodegen, который запускает алгоритм обратной кинематики. Создание inverseKinematics объект и создать rigidBodyTree модель внутри функции. Задайте %#codegen внутри функции, чтобы идентифицировать ее как функцию для генерации кода.

function qConfig = ikCodegen(endEffectorName,tform,weights,initialGuess)
	%#codegen
    
    robot = rigidBodyTree('MaxNumBodies',3,'DataFormat','row');
    body1 = rigidBody('body1');
    body1.Joint = rigidBodyJoint('jnt1','revolute');

    body2 = rigidBody('body2');
    jnt2 = rigidBodyJoint('jnt2','revolute');
    setFixedTransform(jnt2,trvec2tform([1 0 0]))
    body2.Joint = jnt2;

    body3 = rigidBody('tool');
    jnt3 = rigidBodyJoint('jnt3','revolute');
    setFixedTransform(jnt3,trvec2tform([1 0 0]))
    body3.Joint = jnt3;
    
    addBody(robot,body1,'base')
    addBody(robot,body2,'body1')
    addBody(robot,body3,'body2')


	ik = inverseKinematics('RigidBodyTree',robot);
	
	[qConfig,~] = ik(endEffectorName,tform,weights,initialGuess); 
end 

Сохраните функцию в текущей папке.

Выполните генерацию кода для алгоритма

Вы можете использовать любой из них codegen (MATLAB Coder) или MATLAB Coder (MATLAB Coder) приложение для генерации кода. В этом примере сгенерируйте файл MEX путем вызова codegen в командной строке MATLAB. Задайте выборку входных параметров для каждого входа в функцию используя -args входной параметр

Задайте выборку значения для входных параметров.

endEffectorName = 'tool';       
tform = trvec2tform([0.7 -0.7 0]);
weights = [0.25 0.25 0.25 1 1 1];
initialGuess = [0 0 0];

Вызовите codegen и задайте входные параметры в массиве ячеек. Эта функция создает отдельное ikCodegen_mex функцию для использования. Вы также можете создать код С при помощи options входной параметр.

codegen ikCodegen -args {endEffectorName,tform,weights,initialGuess}

Если ваш вход может быть получен из длин переменного размера, задайте канонический тип входов при помощи coder.typeof (Fixed-Point Designer) с codegen (MATLAB Coder) функция.

Проверяйте эффективность сгенерированного кода

Сравните время сгенерированной MEX-функции с временем исходной функции при помощи timeit.

time = timeit(@() ikCodegen(endEffectorName,tform,weights,initialGuess))
mexTime = timeit(@() ikCodegen_mex(endEffectorName,tform,weights,initialGuess))
time =

    0.0425


mexTime =

    0.0011

В этом примере MEX-функция работает более чем в 30 раз быстрее. Результаты могут варьироваться в вашей системе.

Замените функцию алгоритма на MEX-функцию

Откройте основную функцию для выполнения рабочего процесса робототехники. Замените ik вызов объекта с MEX-функцией, которую вы создали с использованием генерации кода. В данном примере используйте пример трассировки простого 2-D пути.

Откройте пример 2-D трассировки пути с обратной кинематикой.

openExample('robotics/TwoDInverseKinematicsExampleExample')

Измените код примера, чтобы использовать новую ikCodegen_mex функция. Последующий код является копией примера с изменениями в использовании новой MEX-функции. Определение модели робота выполняется внутри функции, поэтому пропустите раздел Конструировать робота.

Определите траекторию

t = (0:0.2:10)'; % Time
count = length(t);
center = [0.3 0.1 0];
radius = 0.15;
theta = t*(2*pi/t(end));
points = center + radius*[cos(theta) sin(theta) zeros(size(theta))];

Решение обратной кинематики

Предварительно распределите строение решения как матрицу, qs. Задайте веса для преобразования end-effector и имени end-effector.

q0 = [0 0 0];
ndof = length(q0);
qs = zeros(count, ndof);
weights = [0, 0, 0, 1, 1, 0];
endEffector = 'tool';

Проследите контур траектории точек, чтобы проследить окружность. Замените ik вызов объекта с помощью ikCodegen_mex функция. Вычислите решение для каждой точки, чтобы сгенерировать строение соединения, которая достигает положения end-effector. Сохраните строения, которые будут использоваться позже.

qInitial = q0; % Use home configuration as the initial guess
for i = 1:count
    % Solve for the configuration satisfying the desired end effector
    % position
    point = points(i,:);
    qSol = ikCodegen_mex(endEffector,trvec2tform(point),weights,qInitial);
    % Store the configuration
    qs(i,:) = qSol;
    % Start from prior solution
    qInitial = qSol;
end

Анимируйте решение

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

robot = rigidBodyTree('MaxNumBodies',15,'DataFormat','row');
body1 = rigidBody('body1');
body1.Joint = rigidBodyJoint('jnt1','revolute');

body2 = rigidBody('body2');
jnt2 = rigidBodyJoint('jnt2','revolute');
setFixedTransform(jnt2,trvec2tform([0.3 0 0]))
body2.Joint = jnt2;

body3 = rigidBody('tool');
jnt3 = rigidBodyJoint('jnt3','revolute');
setFixedTransform(jnt3,trvec2tform([0.3 0 0]))
body3.Joint = jnt3;

addBody(robot,body1,'base')
addBody(robot,body2,'body1')
addBody(robot,body3,'body2')

% Show first solution and set view.
figure
show(robot,qs(1,:));
view(2)
ax = gca;
ax.Projection = 'orthographic';
hold on
plot(points(:,1),points(:,2),'k')
axis([-0.1 0.7 -0.3 0.5])

% Iterate through the solutions
framesPerSecond = 15;
r = rateControl(framesPerSecond);
for i = 1:count
    show(robot,qs(i,:),'PreservePlot',false);
    drawnow
    waitfor(r);
end

Этот пример показал, как вы можете сгенерировать код для определенных алгоритмов или функций, чтобы улучшить их скорость и просто заменить их сгенерированной MEX-функцией в вашем рабочем процессе.

См. также

| | (MATLAB CODER)

Похожие темы