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}