diff --git a/Timers-in-FTC-Blocks.md b/Timers-in-FTC-Blocks.md index b43098d..bc26653 100644 --- a/Timers-in-FTC-Blocks.md +++ b/Timers-in-FTC-Blocks.md @@ -1,7 +1,9 @@ ## Introduction -This tutorial shows FTC Blocks programmers how to use Timers. If you're in a hurry (no time), skip to the [examples below](#timer-examples). Java programmers may benefit from learning here how FTC timers work. +This tutorial shows FTC Blocks programmers how to use Timers. If you're in a hurry (no time), skip to the [examples below](#timer-examples). + +
Java programmers may benefit from learning here how FTC timers work. ## Why not Sleep? @@ -9,7 +11,7 @@ Many new Blocks programmers use the Sleep command (MyOpMode.sleep) as their only
[[/images/Timers-in-FTC-Blocks/0100-Sleep.png|Sleep]]
-This is a very basic and common use of timed action in a linear Op Mode used for Autonomous. It tells the robot to process **no new instructions** for the specified duration. +This is a very basic and common use of timed action in a linear OpMode used for Autonomous. It tells the robot to process **no new instructions** for the specified duration. But what if other activities need to happen while that motor runs? In Autonomous, for example, you might need to collect sensor data while the robot moves forward for 3 seconds. In TeleOp, you might need to continue driving with gamepads while a CR servo rotates for 2 seconds. The Sleep command will not allow this; "no new instructions". @@ -39,19 +41,19 @@ This is not the usual Blocks "Set" command. Instead of assigning a number to a The default unit of reporting time is Seconds, for a timer created with the simple Block shown above. An option for Milliseconds is discussed far below. -A new timer begins running as soon as it's created, even in the Initialize section, starting with the current time on the **system clock**. However you will probably **not** rely on that starting time value, because you will use the timer later in your Op Mode when the system time has changed. Pressing the DS phone's Start button at the beginning of Autonomous or TeleOp does not restart your timer. +A new timer begins running as soon as it's created, even in the Initialize section, starting with the current time on the **system clock**. However you will probably **not** rely on that starting time value, because you will use the timer later in your OpMode when the system time has changed. Pressing the DS phone's Start button at the beginning of Autonomous or TeleOp does not restart your timer. [
Return to Top](#introduction)
## Initialize a Timer -Consider the point where your Op Mode is ready to use myTimer, probably someplace after 'waitForStart'. As a programmer you don't know in advance how much time has passed, so you should set the time value of myTimer to a definite fresh starting point. That starting point will again be the current time on the **system clock**. +Consider the point where your OpMode is ready to use myTimer, probably someplace after 'waitForStart'. As a programmer you don't know in advance how much time has passed, so you should set the time value of myTimer to a definite fresh starting point. That starting point will again be the current time on the **system clock**.
[[/images/Timers-in-FTC-Blocks/0130-reset-myTimer.png|]]
This Block uses a method called **"reset"**, from the class called ElapsedTime. It resets your timer to the current system time; it will start counting immediately and keep running. **Timers don't stop**; all you can do is read their changing time value at a single instant. -Note: this tutorial will reserve the term clock to mean only the high-level system clock that runs on the RC phone or Control Hub, independent of the FTC apps and Op Mode. It cannot be reset by the Op Mode. +Note: this tutorial will reserve the term clock to mean only the high-level system clock that runs on the RC phone or Control Hub, independent of the FTC apps and OpMode. It cannot be reset by the OpMode. [
Return to Top](#introduction)
@@ -65,7 +67,7 @@ Instead you must use a built-in method or command, to get or retri The green Block uses an **Elapsed Time** method named "Time"; you can consider it as "Get A Timer's Current Elapsed Time Value". **Elapsed time means the time that has passed since the timer was created or last reset, whichever was later.** You might prefer to ignore the system time and think of timers as counting **from zero**. That outlook or model does work, but keep in mind the actual process is to subtract the starting system time from the current system time. This tutorial will often refer to elapsed time as simply "time". -We can read the above Blocks from right to left. The "Time" method gets the time value from myTimer and passes, or returns, the calculated Elapsed Time to the left. On the left could be a variable to hold that number, or it could be another Block that accepts number input. +We can read the above Blocks from right to left. From myTimer, the "Time" method gets the time value and passes, or returns, the calculated Elapsed Time to the left. On the left could be a variable to hold that number, or it could be another Block that accepts number input. The units will be Seconds or Milliseconds, based on how the timer was created. @@ -89,13 +91,15 @@ You may find that a constantly changing time value causes programming or calcula Here the Telemetry Block builds a message showing the variable currentTime, containing a value retrieved from your timer. Although its value may be updating constantly in a Repeat loop, currentTime is not actually the running stopwatch. Again, keep in mind that the variable holds a **fixed, saved value**. -Telemetry can give a **final time report** from variables that recorded the duration of actions or time between actions. When developing new Autonomous Op Modes, this tool can help you optimize performance and identify wasted time. +[
Return to Top](#introduction)
+ +Telemetry can give a **final time report** from variables that recorded the duration of actions or time between actions. When developing new Autonomous OpModes, this tool can help you optimize performance and identify wasted time.
[[/images/Timers-in-FTC-Blocks/0820-options-Telemetry3.png|]]
Telemetry can be used inside a Repeat loop to monitor changing time values, as shown in several Examples below. Telemetry can also be used **after** a loop to give a final time report, from variables that recorded times **inside** the loop. -When testing your Op Mode, make sure the final Telemetry message **stays on the screen** long enough to read it. If this is not possible, or you are studying a sequence of very close events, consider the logging option described far below. +When testing your OpMode, make sure the final Telemetry message **stays on the screen** long enough to read it. If this is not possible, or you are studying a sequence of very close events, consider the logging option described far below. > **Programming tip:** Consider the user. Telemetry can display timer values in units of Seconds or Milliseconds, but always with its native Nanosecond accuracy. The extra 5 to 9 digits make it hard to interpret the data on the DS screen. Use the 'roundDecimal' Block from the Miscellaneous menu and choose a suitable rounding level such as 1 or 2 decimals for Seconds, or zero decimals for Milliseconds. >
[[/images/Timers-in-FTC-Blocks/0830-options-rounding.png|]]
@@ -108,11 +112,11 @@ When testing your Op Mode, make sure the final Telemetry message **stays on the
Here are five common uses of timers in FTC:
-[1. ](#1-loop-for-time)Loop until a time limit is reached. Think of this as an alarm clock.
-[2. ](#2-measure-duration-of-action)Measure the length of time (until an action stops or occurs). Think of this as a stopwatch.
-[3. ](#3-safety-timeout)Safety timeout. Don't get stuck in a loop!
-[4. ](#4-match-timer)Match timer or countdown timer.
-[5. ](#5-device-timer-in-teleop)Device timer in TeleOp.
+[1. ](#1-loop-for-time)Loop until a time limit is reached. Think of this as an alarm clock.
+[2. ](#2-measure-duration-of-action)Measure the length of time (until an action stops or occurs). Think of this as a stopwatch.
+[3. ](#3-safety-timeout)Safety timeout. Don't get stuck in a loop!
+[4. ](#4-match-timer)Match timer or countdown timer.
+[5. ](#5-device-timer-in-teleop)Device timer in TeleOp.
More advanced applications are mentioned at the end of this tutorial.
@@ -124,7 +128,7 @@ This is the most common use. In the shortest version, create and start the time
[[/images/Timers-in-FTC-Blocks/0210-Example-1-loop-short.png|]]
-In the more formal recommended version, create the timer in the Initialize section of your Op Mode (before waitForStart). Then reset the timer before each use. This example also shows the Telemetry command. +In the more formal recommended version, create the timer in the Initialize section of your OpMode (before waitForStart). Then reset the timer before each use. This example also shows the Telemetry command.
[[/images/Timers-in-FTC-Blocks/0230-Example-1-loop-Telemetry.png|]]
@@ -136,19 +140,19 @@ Create the 'stopwatch' timer in the Initialize section, then **reset** that time
[[/images/Timers-in-FTC-Blocks/0310-Example-2-duration.png|]]
-Again, **timers don't stop**; all you can do is read the time value at one moment. Here the stored post-action timer value is displayed immediately as Telemetry. For testing only, a long Sleep command can keep your Telemetry on the DS screen, before the Op Mode ends. +Again, **timers don't stop**; all you can do is read the time value at one moment. Here the stored post-action timer value is displayed immediately as Telemetry. For testing only, a long Sleep command can keep your Telemetry on the DS screen, before the OpMode ends. [
Return to Top](#introduction)
## 3. Safety Timeout -This is similar to 'Loop for Time', except here the timer is not the **primary basis** for looping, it's the **last resort**. Reaching the time limit typically means the loop **did not achieve** its primary goal; it's time to give up and move on. This can help prevent: motor/servo burnout, mechanism breaking, field damage, or simply wasted time. All action loops should have a safety timeout. +This is similar to 'Loop for Time', except here the timer is not the **primary basis** for looping, it's the **last resort**. Reaching the time limit typically means the loop **did not achieve** its primary goal; it's time to give up and move on. This can help prevent: motor/servo burnout, mechanism breaking, field damage, or simply wasted time. Action loops should have a safety timeout. Here is a simple example that might be used in Autonomous or an automated section of TeleOp.
[[/images/Timers-in-FTC-Blocks/0410-Example-3-safety-timeout.png|]]
-What might cause a timeout? Sensors failed, unexpected field condition, low battery, robot meets robot, etc. If the Op Mode remains stuck in a Repeat Loop, the timeout can allow the Op Mode to continue safely. +What might cause a timeout? Sensors failed, unexpected field condition, low battery, robot meets robot, etc. If the OpMode remains stuck in a Repeat Loop, the timeout can allow the OpMode to continue safely. As noted by the blue comments, inside the loop you could set a variable indicating the **cause** of exiting the loop. In this example, the variable is simply a Boolean (true/false) "flag" to indicate whether or not the robot action finished as intended. This Boolean flag can be used immediately after the Loop to stop the action if needed, and carry out the best next action. The next action might be to back up, try again, move on with other scoring attempts, re-establish the robot's location, or simply take no action until the end of Autonomous or Endgame. @@ -158,11 +162,11 @@ Test to make sure the safety time limit is **not shorter** than the intended act ## 4. Match Timer -Your Op Mode can monitor the elapsed time since the start of Autonomous or TeleOp, and give warnings or take action accordingly. It can also can 'lock out' or prevent certain actions until a specific time in TeleOp, to reduce driver error. Example from Rover Ruckus: don't begin the "hang" before Endgame. Or, from SKYSTONE: don't release the spring-powered Loading Zone extender before Endgame. +Your OpMode can monitor the elapsed time since the start of Autonomous or TeleOp, and give warnings or take action accordingly. It can also can 'lock out' or prevent certain actions until a specific time in TeleOp, to reduce driver error. Example from Rover Ruckus: don't begin the "hang" before Endgame. Or, from SKYSTONE: don't release the spring-powered Loading Zone extender before Endgame.
[[/images/Timers-in-FTC-Blocks/0450-Example-4-match.png|]]
-It's recommended to instantiate a timer in the Initialize section, allowing re-use of that timer with simple Resets at each place needed in the Op Mode. This example does **not** do that, to illustrate that it's optional. +It's recommended to instantiate a timer in the Initialize section, allowing re-use of that timer with simple Resets at each place needed in the OpMode. This example does **not** do that, to illustrate that it's optional. You might prefer to instantiate a timer only where needed. It makes sense in this example, since a Match Timer will not be used more than once. You get a Reset for free, saving one line of code. @@ -170,7 +174,7 @@ You might prefer to instantiate a timer only where needed. It makes sense in th >
[[/images/Timers-in-FTC-Blocks/0460-Example-4-tip-true.png|]]
> Likewise, these two Blocks are equivalent. >
[[/images/Timers-in-FTC-Blocks/0470-Example-4-tip-false.png|]]
-> Carefully select the names of your Boolean variables, so your Op Modes are simple and easy to read.
+> Carefully select the names of your Boolean variables, so your OpModes are simple and easy to read.
@@ -182,13 +186,13 @@ You might prefer to instantiate a timer only where needed. It makes sense in th
## 5. Device Timer in TeleOp
-For TeleOp, an Op Mode typically runs all commands in a single overall Repeat Loop. How can you run a device for time, within that loop? Example: when button B pressed, run a CR servo for 2 seconds.
+For TeleOp, an OpMode typically runs all commands in a single overall Repeat Loop. How can you run a device for time, within that loop? Example: when button B pressed, run a CR servo for 2 seconds.
[[/images/Timers-in-FTC-Blocks/0550-Example-5-device.png|]]
The timer here is instantiated with time units or resolution of Milliseconds, rather than the default Seconds. This affects only the programming and display aspects for convenience; the actual timer accuracy is in Nanoseconds. -Timers can be used in this way also for Autonomous Op Modes written in a State Machine style, where an iterative (looping) Op Mode progresses sequentially through program steps, or states. +Timers can be used in this way also for Autonomous OpModes written in a State Machine style, where an iterative (looping) OpMode progresses sequentially through program steps, or states. This example also shows how to capture only the first moment of the button being pressed. The continued pressing of the button is ignored, when the Boolean (true/false) variable CRservoIsRunning is set to True. After 2 seconds of running, this Boolean "flag" is reset to False, which stops checking the timer and allows a fresh press of button B if desired. @@ -208,13 +212,13 @@ Here are the other timer-related Blocks not yet discussed. First, above the Ela
[[/images/Timers-in-FTC-Blocks/0710-System-nanoTime.png|]]
-This returns the system-level time in Nanoseconds, to be used for elapsed-time calculations. The system timer is a high-level clock that runs independently from the Op Mode and the FTC apps, and cannot be reset in the Op Mode. A millisecond is 1/1000 of a second, a microsecond is 1/1000 of a millisecond, and a nanosecond is 1/1000 of a microsecond. +This returns the system-level time in Nanoseconds, to be used for elapsed-time calculations. The system timer is a high-level clock that runs independently from the OpMode and the FTC apps, and cannot be reset in the OpMode. A millisecond is 1/1000 of a second, a microsecond is 1/1000 of a millisecond, and a nanosecond is 1/1000 of a microsecond.
[[/images/Timers-in-FTC-Blocks/0610-Elapsed-start-System-nano.png|]]
From the ElapsedTime menu, the above Block creates a new timer using Seconds, initialized to the input value. When using the indicated default **system** input, this Block is the same as the common "new ElapsedTime" Block used throughout this tutorial. In either case, the timer will later return a correct **elapsed time**. The faint/ghosted default input works the same as the bright purple input from the Time menu above ElapsedTime. -This Block does allow plugging in a different starting time as a raw number in Nanoseconds, but take great care. This will **not** give a usable elapsed-time result later, since each new run of the Op Mode would start at a different time relative to the constantly running system clock. But the StartTime method shown below would reflect the raw number input. For example if the input is zero, the start time always shows as zero, and an elapsed-time getter method (e.g. ElapsedTime.Time) returns the current **system clock** time. +This Block does allow plugging in a different starting time as a raw number in Nanoseconds, but take great care. This will **not** give a usable elapsed-time result later, since each new run of the OpMode would start at a different time relative to the constantly running system clock. But the StartTime method shown below would reflect the raw number input. For example if the input is zero, the start time always shows as zero, and an elapsed-time getter method (e.g. ElapsedTime.Time) returns the current **system clock** time.
[[/images/Timers-in-FTC-Blocks/0620-new-Elapsed-resolution.png|]]
@@ -248,15 +252,15 @@ The above Block writes a message to the system log file, for later analysis. Th
[[/images/Timers-in-FTC-Blocks/0680-Elapsed-to-text.png|]]
-The above Block returns a text string, converted from the timer's numeric value of elapsed time. This allows combining the value with other text; here is an example. +The above Block returns a text string, converted from the timer's numeric value of elapsed time. This allows combining the value with other text; here is an example:
[[/images/Timers-in-FTC-Blocks/0690-example-to-text.png|]]
-Lastly, there is a time-related Block in the LinearOpMode menu (top of list at left side). This method, called 'getRuntime', returns the time in Seconds since the Op Mode was started by pressing the INIT button. +Lastly, there is a time-related Block in the LinearOpMode menu (top of list at left side). This method, called 'getRuntime', returns the time in Seconds since the OpMode was started by pressing the INIT button.
[[/images/Timers-in-FTC-Blocks/0700-get-Runtime.png|]]
-Think of Runtime as a special timer instantiated as the first action in the initialize section of your Op Mode -- except it can only be read, and cannot be reset. Runtime starts from zero and is not affected by pressing the START button. None of the above ElapsedTime methods can operate on Runtime; it's not an instance of that class. However the getRuntime Block **can be used directly** in Math, Logic, Telemetry and DbgLog operations without needing an ElapsedTime method to retrieve its contents. +Think of Runtime as a special timer instantiated as the first action in the initialize section of your OpMode -- except it can only be read, and cannot be reset. Runtime starts from zero and is not affected by pressing the START button. None of the above ElapsedTime methods can operate on Runtime; it's not an instance of that class. However the getRuntime Block **can be used directly** in Math, Logic, Telemetry and DbgLog operations without needing an ElapsedTime method to retrieve its contents.
@@ -264,7 +268,7 @@ Think of Runtime as a special timer instantiated as the first action in the init ## Multiple Timers and Potential Uses -You can create and use **multiple timers**, resetting and reading them at various points in your Op Mode. They can overlap, and have no effect on each other. It's best to give them meaningful names, like LifterLoopTimer or TimeSinceStart or GrabberSafetyTimer. +You can create and use **multiple timers**, resetting and reading them at various points in your OpMode. They can overlap, and have no effect on each other. It's best to give them meaningful names, like LifterLoopTimer or TimeSinceStart or GrabberSafetyTimer. This tutorial described basic use of Timers in Blocks programming. Timers also offer many **advanced capabilities** in FTC robotics, including: @@ -275,6 +279,8 @@ This tutorial described basic use of Timers in Blocks programming. Timers also [
Return to Top](#introduction)
-===========
+***
-Questions, comments and corrections to: westsiderobotics@verizon.net
+
Questions, comments and corrections to: westsiderobotics@verizon.net
+
+