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

Введение

Путем выполнения кода в постоянных интервалах вы можете точно время и планировать задачи. Используя 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.002622
Iteration: 2 - Time Elapsed: 1.001115
Iteration: 3 - Time Elapsed: 2.001586
Iteration: 4 - Time Elapsed: 3.000964
Iteration: 5 - Time Elapsed: 4.001710
Iteration: 6 - Time Elapsed: 5.001164
Iteration: 7 - Time Elapsed: 6.000850
Iteration: 8 - Time Elapsed: 7.001124
Iteration: 9 - Time Elapsed: 8.000808
Iteration: 10 - Time Elapsed: 9.000687

Каждая итерация выполняется в 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: [1.0004 1.0000 1.0000 1.1024 0.9997 0.9997 1.0005 ... ]
           NumPeriods: 20
        AveragePeriod: 1.0203
    StandardDeviation: 0.0419
          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: [1.0003 1.0003 1.0000 2.0031 0.9970 1.0000 2.0003 ... ]
           NumPeriods: 16
        AveragePeriod: 1.2501
    StandardDeviation: 0.4478
          NumOverruns: 4

Используя 'drop' по запущенному действию привел к 16 периодам когда 'slip' приведший к 20 периодам. Это различие то, потому что 'slip' не ожидал до следующего интервала на основе желаемого уровня. По существу, использование 'slip' попытки сохранить AveragePeriod свойство как близко к желаемому уровню. Используя 'drop' гарантирует, что код выполнится в ровном интервале относительно DesiredRate с некоторыми пропускаемыми итерациями.

Смотрите также

| (ROS Toolbox) |