Ejecutar código a una tasa fija
Introducción
Al ejecutar código a intervalos constantes, puede cronometrar y programar tareas con precisión. El uso de un objeto rateControl
le permite controlar la velocidad de ejecución de su código. Estos ejemplos muestran diferentes aplicaciones para el objeto rateControl
, incluidos sus usos con ROS y el envío de comandos para el control del robot.
Ejecutar bucle a velocidad fija
Cree un objeto de velocidad que se ejecute a 1 Hz.
r = rateControl(1);
Inicie un bucle utilizando el objeto rateControl
dentro para controlar la ejecución del bucle. Restablezca el objeto antes de la ejecución del bucle para restablecer el temporizador. Imprime la iteración y el tiempo transcurrido.
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.001865 Iteration: 2 - Time Elapsed: 1.000779 Iteration: 3 - Time Elapsed: 2.001266 Iteration: 4 - Time Elapsed: 3.001085 Iteration: 5 - Time Elapsed: 4.000798 Iteration: 6 - Time Elapsed: 5.001535 Iteration: 7 - Time Elapsed: 6.000616 Iteration: 8 - Time Elapsed: 7.001048 Iteration: 9 - Time Elapsed: 8.000344 Iteration: 10 - Time Elapsed: 9.000979
Cada iteración se ejecuta en un intervalo de 1 segundo.
Acciones de desbordamiento para la ejecución de tasa fija
El objeto rateControl
utiliza la propiedad OverrunAction
para decidir cómo manejar el código que tarda más que el período deseado en funcionar. Las opciones son 'slip'
(predeterminado) o 'drop'
. Este ejemplo muestra cómo OverrunAction
afecta la ejecución del código.
Configure la velocidad deseada y el tiempo de bucle. slowFrames
es una matriz de momentos en los que el bucle debe detenerse por más tiempo que la velocidad deseada.
desiredRate = 1; loopTime = 20; slowFrames = [3 7 12 18];
Cree el objeto Rate
y especifique la propiedad OverrunAction
. 'slip'
indica que la función waitfor
regresará inmediatamente si el tiempo para LastPeriod
es mayor que la propiedad DesiredRate
.
rate = rateControl(desiredRate);
rate.OverrunAction = 'slip';
Restablecer el objeto Rate
y comenzar el bucle. Este bucle se ejecutará a la velocidad deseada hasta que se alcance el tiempo del bucle. Cuando TotalElapsedTime
alcanza un tiempo de cuadro lento, se detendrá durante más tiempo que el período deseado.
reset(rate); while rate.TotalElapsedTime < loopTime if ~isempty(find(slowFrames == floor(rate.TotalElapsedTime))) pause(desiredRate + 0.1) end waitfor(rate); end
Ver estadísticas sobre el objeto Rate
. Observe el número de períodos.
stats = statistics(rate)
stats = struct with fields:
Periods: [1.0014 0.9991 0.9999 1.1024 0.9994 0.9999 1.0003 1.1032 0.9987 1.0003 1.0004 1.0004 1.1015 0.9992 1.0003 1.0002 1.0000 1.0000 1.1009 1.0002]
NumPeriods: 20
AveragePeriod: 1.0204
StandardDeviation: 0.0419
NumOverruns: 4
Cambie OverrunAction
a 'drop'
. 'drop'
indica que la función waitfor
regresará en el siguiente paso de tiempo, incluso si LastPeriod
es mayor que la propiedad DesiredRate
. Esto efectivamente elimina la iteración que se perdió debido a la ejecución más lenta del código.
rate.OverrunAction = 'drop';
Restablecer el objeto Rate
y comenzar el bucle.
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.0002 1.0008 0.9999 2.0022 0.9977 0.9999 2.0002 0.9996 1.0004 0.9993 2.0012 0.9993 1.0003 0.9994 1.0004 2.0005]
NumPeriods: 16
AveragePeriod: 1.2501
StandardDeviation: 0.4478
NumOverruns: 4
El uso de la acción de ejecución excesiva 'drop'
dio como resultado 16 períodos, mientras que 'slip'
dio como resultado 20 períodos. Esta diferencia se debe a que 'slip'
no esperó hasta el siguiente intervalo en función de la velocidad deseada. Básicamente, el uso de 'slip'
intenta mantener la propiedad AveragePeriod
lo más cerca posible de la tasa deseada. El uso de 'drop'
garantiza que el código se ejecutará en un intervalo uniforme con respecto a DesiredRate
y se omitirán algunas iteraciones.
Consulte también
rateControl
| rosrate
(ROS Toolbox) | waitfor
(Robotics System Toolbox)