Выполнение кода с постоянными интервалами позволяет точно определить время и расписание выполнения задач. Использование rateControl объект позволяет управлять скоростью выполнения кода. Эти примеры показывают различные приложения для rateControl объект, включающий его применение с АФК и отправку команд для управления роботом.
Создайте объект скорости с частотой 1 Гц.
r = rateControl(1);
Запуск цикла с помощью rateControl объект внутри для управления выполнением цикла. Сбросьте объект перед выполнением цикла на таймер сброса. Печать итерации и прошедшего времени.
reset(r) for i = 1:10 time = r.TotalElapsedTime; fprintf('Iteration: %d - Time Elapsed: %f\n',i,time) waitfor(r); end
Iteration: 1 - Time Elapsed: 0.002655 Iteration: 2 - Time Elapsed: 1.001775 Iteration: 3 - Time Elapsed: 2.000507 Iteration: 4 - Time Elapsed: 3.001433 Iteration: 5 - Time Elapsed: 4.001127 Iteration: 6 - Time Elapsed: 5.001328 Iteration: 7 - Time Elapsed: 6.000218 Iteration: 8 - Time Elapsed: 7.000240 Iteration: 9 - Time Elapsed: 8.000945 Iteration: 10 - Time Elapsed: 9.000661
Каждая итерация выполняется с интервалом в 1 секунду.
rateControl объект использует OverrunAction , чтобы решить, как обрабатывать код, который занимает больше времени, чем требуется для работы. Опции: 'slip' (по умолчанию) или 'drop'. В этом примере показано, как OverrunAction влияет на выполнение кода.
Установка требуемой скорости и времени цикла. slowFrames - массив времен, когда цикл должен быть остановлен дольше, чем требуемая скорость.
desiredRate = 1; loopTime = 20; slowFrames = [3 7 12 18];
Создать Rate и укажите OverrunAction собственность. 'slip' указывает, что waitfor функция вернется немедленно, если время для LastPeriod больше, чем DesiredRate собственность.
rate = rateControl(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.0205
StandardDeviation: 0.0421
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.2501
StandardDeviation: 0.4480
NumOverruns: 4
Использование 'drop' чрезмерное действие привело к 16 периодам, когда 'slip' в результате было проведено 20 периодов. Это различие связано с 'slip' не дожидался следующего интервала на основе требуемой скорости. По существу, использование 'slip' пытается сохранить AveragePeriod свойство, близкое к требуемой скорости. Используя 'drop' гарантирует, что код будет выполняться с четным интервалом относительно DesiredRate некоторые итерации пропускаются.
rateControl | waitfor | rosrate (панель инструментов ROS)