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

Введение

Выполняя код с постоянными интервалами, можно точно времени и планирования задач. Использование rateControl объект позволяет вам контролировать скорость выполнения кода. Эти примеры показывают различные приложения для rateControl объект, включая его использование с ROS и отправку команд для управления роботом.

Цикл запуска с фиксированной частотой

Создайте объект скорости, который работает с частотой 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 секунду.

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

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

Setup требуемой скорости и времени цикла. 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 с пропущенными некоторыми итерациями.

См. также

| | (ROS Toolbox)