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