001package edu.wpi.first.wpilibj; 002 003import edu.wpi.first.wpilibj.util.BaseSystemNotInitializedException; 004 005public class Timer { 006 private static StaticInterface impl; 007 008 public static void SetImplementation(StaticInterface ti) { 009 impl = ti; 010 } 011 012 /** 013 * Return the system clock time in seconds. Return the time from the 014 * FPGA hardware clock in seconds since the FPGA started. 015 * 016 * @return Robot running time in seconds. 017 */ 018 public static double getFPGATimestamp() { 019 if (impl != null) { 020 return impl.getFPGATimestamp(); 021 } else { 022 throw new BaseSystemNotInitializedException(StaticInterface.class, Timer.class); 023 } 024 } 025 026 /** 027 * Return the approximate match time 028 * The FMS does not currently send the official match time to the robots 029 * This returns the time since the enable signal sent from the Driver Station 030 * At the beginning of autonomous, the time is reset to 0.0 seconds 031 * At the beginning of teleop, the time is reset to +15.0 seconds 032 * If the robot is disabled, this returns 0.0 seconds 033 * Warning: This is not an official time (so it cannot be used to argue with referees) 034 * @return Match time in seconds since the beginning of autonomous 035 */ 036 public static double getMatchTime() { 037 if (impl != null) { 038 return impl.getMatchTime(); 039 } else { 040 throw new BaseSystemNotInitializedException(StaticInterface.class, Timer.class); 041 } 042 } 043 044 /** 045 * Pause the thread for a specified time. Pause the execution of the 046 * thread for a specified period of time given in seconds. Motors will 047 * continue to run at their last assigned values, and sensors will continue 048 * to update. Only the task containing the wait will pause until the wait 049 * time is expired. 050 * 051 * @param seconds Length of time to pause 052 */ 053 public static void delay(final double seconds) { 054 if (impl != null) { 055 impl.delay(seconds); 056 } else { 057 throw new BaseSystemNotInitializedException(StaticInterface.class, Timer.class); 058 } 059 } 060 061 public interface StaticInterface { 062 double getFPGATimestamp(); 063 double getMatchTime(); 064 void delay(final double seconds); 065 Interface newTimer(); 066 } 067 068 private final Interface timer; 069 070 public Timer() { 071 if(impl != null){ 072 timer = impl.newTimer(); 073 } else { 074 throw new BaseSystemNotInitializedException(StaticInterface.class, Timer.class); 075 } 076 } 077 078 /** 079 * Get the current time from the timer. If the clock is running it is derived from 080 * the current system clock the start time stored in the timer class. If the clock 081 * is not running, then return the time when it was last stopped. 082 * 083 * @return Current time value for this timer in seconds 084 */ 085 public double get() { 086 return timer.get(); 087 } 088 089 /** 090 * Reset the timer by setting the time to 0. 091 * Make the timer startTime the current time so new requests will be relative now 092 */ 093 public void reset() { 094 timer.reset(); 095 } 096 097 /** 098 * Start the timer running. 099 * Just set the running flag to true indicating that all time requests should be 100 * relative to the system clock. 101 */ 102 public void start() { 103 timer.start(); 104 } 105 106 /** 107 * Stop the timer. 108 * This computes the time as of now and clears the running flag, causing all 109 * subsequent time requests to be read from the accumulated time rather than 110 * looking at the system clock. 111 */ 112 public void stop() { 113 timer.stop(); 114 } 115 116 /** 117 * Check if the period specified has passed and if it has, advance the start 118 * time by that period. This is useful to decide if it's time to do periodic 119 * work without drifting later by the time it took to get around to checking. 120 * 121 * @param period The period to check for (in seconds). 122 * @return If the period has passed. 123 */ 124 public boolean hasPeriodPassed(double period) 125 { 126 return timer.hasPeriodPassed(period); 127 } 128 129 public interface Interface { 130 /** 131 * Get the current time from the timer. If the clock is running it is derived from 132 * the current system clock the start time stored in the timer class. If the clock 133 * is not running, then return the time when it was last stopped. 134 * 135 * @return Current time value for this timer in seconds 136 */ 137 public double get(); 138 139 /** 140 * Reset the timer by setting the time to 0. 141 * Make the timer startTime the current time so new requests will be relative now 142 */ 143 public void reset(); 144 145 /** 146 * Start the timer running. 147 * Just set the running flag to true indicating that all time requests should be 148 * relative to the system clock. 149 */ 150 public void start(); 151 152 /** 153 * Stop the timer. 154 * This computes the time as of now and clears the running flag, causing all 155 * subsequent time requests to be read from the accumulated time rather than 156 * looking at the system clock. 157 */ 158 public void stop(); 159 160 161 /** 162 * Check if the period specified has passed and if it has, advance the start 163 * time by that period. This is useful to decide if it's time to do periodic 164 * work without drifting later by the time it took to get around to checking. 165 * 166 * @param period The period to check for (in seconds). 167 * @return If the period has passed. 168 */ 169 public boolean hasPeriodPassed(double period); 170 } 171}