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

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

В данном примере робот блуждает в среде с помощью класса VectorFieldHistogram с лазерными данными сканирования, чтобы выполнить предотвращение препятствия. Цель состоит в том, чтобы заменить алгоритм векторной полевой гистограммы (VFH) на файл MEX, созданный из генерации кода.

Чтобы видеть этот пример без генерации кода, смотрите Предотвращение Препятствия с TurtleBot и VFH.

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

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

function steerDir = vfhCodeGen(ranges,angles,targetDir)
	%#codegen	
	vfh = robotics.VectorFieldHistogram;
	vfh.DistanceLimits = [0.05 1];
	vfh.RobotRadius = 0.1;
	vfh.MinTurningRadius = 0.2;
	vfh.SafetyDistance = 0.1;
	
	steerDir = vfh(ranges,angles,targetDir); 
end 

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

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

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

Задайте демонстрационные значения для входных параметров. Создайте выборку областей значений, углов, и предназначайтесь для направлений. Сканирование лазера TurtleBot® дает 640 сканирований.

ranges = zeros(640,1);
angles = zeros(640,1);
targetDir = 0;

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

codegen vfhCodeGen -args {ranges,angles,targetDir}

Если ваше лазерное сканирование может прибыть из других источников с длинами переменного размера, задайте канонический тип ranges и входных параметров angles при помощи coder.typeof с функцией codegen .

codegen vfhCodeGen -args {coder.typeof(ranges,[Inf 1]), ...
                          coder.typeof(angles,[Inf 1]),targetDir}

Проверяйте производительность сгенерированного кода

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

time = timeit(@() vfhCodeGen(ranges,angles,targetDir))
mexTime = timeit(@() vfhCodeGen_mex(ranges,angles,targetDir))
time =

    0.0039


mexTime =

   7.6490e-05

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

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

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

Откройте Предотвращение Препятствия с TurtleBot и примером VFH.

openExample('robotics/ObstacleAvoidanceWithTurtleBotAndVFHExample')

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

Соединитесь с TurtleBot. Настройте лазерного подписчика сканирования, скоростного издателя и объект управления уровня. Задайте стартовое целевое направление.

rosinit('192.168.154.131')
laserSub = rossubscriber('/scan');
[velPub, velMsg] = rospublisher('/mobile_base/commands/velocity');
rate = robotics.Rate(10);
targetDir = 0;

Создайте цикл, который собирает данные, вычисляет держащееся направление и управляет роботом. Назначьте время цикла 30 секунд. Замените вызов step на vfhCodeGen_mex.

while rate.TotalElapsedTime < 30

	% Get laser scan data
	laserScan = receive(laserSub);
	ranges = double(laserScan.Ranges);
	angles = double(readScanAngles(laserScan));
	
	% Call MEX function created using code generation
	steerDir = vfhCodeGen_mex(ranges,angles,targetDir);
    
	% Calculate velocities
	if ~isnan(steerDir) % If steering direction is valid
		desiredV = 0.2;
		w = exampleHelperComputeAngularVelocity(steerDir,1);
	else % Stop and search for valid direction
		desiredV = 0.0;
		w = 0.5;
	end

	% Assign and send velocity commands
	velMsg.Linear.X = desiredV;
	velMsg.Angular.Z = w;
	send(velPub,velMsg);
end

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

Отключитесь от сети ROS.

rosshutdown

Смотрите также

| |

Похожие темы