blob: ae4a66ed27f31ffb580f1d536e58de6b4103273d [file] [log] [blame]
Brian Silverman41cdd3e2019-01-19 19:48:58 -08001/*----------------------------------------------------------------------------*/
2/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
3/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in the root directory of */
5/* the project. */
6/*----------------------------------------------------------------------------*/
7
8#include "frc/Timer.h"
9
10#include <chrono>
11#include <thread>
12
13#include <hal/HAL.h>
14
15#include "frc/DriverStation.h"
16#include "frc/RobotController.h"
17
18namespace frc {
19
20void Wait(double seconds) {
21 std::this_thread::sleep_for(std::chrono::duration<double>(seconds));
22}
23
24double GetClock() { return Timer::GetFPGATimestamp(); }
25
26double GetTime() {
27 using std::chrono::duration;
28 using std::chrono::duration_cast;
29 using std::chrono::system_clock;
30
31 return duration_cast<duration<double>>(system_clock::now().time_since_epoch())
32 .count();
33}
34
35} // namespace frc
36
37using namespace frc;
38
39// for compatibility with msvc12--see C2864
40const double Timer::kRolloverTime = (1ll << 32) / 1e6;
41
42Timer::Timer() { Reset(); }
43
44double Timer::Get() const {
45 double result;
46 double currentTime = GetFPGATimestamp();
47
48 std::lock_guard<wpi::mutex> lock(m_mutex);
49 if (m_running) {
50 // If the current time is before the start time, then the FPGA clock rolled
51 // over. Compensate by adding the ~71 minutes that it takes to roll over to
52 // the current time.
53 if (currentTime < m_startTime) {
54 currentTime += kRolloverTime;
55 }
56
57 result = (currentTime - m_startTime) + m_accumulatedTime;
58 } else {
59 result = m_accumulatedTime;
60 }
61
62 return result;
63}
64
65void Timer::Reset() {
66 std::lock_guard<wpi::mutex> lock(m_mutex);
67 m_accumulatedTime = 0;
68 m_startTime = GetFPGATimestamp();
69}
70
71void Timer::Start() {
72 std::lock_guard<wpi::mutex> lock(m_mutex);
73 if (!m_running) {
74 m_startTime = GetFPGATimestamp();
75 m_running = true;
76 }
77}
78
79void Timer::Stop() {
80 double temp = Get();
81
82 std::lock_guard<wpi::mutex> lock(m_mutex);
83 if (m_running) {
84 m_accumulatedTime = temp;
85 m_running = false;
86 }
87}
88
89bool Timer::HasPeriodPassed(double period) {
90 if (Get() > period) {
91 std::lock_guard<wpi::mutex> lock(m_mutex);
92 // Advance the start time by the period.
93 m_startTime += period;
94 // Don't set it to the current time... we want to avoid drift.
95 return true;
96 }
97 return false;
98}
99
100double Timer::GetFPGATimestamp() {
101 // FPGA returns the timestamp in microseconds
102 return RobotController::GetFPGATime() * 1.0e-6;
103}
104
105double Timer::GetMatchTime() {
106 return DriverStation::GetInstance().GetMatchTime();
107}