001    /*----------------------------------------------------------------------------*/
002    /* Copyright (c) FIRST 2008-2012. All Rights Reserved.                        */
003    /* Open Source Software - may be modified and shared by FRC teams. The code   */
004    /* must be accompanied by the FIRST BSD license file in the root directory of */
005    /* the project.                                                               */
006    /*----------------------------------------------------------------------------*/
007    
008    package edu.wpi.first.wpilibj;
009    
010    import edu.wpi.first.wpilibj.parsing.IUtility;
011    
012    /**
013     * Timer objects measure accumulated time in milliseconds.
014     * The timer object functions like a stopwatch. It can be started, stopped, and cleared. When the
015     * timer is running its value counts up in milliseconds. When stopped, the timer holds the current
016     * value. The implementation simply records the time when started and subtracts the current time
017     * whenever the value is requested.
018     */
019    public class Timer implements IUtility{
020    
021        private long m_startTime;
022        private double m_accumulatedTime;
023        private boolean m_running;
024    
025        /**
026         * Pause the thread for a specified time. Pause the execution of the
027         * thread for a specified period of time given in seconds. Motors will
028         * continue to run at their last assigned values, and sensors will continue
029         * to update. Only the task containing the wait will pause until the wait
030         * time is expired.
031         *
032         * @param seconds Length of time to pause
033         */
034        public static void delay(final double seconds) {
035            try {
036                Thread.sleep((long) (seconds * 1e3));
037            } catch (final InterruptedException e) {
038            }
039        }
040    
041        /**
042         * Return the system clock time in microseconds. Return the time from the
043         * FPGA hardware clock in microseconds since the FPGA started.
044         *
045         * @deprecated Use getFPGATimestamp instead.
046         * @return Robot running time in microseconds.
047         */
048        public static long getUsClock() {
049            return Utility.getFPGATime();
050        }
051    
052        /**
053         * Return the system clock time in milliseconds. Return the time from the
054         * FPGA hardware clock in milliseconds since the FPGA started.
055         *
056         * @deprecated Use getFPGATimestamp instead.
057         * @return Robot running time in milliseconds.
058         */
059        static long getMsClock() {
060            return getUsClock() / 1000;
061        }
062    
063        /**
064         * Return the system clock time in seconds. Return the time from the
065         * FPGA hardware clock in seconds since the FPGA started.
066         *
067         * @return Robot running time in seconds.
068         */
069        public static double getFPGATimestamp() {
070            return Utility.getFPGATime() / 1000000.0;
071        }
072    
073        /**
074         * Create a new timer object.
075         * Create a new timer object and reset the time to zero. The timer is initially not running and
076         * must be started.
077         */
078        public Timer() {
079            reset();
080        }
081    
082        /**
083         * Get the current time from the timer. If the clock is running it is derived from
084         * the current system clock the start time stored in the timer class. If the clock
085         * is not running, then return the time when it was last stopped.
086         *
087         * @return Current time value for this timer in seconds
088         */
089        public synchronized double get() {
090            if (m_running) {
091                return ((double) ((getMsClock() - m_startTime) + m_accumulatedTime)) / 1000.0;
092            } else {
093                return m_accumulatedTime;
094            }
095        }
096    
097        /**
098         * Reset the timer by setting the time to 0.
099         * Make the timer startTime the current time so new requests will be relative now
100         */
101        public synchronized void reset() {
102            m_accumulatedTime = 0;
103            m_startTime = getMsClock();
104        }
105    
106        /**
107         * Start the timer running.
108         * Just set the running flag to true indicating that all time requests should be
109         * relative to the system clock.
110         */
111        public synchronized void start() {
112            m_startTime = getMsClock();
113            m_running = true;
114        }
115    
116        /**
117         * Stop the timer.
118         * This computes the time as of now and clears the running flag, causing all
119         * subsequent time requests to be read from the accumulated time rather than
120         * looking at the system clock.
121         */
122        public synchronized void stop() {
123            final double temp = get();
124            m_accumulatedTime = temp;
125            m_running = false;
126        }
127    }