Выполните код в с фиксированной процентной ставкой

Введение

Используя объект robotics.Rate или rosrate функция позволяет вам итерациям времени ваших приложений робототехники. Путем выполнения кода в постоянных интервалах вы можете точно время и планировать задачи. Эти примеры показывают различные приложения для объекта Rate включая его использование с ROS и передающие команды для управления роботом.

В зависимости от вашего приложения функция rosrate и объект robotics.Rate предлагают различные варианты. Если требуется выполнить код на основе системного времени компьютера, создайте объект с помощью robotics.Rate. Однако, если вы соединяетесь с сетью ROS и хотите основывать выполнение кода на времени ROS, можно использовать функцию rosrate.

Отправьте команды управления с фиксированной процентной ставкой в робота

Этот пример показывает, чтобы отправить регулярные команды в робота по фиксированной процентной ставке. Это использует объект Rate выполнить цикл, который публикует сообщения std_msgs/Twist к сети в равном интервале.

Сеть ROS Setup. Задайте IP-адрес, если ваша сеть ROS уже существует.

rosinit
Initializing ROS master on http://AH-SRADFORD:11311/.
Initializing global node /matlab_global_node_26621 with NodeURI http://AH-SRADFORD:50081/

Издатель Setup и сообщение для отправки команд Twist.

[pub,msg] = rospublisher('/cmd_vel','geometry_msgs/Twist');
msg.Linear.X = 0.5;
msg.Angular.Z = -0.5;

Создайте объект Rate с заданными параметрами цикла.

desiredRate = 10;
rate = robotics.Rate(desiredRate);
rate.OverrunAction = 'drop'
rate = 

  Rate with properties:

         DesiredRate: 10
       DesiredPeriod: 0.1000
       OverrunAction: 'drop'
    TotalElapsedTime: 0.0300
          LastPeriod: NaN

Запустите цикл и содержите каждую итерацию с помощью waitfor(rate). Отправьте сообщение Twist в цикле. Сбросьте объект Rate перед циклом, чтобы сбросить синхронизацию.

reset(rate)

while rate.TotalElapsedTime < 10
   send(pub,msg)
   waitfor(rate);
end

Просмотрите статистику выполнения с фиксированной процентной ставкой. Посмотрите на AveragePeriod, чтобы проверить, что желаемый уровень сохранялся.

statistics(rate)
ans = 

  struct with fields:

              Periods: [1×100 double]
           NumPeriods: 100
        AveragePeriod: 0.1000
    StandardDeviation: 3.4189e-04
          NumOverruns: 0

Закройте сеть ROS

rosshutdown
Shutting down global node /matlab_global_node_26621 with NodeURI http://AH-SRADFORD:50081/
Shutting down ROS master on http://AH-SRADFORD:11311/.

Публикация с фиксированной процентной ставкой данных изображения ROS

Этот пример показывает, как регулярно публиковать и получать сообщения изображений с помощью ROS и функции rosrate. Функция rosrate создает объект Rate к, регулярно получают доступ к теме /camera/rgb/image_raw в сети ROS с помощью подписчика. Изображение rgb преобразовано в шкалу полутонов с помощью rgb2gray и переиздано в равном интервале. Параметры, такие как IP-адрес и названия темы меняются в зависимости от вашего робота и настройки.

Соединитесь с сетью ROS. Подписчик Setup, издатель и сообщение данных.

ipaddress = '172.28.194.188'; % Replace with your network address
rosinit(ipaddress)
sub = rossubscriber('/camera/rgb/image_raw');
pub = rospublisher('/camera/gray/image_gray','sensor_msgs/Image');
msgGray = rosmessage('sensor_msgs/Image');
msgGray.Encoding = 'mono8';
Initializing global node /matlab_global_node_04172 with NodeURI http://172.28.194.235:61739/

Получите первое сообщение изображений. Извлеките изображение и преобразуйте в полутоновое изображение. Отобразите полутоновое изображение и опубликуйте сообщение.

msgImg = receive(sub);

img = readImage(msgImg);
grayImg = rgb2gray(img);
imshow(grayImg)

writeImage(msgGray,grayImg)
send(pub,msgGray)

Создайте объект ROS Rate выполниться на уровне 10 Гц. Назначьте время цикла и OverrunAction для обработки

desiredRate = 10;
loopTime = 5;
overrunAction = 'slip';
rate = rosrate(desiredRate);
r.OverrunAction = overrunAction;

Начните цикл, чтобы получить, обработать и отправить сообщениям каждые 0,1 секунды (10 Гц). Сбросьте объект Rate перед началом.

reset(rate)

for i = 1:desiredRate*loopTime

    msgImg = receive(sub);

    img = readImage(msgImg);
    grayImg = rgb2gray(img);
    writeImage(msgGray,grayImg)

    send(pub,msgGray)

    waitfor(rate);
end

Просмотрите статистику для выполнения кода. AveragePeriod и StandardDeviation показывают, как хорошо код поддержал desiredRate. OverRuns происходит, когда обработка данных занимает больше времени, чем желаемая длина периода.

statistics(rate)
ans = 

              Periods: [1x50 double]
           NumPeriods: 50
        AveragePeriod: 0.1024
    StandardDeviation: 0.0193
          NumOverruns: 1

Закройте узел ROS

rosshutdown
Shutting down global node /matlab_global_node_04172 with NodeURI http://172.28.194.235:61739/

Превысьте действия для выполнения фиксированной процентной ставки

Объект Rate использует свойство OverrunAction решить, как обработать код, который занимает больше времени, чем желаемый период, чтобы действовать. Опциями является 'slip' (значение по умолчанию) или 'drop'. Этот пример показывает, как OverrunAction влияет на выполнение кода.

Setup желал время цикла и уровня. slowFrames является массивом времен, когда цикл должен быть остановлен дольше, чем желаемый уровень.

desiredRate = 1;
loopTime = 20;
slowFrames = [3 7 12 18];

Создайте объект Rate и задайте свойство OverrunAction. 'slip' указывает, что функция waitfor сразу возвратится, если время для LastPeriod будет больше, чем свойство DesiredRate.

rate = robotics.Rate(desiredRate);
rate.OverrunAction = 'slip';

Сбросьте объект Rate и начните цикл. Этот цикл выполнится на желаемом уровне, пока время цикла не будет достигнуто. Когда TotalElapsedTime достигнет медленного времени кадра, он остановится для дольше, чем желаемый период.

reset(rate);

while rate.TotalElapsedTime < loopTime
    if ~isempty(find(slowFrames == floor(rate.TotalElapsedTime)))
        pause(desiredRate + 0.1)
    end
    waitfor(rate);
end

Просмотрите статистику по объекту Rate. Заметьте количество периодов.

stats = statistics(rate)
stats = struct with fields:
              Periods: [1x20 double]
           NumPeriods: 20
        AveragePeriod: 1.0204
    StandardDeviation: 0.0422
          NumOverruns: 4

Измените OverrunAction на 'drop'. 'drop' указывает, что функция waitfor возвратится на следующем временном шаге, даже если LastPeriod будет больше, чем свойство DesiredRate. Это эффективно пропускает итерацию, которая была пропущена более медленным выполнением кода.

rate.OverrunAction = 'drop';

Сбросьте объект Rate и начните цикл.

reset(rate);

while rate.TotalElapsedTime < loopTime
    if ~isempty(find(slowFrames == floor(rate.TotalElapsedTime)))
        pause(1.1)
    end
    waitfor(rate);
end
stats2 = statistics(rate)
stats2 = struct with fields:
              Periods: [1x16 double]
           NumPeriods: 16
        AveragePeriod: 1.2500
    StandardDeviation: 0.4477
          NumOverruns: 4

Используя 'drop' по запущенному действию, приведшему к 16 периодам, когда 'slip' привел к 20 периодам. Это различие - то, потому что 'slip' не ожидал до следующего интервала на основе желаемого уровня. По существу использование 'slip' пытается сохранить свойство AveragePeriod как близко к желаемому уровню. Используя 'drop' гарантирует, что код выполнится в ровном интервале относительно DesiredRate с некоторыми пропускаемыми итерациями.

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

| |