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

Введение

Путем выполнения кода в постоянных интервалах вы можете точно время и планировать задачи. Используя 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 втором интервале.

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

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)