mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-26 01:51:41 +00:00
WPILib Reorganization
This is a major restructuring of the WPILib repository to simply build procedures and remove the remnants of Maven from everything except the eclipse plugins. Gradle files have been largely simplified or rewritten, taking advantage of splitting up parts of the build into separate build files for ease of reading. The eclipse plugins are now in a separate project, as is ntcore. All dependencies are resolved via Maven dependencies, with the Jenkins-maintained WPILib repo. Project structures have also been simplified: we no longer have separate subprojects inside wpilibc and wpilibj. Where possible, these changes hav been done with git renames, to make sure we still have full history for all repositories. Other unrelated subprojects have also been broken out: OutlineViewer is now a separate project. Change-Id: Ib4e2a6e1a2f66427a14f16612b0e0d69ed661878
This commit is contained in:
177
wpilibc/Athena/src/Timer.cpp
Normal file
177
wpilibc/Athena/src/Timer.cpp
Normal file
@@ -0,0 +1,177 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2008. All Rights Reserved.
|
||||
*/
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "Timer.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "HAL/HAL.hpp"
|
||||
#include "Utility.h"
|
||||
#include <iostream>
|
||||
|
||||
/**
|
||||
* Pause the task for a specified time.
|
||||
*
|
||||
* Pause the execution of the program for a specified period of time given in
|
||||
* seconds.
|
||||
* Motors will continue to run at their last assigned values, and sensors will
|
||||
* continue to
|
||||
* update. Only the task containing the wait will pause until the wait time is
|
||||
* expired.
|
||||
*
|
||||
* @param seconds Length of time to pause, in seconds.
|
||||
*/
|
||||
void Wait(double seconds) {
|
||||
if (seconds < 0.0) return;
|
||||
delaySeconds(seconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the FPGA system clock time in seconds.
|
||||
* This is deprecated and just forwards to Timer::GetFPGATimestamp().
|
||||
* @return Robot running time in seconds.
|
||||
*/
|
||||
double GetClock() { return Timer::GetFPGATimestamp(); }
|
||||
|
||||
/**
|
||||
* @brief Gives real-time clock system time with nanosecond resolution
|
||||
* @return The time, just in case you want the robot to start autonomous at 8pm
|
||||
* on Saturday.
|
||||
*/
|
||||
double GetTime() {
|
||||
struct timespec tp;
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &tp);
|
||||
double realTime = (double)tp.tv_sec + (double)((double)tp.tv_nsec * 1e-9);
|
||||
|
||||
return (realTime);
|
||||
}
|
||||
|
||||
//for compatibility with msvc12--see C2864
|
||||
const double Timer::kRolloverTime = (1ll << 32) / 1e6;
|
||||
/**
|
||||
* Create a new timer object.
|
||||
*
|
||||
* Create a new timer object and reset the time to zero. The timer is initially
|
||||
* not running and
|
||||
* must be started.
|
||||
*/
|
||||
Timer::Timer() {
|
||||
// Creates a semaphore to control access to critical regions.
|
||||
// Initially 'open'
|
||||
Reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current time from the timer. If the clock is running it is derived
|
||||
* from
|
||||
* the current system clock the start time stored in the timer class. If the
|
||||
* clock
|
||||
* is not running, then return the time when it was last stopped.
|
||||
*
|
||||
* @return Current time value for this timer in seconds
|
||||
*/
|
||||
double Timer::Get() const {
|
||||
double result;
|
||||
double currentTime = GetFPGATimestamp();
|
||||
|
||||
std::lock_guard<priority_mutex> sync(m_mutex);
|
||||
if (m_running) {
|
||||
// If the current time is before the start time, then the FPGA clock
|
||||
// rolled over. Compensate by adding the ~71 minutes that it takes
|
||||
// to roll over to the current time.
|
||||
if (currentTime < m_startTime) {
|
||||
currentTime += kRolloverTime;
|
||||
}
|
||||
|
||||
result = (currentTime - m_startTime) + m_accumulatedTime;
|
||||
} else {
|
||||
result = m_accumulatedTime;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the timer by setting the time to 0.
|
||||
*
|
||||
* Make the timer startTime the current time so new requests will be relative to
|
||||
* now
|
||||
*/
|
||||
void Timer::Reset() {
|
||||
std::lock_guard<priority_mutex> sync(m_mutex);
|
||||
m_accumulatedTime = 0;
|
||||
m_startTime = GetFPGATimestamp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the timer running.
|
||||
* Just set the running flag to true indicating that all time requests should be
|
||||
* relative to the system clock.
|
||||
*/
|
||||
void Timer::Start() {
|
||||
std::lock_guard<priority_mutex> sync(m_mutex);
|
||||
if (!m_running) {
|
||||
m_startTime = GetFPGATimestamp();
|
||||
m_running = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the timer.
|
||||
* This computes the time as of now and clears the running flag, causing all
|
||||
* subsequent time requests to be read from the accumulated time rather than
|
||||
* looking at the system clock.
|
||||
*/
|
||||
void Timer::Stop() {
|
||||
double temp = Get();
|
||||
|
||||
std::lock_guard<priority_mutex> sync(m_mutex);
|
||||
if (m_running) {
|
||||
m_accumulatedTime = temp;
|
||||
m_running = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the period specified has passed and if it has, advance the start
|
||||
* time by that period. This is useful to decide if it's time to do periodic
|
||||
* work without drifting later by the time it took to get around to checking.
|
||||
*
|
||||
* @param period The period to check for (in seconds).
|
||||
* @return True if the period has passed.
|
||||
*/
|
||||
bool Timer::HasPeriodPassed(double period) {
|
||||
if (Get() > period) {
|
||||
std::lock_guard<priority_mutex> sync(m_mutex);
|
||||
// Advance the start time by the period.
|
||||
m_startTime += period;
|
||||
// Don't set it to the current time... we want to avoid drift.
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the FPGA system clock time in seconds.
|
||||
*
|
||||
* Return the time from the FPGA hardware clock in seconds since the FPGA
|
||||
* started.
|
||||
* Rolls over after 71 minutes.
|
||||
* @returns Robot running time in seconds.
|
||||
*/
|
||||
double Timer::GetFPGATimestamp() {
|
||||
// FPGA returns the timestamp in microseconds
|
||||
// Call the helper GetFPGATime() in Utility.cpp
|
||||
return GetFPGATime() * 1.0e-6;
|
||||
}
|
||||
|
||||
// Internal function that reads the PPC timestamp counter.
|
||||
extern "C" {
|
||||
uint32_t niTimestamp32(void);
|
||||
uint64_t niTimestamp64(void);
|
||||
}
|
||||
Reference in New Issue
Block a user