Используя объект 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 и функции 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 с некоторыми пропускаемыми итерациями.