From e944ae9aca562e931b519cd2b762c2900ac21fba Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Sun, 15 Mar 2026 15:08:41 -0700 Subject: [PATCH] [hal,wpilib] Rename FPGA clock to monotonic clock (#8672) - Remove status return from HAL level (clock getting should never fail) - Remove 32-bit timestamp expand function - Make monotonic_clock.hpp (formerly fpga_clock.hpp) header-only and move to root hal include directory --- .../java/org/wpilib/hardware/hal/HALUtil.java | 6 +-- hal/src/main/native/cpp/cpp/fpga_clock.cpp | 32 ---------------- hal/src/main/native/cpp/jni/HALUtil.cpp | 9 ++--- hal/src/main/native/include/wpi/hal/HAL.h | 24 ++---------- .../native/include/wpi/hal/cpp/fpga_clock.hpp | 31 --------------- .../include/wpi/hal/monotonic_clock.hpp | 38 +++++++++++++++++++ hal/src/main/native/sim/Alert.cpp | 2 +- hal/src/main/native/sim/DriverStation.cpp | 8 ++-- hal/src/main/native/sim/HAL.cpp | 28 +------------- hal/src/main/native/sim/MockHooks.cpp | 11 ++---- hal/src/main/native/sim/MockHooksInternal.hpp | 4 +- hal/src/main/native/sim/Notifier.cpp | 8 ++-- .../main/native/systemcore/AddressableLED.cpp | 6 +-- hal/src/main/native/systemcore/Alert.cpp | 2 +- .../main/native/systemcore/AnalogInput.cpp | 6 +-- hal/src/main/native/systemcore/Counter.cpp | 6 +-- hal/src/main/native/systemcore/DIO.cpp | 6 +-- hal/src/main/native/systemcore/DutyCycle.cpp | 6 +-- hal/src/main/native/systemcore/HAL.cpp | 33 +--------------- hal/src/main/native/systemcore/Notifier.cpp | 8 ++-- hal/src/main/native/systemcore/PWM.cpp | 6 +-- .../native/systemcore/PowerDistribution.cpp | 5 +-- hal/src/main/python/semiwrap/HAL.yml | 3 +- .../RomiReference/commands/drivetime.py | 4 +- .../RomiReference/commands/turntime.py | 4 +- .../XrpReference/commands/drivetime.py | 4 +- .../XrpReference/commands/turntime.py | 4 +- .../src/main/native/cpp/DriverStationGui.cpp | 3 +- .../src/main/native/cpp/TimingGui.cpp | 5 +-- .../main/native/cpp/framework/TimedRobot.cpp | 4 +- .../native/cpp/hardware/motor/MotorSafety.cpp | 6 +-- .../main/native/cpp/opmode/PeriodicOpMode.cpp | 6 +-- .../native/cpp/system/RobotController.cpp | 9 ++--- wpilibc/src/main/native/cpp/system/Timer.cpp | 9 +++-- wpilibc/src/main/native/cpp/system/Tracer.cpp | 6 +-- .../src/main/native/cpp/system/Watchdog.cpp | 9 ++--- .../include/wpi/framework/TimedRobot.hpp | 17 +++++---- .../wpi/hardware/motor/MotorSafety.hpp | 2 +- .../include/wpi/opmode/PeriodicOpMode.hpp | 7 ++-- .../include/wpi/system/RobotController.hpp | 15 ++++---- .../main/native/include/wpi/system/Timer.hpp | 18 ++++----- .../main/native/include/wpi/system/Tracer.hpp | 8 ++-- .../main/python/semiwrap/RobotController.yml | 2 +- wpilibc/src/main/python/semiwrap/Timer.yml | 4 +- wpilibc/src/main/python/wpilib/__init__.py | 4 +- wpilibc/src/test/native/cpp/TimerTest.cpp | 6 +-- .../java/org/wpilib/framework/TimedRobot.java | 8 ++-- .../wpilib/hardware/motor/MotorSafety.java | 8 ++-- .../org/wpilib/opmode/PeriodicOpMode.java | 12 +++--- .../org/wpilib/system/RobotController.java | 30 +++++++-------- .../main/java/org/wpilib/system/Timer.java | 15 ++++---- .../main/java/org/wpilib/system/Tracer.java | 6 +-- .../main/java/org/wpilib/system/Watchdog.java | 8 ++-- .../wpilib/hardware/led/LEDPatternTest.java | 2 +- .../java/org/wpilib/system/TimerTest.java | 6 +-- .../wpilib/math/estimator/PoseEstimator.java | 12 +++--- .../math/estimator/PoseEstimator3d.java | 12 +++--- .../wpi/math/estimator/PoseEstimator.hpp | 14 +++---- .../wpi/math/estimator/PoseEstimator3d.hpp | 14 +++---- 59 files changed, 233 insertions(+), 358 deletions(-) delete mode 100644 hal/src/main/native/cpp/cpp/fpga_clock.cpp delete mode 100644 hal/src/main/native/include/wpi/hal/cpp/fpga_clock.hpp create mode 100644 hal/src/main/native/include/wpi/hal/monotonic_clock.hpp diff --git a/hal/src/main/java/org/wpilib/hardware/hal/HALUtil.java b/hal/src/main/java/org/wpilib/hardware/hal/HALUtil.java index 6ace64dbc7..304e0b5925 100644 --- a/hal/src/main/java/org/wpilib/hardware/hal/HALUtil.java +++ b/hal/src/main/java/org/wpilib/hardware/hal/HALUtil.java @@ -71,11 +71,11 @@ public final class HALUtil extends JNIWrapper { public static native int getTeamNumber(); /** - * Reads the microsecond-resolution timer on the FPGA. + * Reads the microsecond-resolution monotonic timer. * - * @return The current time in microseconds according to the FPGA (since FPGA reset). + * @return The current monotonic time in microseconds. */ - public static native long getFPGATime(); + public static native long getMonotonicTime(); /** * Returns the runtime type of the HAL. diff --git a/hal/src/main/native/cpp/cpp/fpga_clock.cpp b/hal/src/main/native/cpp/cpp/fpga_clock.cpp deleted file mode 100644 index 2733aec8e8..0000000000 --- a/hal/src/main/native/cpp/cpp/fpga_clock.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) FIRST and other WPILib contributors. -// Open Source Software; you can modify and/or share it under the terms of -// the WPILib BSD license file in the root directory of this project. - -#include "wpi/hal/cpp/fpga_clock.hpp" - -#include -#include - -#include "wpi/hal/HAL.h" -#include "wpi/util/print.hpp" - -namespace wpi::hal { -const fpga_clock::time_point fpga_clock::min_time = - fpga_clock::time_point(fpga_clock::duration( - std::numeric_limits::min())); - -fpga_clock::time_point fpga_clock::now() noexcept { - int32_t status = 0; - uint64_t currentTime = HAL_GetFPGATime(&status); - if (status != 0) { - wpi::util::print( - stderr, - "Call to HAL_GetFPGATime failed in fpga_clock::now() with status {}. " - "Initialization might have failed. Time will not be correct\n", - status); - std::fflush(stderr); - return epoch(); - } - return time_point(std::chrono::microseconds(currentTime)); -} -} // namespace wpi::hal diff --git a/hal/src/main/native/cpp/jni/HALUtil.cpp b/hal/src/main/native/cpp/jni/HALUtil.cpp index d9d551194d..6f739fd90f 100644 --- a/hal/src/main/native/cpp/jni/HALUtil.cpp +++ b/hal/src/main/native/cpp/jni/HALUtil.cpp @@ -473,17 +473,14 @@ Java_org_wpilib_hardware_hal_HALUtil_getTeamNumber /* * Class: org_wpilib_hardware_hal_HALUtil - * Method: getFPGATime + * Method: getMonotonicTime * Signature: ()J */ JNIEXPORT jlong JNICALL -Java_org_wpilib_hardware_hal_HALUtil_getFPGATime +Java_org_wpilib_hardware_hal_HALUtil_getMonotonicTime (JNIEnv* env, jclass) { - int32_t status = 0; - jlong returnValue = HAL_GetFPGATime(&status); - CheckStatus(env, status); - return returnValue; + return HAL_GetMonotonicTime(); } /* diff --git a/hal/src/main/native/include/wpi/hal/HAL.h b/hal/src/main/native/include/wpi/hal/HAL.h index 589836bda2..72edf2dff4 100644 --- a/hal/src/main/native/include/wpi/hal/HAL.h +++ b/hal/src/main/native/include/wpi/hal/HAL.h @@ -111,29 +111,11 @@ HAL_Bool HAL_GetBrownedOut(int32_t* status); int32_t HAL_GetCommsDisableCount(int32_t* status); /** - * Reads the microsecond-resolution timer on the FPGA. + * Reads the microsecond-resolution monotonic timer. * - * @param[out] status the error code, or 0 for success - * @return The current time in microseconds according to the FPGA (since FPGA - * reset). + * @return The current monotonic time in microseconds. */ -uint64_t HAL_GetFPGATime(int32_t* status); - -/** - * Given an 32 bit FPGA time, expand it to the nearest likely 64 bit FPGA time. - * - * Note: This is making the assumption that the timestamp being converted is - * always in the past. If you call this with a future timestamp, it probably - * will make it in the past. If you wait over 70 minutes between capturing the - * bottom 32 bits of the timestamp and expanding it, you will be off by - * multiples of 1<<32 microseconds. - * - * @param[in] unexpandedLower 32 bit FPGA time - * @param[out] status the error code, or 0 for success - * @return The current time in microseconds according to the FPGA (since FPGA - * reset) as a 64 bit number. - */ -uint64_t HAL_ExpandFPGATime(uint32_t unexpandedLower, int32_t* status); +uint64_t HAL_GetMonotonicTime(void); /** * Gets the current state of the Robot Signal Light (RSL). diff --git a/hal/src/main/native/include/wpi/hal/cpp/fpga_clock.hpp b/hal/src/main/native/include/wpi/hal/cpp/fpga_clock.hpp deleted file mode 100644 index 42b2ba3bea..0000000000 --- a/hal/src/main/native/include/wpi/hal/cpp/fpga_clock.hpp +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) FIRST and other WPILib contributors. -// Open Source Software; you can modify and/or share it under the terms of -// the WPILib BSD license file in the root directory of this project. - -#pragma once - -#include - -/** WPILib Hardware Abstraction Layer (HAL) namespace */ -namespace wpi::hal { - -/** - * A std::chrono compatible wrapper around the FPGA Timer. - */ -class fpga_clock { - public: - using rep = std::chrono::microseconds::rep; - using period = std::chrono::microseconds::period; - using duration = std::chrono::microseconds; - using time_point = std::chrono::time_point; - - static fpga_clock::time_point now() noexcept; - static constexpr bool is_steady = true; - - static fpga_clock::time_point epoch() noexcept { return time_point(zero()); } - - static fpga_clock::duration zero() noexcept { return duration(0); } - - static const time_point min_time; -}; -} // namespace wpi::hal diff --git a/hal/src/main/native/include/wpi/hal/monotonic_clock.hpp b/hal/src/main/native/include/wpi/hal/monotonic_clock.hpp new file mode 100644 index 0000000000..48e10a3848 --- /dev/null +++ b/hal/src/main/native/include/wpi/hal/monotonic_clock.hpp @@ -0,0 +1,38 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +#pragma once + +#include +#include + +#include "wpi/hal/HAL.h" + +/** WPILib Hardware Abstraction Layer (HAL) namespace */ +namespace wpi::hal { + +/** + * A std::chrono compatible wrapper around the HAL monotonic timer. + */ +class monotonic_clock { + public: + using rep = std::chrono::microseconds::rep; + using period = std::chrono::microseconds::period; + using duration = std::chrono::microseconds; + using time_point = std::chrono::time_point; + + static time_point now() noexcept { + uint64_t currentTime = HAL_GetMonotonicTime(); + return time_point(std::chrono::microseconds(currentTime)); + } + static constexpr bool is_steady = true; + + static time_point epoch() noexcept { return time_point(zero()); } + + static duration zero() noexcept { return duration(0); } + + static constexpr time_point min_time = + time_point(duration(std::numeric_limits::min())); +}; +} // namespace wpi::hal diff --git a/hal/src/main/native/sim/Alert.cpp b/hal/src/main/native/sim/Alert.cpp index 79c0ec7a95..8b96d03e21 100644 --- a/hal/src/main/native/sim/Alert.cpp +++ b/hal/src/main/native/sim/Alert.cpp @@ -75,7 +75,7 @@ void HAL_SetAlertActive(HAL_AlertHandle alertHandle, HAL_Bool active, // Already active, do nothing (avoids cost of getting time) return; } - int64_t now = HAL_GetFPGATime(status); + int64_t now = HAL_GetMonotonicTime(); int64_t expected = 0; // use compare-exchange to avoid potential race alert->activeStartTime.compare_exchange_strong(expected, now); diff --git a/hal/src/main/native/sim/DriverStation.cpp b/hal/src/main/native/sim/DriverStation.cpp index ad324e70be..84e32f171c 100644 --- a/hal/src/main/native/sim/DriverStation.cpp +++ b/hal/src/main/native/sim/DriverStation.cpp @@ -20,7 +20,7 @@ #include "mockdata/DriverStationDataInternal.hpp" #include "wpi/hal/DriverStationTypes.h" #include "wpi/hal/Errors.h" -#include "wpi/hal/cpp/fpga_clock.hpp" +#include "wpi/hal/monotonic_clock.hpp" #include "wpi/hal/simulation/MockHooks.h" #include "wpi/util/EventVector.hpp" #include "wpi/util/mutex.hpp" @@ -155,16 +155,16 @@ int32_t HAL_SendError(HAL_Bool isError, int32_t errorCode, HAL_Bool isLVCode, static constexpr int KEEP_MSGS = 5; std::scoped_lock lock(msgMutex); static std::string prevMsg[KEEP_MSGS]; - static fpga_clock::time_point prevMsgTime[KEEP_MSGS]; + static monotonic_clock::time_point prevMsgTime[KEEP_MSGS]; static bool initialized = false; if (!initialized) { for (int i = 0; i < KEEP_MSGS; i++) { - prevMsgTime[i] = fpga_clock::now() - std::chrono::seconds(2); + prevMsgTime[i] = monotonic_clock::now() - std::chrono::seconds(2); } initialized = true; } - auto curTime = fpga_clock::now(); + auto curTime = monotonic_clock::now(); int i; for (i = 0; i < KEEP_MSGS; ++i) { if (prevMsg[i] == details) { diff --git a/hal/src/main/native/sim/HAL.cpp b/hal/src/main/native/sim/HAL.cpp index 5d318e760f..f0e77b56e5 100644 --- a/hal/src/main/native/sim/HAL.cpp +++ b/hal/src/main/native/sim/HAL.cpp @@ -254,32 +254,8 @@ int32_t HAL_GetTeamNumber(void) { return HALSIM_GetRoboRioTeamNumber(); } -uint64_t HAL_GetFPGATime(int32_t* status) { - return wpi::hal::GetFPGATime(); -} - -uint64_t HAL_ExpandFPGATime(uint32_t unexpandedLower, int32_t* status) { - // Capture the current FPGA time. This will give us the upper half of the - // clock. - uint64_t fpgaTime = HAL_GetFPGATime(status); - if (*status != 0) { - return 0; - } - - // Now, we need to detect the case where the lower bits rolled over after we - // sampled. In that case, the upper bits will be 1 bigger than they should - // be. - - // Break it into lower and upper portions. - uint32_t lower = fpgaTime & 0xffffffffull; - uint64_t upper = (fpgaTime >> 32) & 0xffffffff; - - // The time was sampled *before* the current time, so roll it back. - if (lower < unexpandedLower) { - --upper; - } - - return (upper << 32) + static_cast(unexpandedLower); +uint64_t HAL_GetMonotonicTime(void) { + return wpi::hal::GetMonotonicTime(); } HAL_Bool HAL_GetSystemActive(int32_t* status) { diff --git a/hal/src/main/native/sim/MockHooks.cpp b/hal/src/main/native/sim/MockHooks.cpp index f9908e73f6..809745dd87 100644 --- a/hal/src/main/native/sim/MockHooks.cpp +++ b/hal/src/main/native/sim/MockHooks.cpp @@ -25,7 +25,7 @@ static std::atomic programStepTime{0}; namespace wpi::hal::init { void InitializeMockHooks() { - wpi::util::SetNowImpl(GetFPGATime); + wpi::util::SetNowImpl(GetMonotonicTime); } } // namespace wpi::hal::init @@ -59,7 +59,7 @@ void StepTiming(uint64_t delta) { programStepTime += delta; } -uint64_t GetFPGATime() { +uint64_t GetMonotonicTime() { uint64_t curTime = programPauseTime; if (curTime == 0) { curTime = wpi::util::NowDefault(); @@ -67,10 +67,6 @@ uint64_t GetFPGATime() { return curTime + programStepTime - programStartTime; } -double GetFPGATimestamp() { - return GetFPGATime() * 1.0e-6; -} - void SetProgramStarted(bool started) { programStarted = started; } @@ -131,8 +127,7 @@ void HALSIM_StepTiming(uint64_t delta) { WaitNotifiers(); while (delta > 0) { - int32_t status = 0; - uint64_t curTime = HAL_GetFPGATime(&status); + uint64_t curTime = HAL_GetMonotonicTime(); uint64_t nextTimeout = HALSIM_GetNextNotifierTimeout(); uint64_t step = (std::min)(delta, nextTimeout - curTime); diff --git a/hal/src/main/native/sim/MockHooksInternal.hpp b/hal/src/main/native/sim/MockHooksInternal.hpp index 0ebf0f29c5..803011c0f8 100644 --- a/hal/src/main/native/sim/MockHooksInternal.hpp +++ b/hal/src/main/native/sim/MockHooksInternal.hpp @@ -17,9 +17,7 @@ bool IsTimingPaused(); void StepTiming(uint64_t delta); -uint64_t GetFPGATime(); - -double GetFPGATimestamp(); +uint64_t GetMonotonicTime(); void SetProgramStarted(); } // namespace wpi::hal diff --git a/hal/src/main/native/sim/Notifier.cpp b/hal/src/main/native/sim/Notifier.cpp index a6667aa85d..39ca6a1e88 100644 --- a/hal/src/main/native/sim/Notifier.cpp +++ b/hal/src/main/native/sim/Notifier.cpp @@ -93,8 +93,7 @@ void NotifierThread::Main() { // Wait until next alarm const Alarm& alarm = m_alarmQueue.top(); - int32_t status = 0; - uint64_t curTime = HAL_GetFPGATime(&status); + uint64_t curTime = HAL_GetMonotonicTime(); if (alarm.notifier->alarmTime > curTime) { m_cond.wait_for( lock, std::chrono::microseconds{alarm.notifier->alarmTime - curTime}); @@ -114,8 +113,7 @@ void NotifierThread::Main() { void NotifierThread::ProcessAlarms( wpi::util::SmallVectorImpl* signaled) { - int32_t status = 0; - uint64_t curTime = HAL_GetFPGATime(&status); + uint64_t curTime = HAL_GetMonotonicTime(); // Process alarms while (!m_alarmQueue.empty() && @@ -264,7 +262,7 @@ void HAL_SetNotifierAlarm(HAL_NotifierHandle notifierHandle, uint64_t alarmTime, } if (!absolute) { - alarmTime += HAL_GetFPGATime(status); + alarmTime += HAL_GetMonotonicTime(); } uint64_t prevWakeup = UINT64_MAX; diff --git a/hal/src/main/native/systemcore/AddressableLED.cpp b/hal/src/main/native/systemcore/AddressableLED.cpp index 036a3b7f57..e2c4449fec 100644 --- a/hal/src/main/native/systemcore/AddressableLED.cpp +++ b/hal/src/main/native/systemcore/AddressableLED.cpp @@ -20,8 +20,8 @@ #include "SystemServerInternal.hpp" #include "wpi/hal/AddressableLEDTypes.h" #include "wpi/hal/Errors.h" -#include "wpi/hal/cpp/fpga_clock.hpp" #include "wpi/hal/handles/HandlesInternal.hpp" +#include "wpi/hal/monotonic_clock.hpp" #include "wpi/nt/NetworkTableInstance.hpp" #include "wpi/nt/RawTopic.hpp" @@ -133,9 +133,9 @@ void HAL_FreeAddressableLED(HAL_AddressableLEDHandle handle) { smartIoHandles->Free(handle, HAL_HandleEnum::AddressableLED); // Wait for no other object to hold this handle. - auto start = wpi::hal::fpga_clock::now(); + auto start = wpi::hal::monotonic_clock::now(); while (port.use_count() != 1) { - auto current = wpi::hal::fpga_clock::now(); + auto current = wpi::hal::monotonic_clock::now(); if (start + std::chrono::seconds(1) < current) { std::puts("AddressableLED handle free timeout"); std::fflush(stdout); diff --git a/hal/src/main/native/systemcore/Alert.cpp b/hal/src/main/native/systemcore/Alert.cpp index 5fbb42762e..c6fa25c411 100644 --- a/hal/src/main/native/systemcore/Alert.cpp +++ b/hal/src/main/native/systemcore/Alert.cpp @@ -75,7 +75,7 @@ void HAL_SetAlertActive(HAL_AlertHandle alertHandle, HAL_Bool active, // Already active, do nothing (avoids cost of getting time) return; } - int64_t now = HAL_GetFPGATime(status); + int64_t now = HAL_GetMonotonicTime(); int64_t expected = 0; // use compare-exchange to avoid potential race alert->activeStartTime.compare_exchange_strong(expected, now); diff --git a/hal/src/main/native/systemcore/AnalogInput.cpp b/hal/src/main/native/systemcore/AnalogInput.cpp index de7efb98b6..a571f1b3c6 100644 --- a/hal/src/main/native/systemcore/AnalogInput.cpp +++ b/hal/src/main/native/systemcore/AnalogInput.cpp @@ -12,8 +12,8 @@ #include "PortsInternal.hpp" #include "SmartIo.hpp" #include "wpi/hal/Errors.h" -#include "wpi/hal/cpp/fpga_clock.hpp" #include "wpi/hal/handles/HandlesInternal.hpp" +#include "wpi/hal/monotonic_clock.hpp" namespace wpi::hal::init { void InitializeAnalogInput() {} @@ -73,9 +73,9 @@ void HAL_FreeAnalogInputPort(HAL_AnalogInputHandle analogPortHandle) { smartIoHandles->Free(analogPortHandle, HAL_HandleEnum::AnalogInput); // Wait for no other object to hold this handle. - auto start = wpi::hal::fpga_clock::now(); + auto start = wpi::hal::monotonic_clock::now(); while (port.use_count() != 1) { - auto current = wpi::hal::fpga_clock::now(); + auto current = wpi::hal::monotonic_clock::now(); if (start + std::chrono::seconds(1) < current) { std::puts("DIO handle free timeout"); std::fflush(stdout); diff --git a/hal/src/main/native/systemcore/Counter.cpp b/hal/src/main/native/systemcore/Counter.cpp index ea8e2f5e93..e5efb73b0a 100644 --- a/hal/src/main/native/systemcore/Counter.cpp +++ b/hal/src/main/native/systemcore/Counter.cpp @@ -13,7 +13,7 @@ #include "HALInternal.hpp" #include "PortsInternal.hpp" #include "SmartIo.hpp" -#include "wpi/hal/cpp/fpga_clock.hpp" +#include "wpi/hal/monotonic_clock.hpp" using namespace wpi::hal; @@ -74,9 +74,9 @@ void HAL_FreeCounter(HAL_CounterHandle counterHandle) { smartIoHandles->Free(counterHandle, HAL_HandleEnum::Counter); // Wait for no other object to hold this handle. - auto start = wpi::hal::fpga_clock::now(); + auto start = wpi::hal::monotonic_clock::now(); while (port.use_count() != 1) { - auto current = wpi::hal::fpga_clock::now(); + auto current = wpi::hal::monotonic_clock::now(); if (start + std::chrono::seconds(1) < current) { std::puts("DIO handle free timeout"); std::fflush(stdout); diff --git a/hal/src/main/native/systemcore/DIO.cpp b/hal/src/main/native/systemcore/DIO.cpp index cb5bd89de7..3b1abb5321 100644 --- a/hal/src/main/native/systemcore/DIO.cpp +++ b/hal/src/main/native/systemcore/DIO.cpp @@ -13,8 +13,8 @@ #include "PortsInternal.hpp" #include "SmartIo.hpp" #include "wpi/hal/Errors.h" -#include "wpi/hal/cpp/fpga_clock.hpp" #include "wpi/hal/handles/HandlesInternal.hpp" +#include "wpi/hal/monotonic_clock.hpp" using namespace wpi::hal; @@ -79,9 +79,9 @@ void HAL_FreeDIOPort(HAL_DigitalHandle dioPortHandle) { smartIoHandles->Free(dioPortHandle, HAL_HandleEnum::DIO); // Wait for no other object to hold this handle. - auto start = wpi::hal::fpga_clock::now(); + auto start = wpi::hal::monotonic_clock::now(); while (port.use_count() != 1) { - auto current = wpi::hal::fpga_clock::now(); + auto current = wpi::hal::monotonic_clock::now(); if (start + std::chrono::seconds(1) < current) { std::puts("DIO handle free timeout"); std::fflush(stdout); diff --git a/hal/src/main/native/systemcore/DutyCycle.cpp b/hal/src/main/native/systemcore/DutyCycle.cpp index 9212ac3ae7..d9bf3f31c4 100644 --- a/hal/src/main/native/systemcore/DutyCycle.cpp +++ b/hal/src/main/native/systemcore/DutyCycle.cpp @@ -12,8 +12,8 @@ #include "PortsInternal.hpp" #include "SmartIo.hpp" #include "wpi/hal/Errors.h" -#include "wpi/hal/cpp/fpga_clock.hpp" #include "wpi/hal/handles/HandlesInternal.hpp" +#include "wpi/hal/monotonic_clock.hpp" using namespace wpi::hal; @@ -71,9 +71,9 @@ void HAL_FreeDutyCycle(HAL_DutyCycleHandle dutyCycleHandle) { smartIoHandles->Free(dutyCycleHandle, HAL_HandleEnum::DutyCycle); // Wait for no other object to hold this handle. - auto start = wpi::hal::fpga_clock::now(); + auto start = wpi::hal::monotonic_clock::now(); while (port.use_count() != 1) { - auto current = wpi::hal::fpga_clock::now(); + auto current = wpi::hal::monotonic_clock::now(); if (start + std::chrono::seconds(1) < current) { std::puts("DIO handle free timeout"); std::fflush(stdout); diff --git a/hal/src/main/native/systemcore/HAL.cpp b/hal/src/main/native/systemcore/HAL.cpp index c69fffffc5..a4eab1560a 100644 --- a/hal/src/main/native/systemcore/HAL.cpp +++ b/hal/src/main/native/systemcore/HAL.cpp @@ -205,35 +205,11 @@ int32_t HAL_GetTeamNumber(void) { return teamNumber; } -uint64_t HAL_GetFPGATime(int32_t* status) { +uint64_t HAL_GetMonotonicTime(void) { wpi::hal::init::CheckInit(); return wpi::util::NowDefault(); } -uint64_t HAL_ExpandFPGATime(uint32_t unexpandedLower, int32_t* status) { - // Capture the current FPGA time. This will give us the upper half of the - // clock. - uint64_t fpgaTime = HAL_GetFPGATime(status); - if (*status != 0) { - return 0; - } - - // Now, we need to detect the case where the lower bits rolled over after we - // sampled. In that case, the upper bits will be 1 bigger than they should - // be. - - // Break it into lower and upper portions. - uint32_t lower = fpgaTime & 0xffffffffull; - uint64_t upper = (fpgaTime >> 32) & 0xffffffff; - - // The time was sampled *before* the current time, so roll it back. - if (lower < unexpandedLower) { - --upper; - } - - return (upper << 32) + static_cast(unexpandedLower); -} - HAL_Bool HAL_GetSystemActive(int32_t* status) { wpi::hal::init::CheckInit(); *status = HAL_HANDLE_ERROR; @@ -296,14 +272,9 @@ HAL_Bool HAL_Initialize(int32_t timeout, int32_t mode) { // WPILIB_NetworkCommunication_Reserve(nullptr); - int32_t status = 0; - wpi::hal::InitializeDriverStation(); - dsStartTime = HAL_GetFPGATime(&status); - if (status != 0) { - return false; - } + dsStartTime = HAL_GetMonotonicTime(); wpi::hal::WaitForInitialPacket(); diff --git a/hal/src/main/native/systemcore/Notifier.cpp b/hal/src/main/native/systemcore/Notifier.cpp index 93b5c91ff6..6e64e4ada2 100644 --- a/hal/src/main/native/systemcore/Notifier.cpp +++ b/hal/src/main/native/systemcore/Notifier.cpp @@ -84,8 +84,7 @@ void NotifierThread::Main() { // Wait until next alarm const Alarm& alarm = m_alarmQueue.top(); - int32_t status = 0; - uint64_t curTime = HAL_GetFPGATime(&status); + uint64_t curTime = HAL_GetMonotonicTime(); if (alarm.notifier->alarmTime > curTime) { m_cond.wait_for( lock, std::chrono::microseconds{alarm.notifier->alarmTime - curTime}); @@ -99,8 +98,7 @@ void NotifierThread::Main() { } void NotifierThread::ProcessAlarms() { - int32_t status = 0; - uint64_t curTime = HAL_GetFPGATime(&status); + uint64_t curTime = HAL_GetMonotonicTime(); while (!m_alarmQueue.empty() && m_alarmQueue.top().notifier->alarmTime <= curTime) { @@ -190,7 +188,7 @@ void HAL_SetNotifierAlarm(HAL_NotifierHandle notifierHandle, uint64_t alarmTime, } if (!absolute) { - alarmTime += HAL_GetFPGATime(status); + alarmTime += HAL_GetMonotonicTime(); } uint64_t prevWakeup = UINT64_MAX; diff --git a/hal/src/main/native/systemcore/PWM.cpp b/hal/src/main/native/systemcore/PWM.cpp index 7182858050..267f654b0c 100644 --- a/hal/src/main/native/systemcore/PWM.cpp +++ b/hal/src/main/native/systemcore/PWM.cpp @@ -15,8 +15,8 @@ #include "PortsInternal.hpp" #include "SmartIo.hpp" #include "wpi/hal/Errors.h" -#include "wpi/hal/cpp/fpga_clock.hpp" #include "wpi/hal/handles/HandlesInternal.hpp" +#include "wpi/hal/monotonic_clock.hpp" using namespace wpi::hal; @@ -83,9 +83,9 @@ void HAL_FreePWMPort(HAL_DigitalHandle pwmPortHandle) { smartIoHandles->Free(pwmPortHandle, HAL_HandleEnum::PWM); // Wait for no other object to hold this handle. - auto start = wpi::hal::fpga_clock::now(); + auto start = wpi::hal::monotonic_clock::now(); while (port.use_count() != 1) { - auto current = wpi::hal::fpga_clock::now(); + auto current = wpi::hal::monotonic_clock::now(); if (start + std::chrono::seconds(1) < current) { std::puts("PWM handle free timeout"); std::fflush(stdout); diff --git a/hal/src/main/native/systemcore/PowerDistribution.cpp b/hal/src/main/native/systemcore/PowerDistribution.cpp index c0c3fbebec..f54ee8cc21 100644 --- a/hal/src/main/native/systemcore/PowerDistribution.cpp +++ b/hal/src/main/native/systemcore/PowerDistribution.cpp @@ -34,10 +34,7 @@ HAL_PowerDistributionHandle HAL_InitializePowerDistribution( // Ensure we have been alive for long enough to receive a few Power packets. do { - uint64_t currentTime = HAL_GetFPGATime(status); - if (*status != 0) { - return HAL_kInvalidHandle; - } + uint64_t currentTime = HAL_GetMonotonicTime(); if (currentTime >= waitTime) { break; } diff --git a/hal/src/main/python/semiwrap/HAL.yml b/hal/src/main/python/semiwrap/HAL.yml index a731548e13..38516cabb9 100644 --- a/hal/src/main/python/semiwrap/HAL.yml +++ b/hal/src/main/python/semiwrap/HAL.yml @@ -33,8 +33,7 @@ functions: HAL_GetRuntimeType: HAL_GetSystemActive: HAL_GetBrownedOut: - HAL_GetFPGATime: - HAL_ExpandFPGATime: + HAL_GetMonotonicTime: HAL_GetRSLState: HAL_GetSystemTimeValid: HAL_Initialize: diff --git a/robotpyExamples/RomiReference/commands/drivetime.py b/robotpyExamples/RomiReference/commands/drivetime.py index 57312f57c0..09e3dbf7c9 100644 --- a/robotpyExamples/RomiReference/commands/drivetime.py +++ b/robotpyExamples/RomiReference/commands/drivetime.py @@ -30,7 +30,7 @@ class DriveTime(commands2.Command): def initialize(self) -> None: """Called when the command is initially scheduled.""" - self.startTime = wpilib.Timer.getFPGATimestamp() + self.startTime = wpilib.Timer.getTimestamp() self.drive.arcadeDrive(0, 0) def execute(self) -> None: @@ -43,4 +43,4 @@ class DriveTime(commands2.Command): def isFinished(self) -> bool: """Returns true when the command should end""" - return wpilib.Timer.getFPGATimestamp() - self.startTime >= self.duration + return wpilib.Timer.getTimestamp() - self.startTime >= self.duration diff --git a/robotpyExamples/RomiReference/commands/turntime.py b/robotpyExamples/RomiReference/commands/turntime.py index 59b2774a6a..61667107c9 100644 --- a/robotpyExamples/RomiReference/commands/turntime.py +++ b/robotpyExamples/RomiReference/commands/turntime.py @@ -32,7 +32,7 @@ class TurnTime(commands2.Command): def initialize(self) -> None: """Called when the command is initially scheduled.""" - self.startTime = wpilib.Timer.getFPGATimestamp() + self.startTime = wpilib.Timer.getTimestamp() self.drive.arcadeDrive(0, 0) def execute(self) -> None: @@ -45,4 +45,4 @@ class TurnTime(commands2.Command): def isFinished(self) -> bool: """Returns true when the command should end""" - return wpilib.Timer.getFPGATimestamp() - self.startTime >= self.duration + return wpilib.Timer.getTimestamp() - self.startTime >= self.duration diff --git a/robotpyExamples/XrpReference/commands/drivetime.py b/robotpyExamples/XrpReference/commands/drivetime.py index 57312f57c0..09e3dbf7c9 100644 --- a/robotpyExamples/XrpReference/commands/drivetime.py +++ b/robotpyExamples/XrpReference/commands/drivetime.py @@ -30,7 +30,7 @@ class DriveTime(commands2.Command): def initialize(self) -> None: """Called when the command is initially scheduled.""" - self.startTime = wpilib.Timer.getFPGATimestamp() + self.startTime = wpilib.Timer.getTimestamp() self.drive.arcadeDrive(0, 0) def execute(self) -> None: @@ -43,4 +43,4 @@ class DriveTime(commands2.Command): def isFinished(self) -> bool: """Returns true when the command should end""" - return wpilib.Timer.getFPGATimestamp() - self.startTime >= self.duration + return wpilib.Timer.getTimestamp() - self.startTime >= self.duration diff --git a/robotpyExamples/XrpReference/commands/turntime.py b/robotpyExamples/XrpReference/commands/turntime.py index 59b2774a6a..61667107c9 100644 --- a/robotpyExamples/XrpReference/commands/turntime.py +++ b/robotpyExamples/XrpReference/commands/turntime.py @@ -32,7 +32,7 @@ class TurnTime(commands2.Command): def initialize(self) -> None: """Called when the command is initially scheduled.""" - self.startTime = wpilib.Timer.getFPGATimestamp() + self.startTime = wpilib.Timer.getTimestamp() self.drive.arcadeDrive(0, 0) def execute(self) -> None: @@ -45,4 +45,4 @@ class TurnTime(commands2.Command): def isFinished(self) -> bool: """Returns true when the command should end""" - return wpilib.Timer.getFPGATimestamp() - self.startTime >= self.duration + return wpilib.Timer.getTimestamp() - self.startTime >= self.duration diff --git a/simulation/halsim_gui/src/main/native/cpp/DriverStationGui.cpp b/simulation/halsim_gui/src/main/native/cpp/DriverStationGui.cpp index 8b998ee609..750b4edaf7 100644 --- a/simulation/halsim_gui/src/main/native/cpp/DriverStationGui.cpp +++ b/simulation/halsim_gui/src/main/native/cpp/DriverStationGui.cpp @@ -1333,8 +1333,7 @@ void FMSSimModel::Update() { double matchTime = HALSIM_GetDriverStationMatchTime(); if (!IsDSDisabled() && enabled) { - int32_t status = 0; - double curTime = HAL_GetFPGATime(&status) * 1.0e-6; + double curTime = HAL_GetMonotonicTime() * 1.0e-6; if (m_startMatchTime == -1.0) { m_startMatchTime = matchTime + curTime; } diff --git a/simulation/halsim_gui/src/main/native/cpp/TimingGui.cpp b/simulation/halsim_gui/src/main/native/cpp/TimingGui.cpp index 1144f05d3b..df953b2797 100644 --- a/simulation/halsim_gui/src/main/native/cpp/TimingGui.cpp +++ b/simulation/halsim_gui/src/main/native/cpp/TimingGui.cpp @@ -29,8 +29,7 @@ class TimingModel : public wpi::glass::Model { } // namespace static void DisplayTiming() { - int32_t status = 0; - uint64_t curTime = HAL_GetFPGATime(&status); + uint64_t curTime = HAL_GetMonotonicTime(); if (ImGui::Button("Run")) { HALSIM_ResumeTiming(); @@ -50,7 +49,7 @@ static void DisplayTiming() { } ImGui::PopButtonRepeat(); ImGui::PushItemWidth(ImGui::GetFontSize() * 4); - ImGui::LabelText("FPGA Time", "%.3f", curTime / 1000000.0); + ImGui::LabelText("Time", "%.3f", curTime / 1000000.0); ImGui::PopItemWidth(); static std::vector notifiers; diff --git a/wpilibc/src/main/native/cpp/framework/TimedRobot.cpp b/wpilibc/src/main/native/cpp/framework/TimedRobot.cpp index c5ca97188c..2224a3aa4b 100644 --- a/wpilibc/src/main/native/cpp/framework/TimedRobot.cpp +++ b/wpilibc/src/main/native/cpp/framework/TimedRobot.cpp @@ -41,7 +41,7 @@ void TimedRobot::StartCompetition() { break; } - m_loopStartTimeUs = RobotController::GetFPGATime(); + m_loopStartTimeUs = RobotController::GetMonotonicTime(); std::chrono::microseconds currentTime{m_loopStartTimeUs}; callback.func(); @@ -76,7 +76,7 @@ void TimedRobot::EndCompetition() { TimedRobot::TimedRobot(wpi::units::second_t period) : IterativeRobotBase(period) { - m_startTime = std::chrono::microseconds{RobotController::GetFPGATime()}; + m_startTime = std::chrono::microseconds{RobotController::GetMonotonicTime()}; AddPeriodic([=, this] { LoopFunc(); }, period); int32_t status = 0; diff --git a/wpilibc/src/main/native/cpp/hardware/motor/MotorSafety.cpp b/wpilibc/src/main/native/cpp/hardware/motor/MotorSafety.cpp index eb84ab58eb..c42d64f037 100644 --- a/wpilibc/src/main/native/cpp/hardware/motor/MotorSafety.cpp +++ b/wpilibc/src/main/native/cpp/hardware/motor/MotorSafety.cpp @@ -115,7 +115,7 @@ MotorSafety& MotorSafety::operator=(MotorSafety&& rhs) { void MotorSafety::Feed() { std::scoped_lock lock(m_thisMutex); - m_stopTime = Timer::GetFPGATimestamp() + m_expiration; + m_stopTime = Timer::GetMonotonicTimestamp() + m_expiration; } void MotorSafety::SetExpiration(wpi::units::second_t expirationTime) { @@ -130,7 +130,7 @@ wpi::units::second_t MotorSafety::GetExpiration() const { bool MotorSafety::IsAlive() const { std::scoped_lock lock(m_thisMutex); - return !m_enabled || m_stopTime > Timer::GetFPGATimestamp(); + return !m_enabled || m_stopTime > Timer::GetMonotonicTimestamp(); } void MotorSafety::SetSafetyEnabled(bool enabled) { @@ -157,7 +157,7 @@ void MotorSafety::Check() { return; } - if (stopTime < Timer::GetFPGATimestamp()) { + if (stopTime < Timer::GetMonotonicTimestamp()) { WPILIB_ReportError( err::Timeout, "{}... Output not updated often enough. See " diff --git a/wpilibc/src/main/native/cpp/opmode/PeriodicOpMode.cpp b/wpilibc/src/main/native/cpp/opmode/PeriodicOpMode.cpp index e5348ecaef..14cd15af33 100644 --- a/wpilibc/src/main/native/cpp/opmode/PeriodicOpMode.cpp +++ b/wpilibc/src/main/native/cpp/opmode/PeriodicOpMode.cpp @@ -25,7 +25,7 @@ PeriodicOpMode::Callback::Callback(std::function func, period{period}, expirationTime( startTime + offset + period + - (std::chrono::microseconds{wpi::RobotController::GetFPGATime()} - + (std::chrono::microseconds{wpi::RobotController::GetMonotonicTime()} - startTime) / period * period) {} @@ -38,7 +38,7 @@ PeriodicOpMode::~PeriodicOpMode() { PeriodicOpMode::PeriodicOpMode(wpi::units::second_t period) : m_period{period}, m_watchdog(period, [this] { PrintLoopOverrunMessage(); }) { - m_startTime = std::chrono::microseconds{RobotController::GetFPGATime()}; + m_startTime = std::chrono::microseconds{RobotController::GetMonotonicTime()}; AddPeriodic([=, this] { LoopFunc(); }, period); int32_t status = 0; @@ -116,7 +116,7 @@ void PeriodicOpMode::OpModeRun(int64_t opModeId) { break; } - m_loopStartTimeUs = RobotController::GetFPGATime(); + m_loopStartTimeUs = RobotController::GetMonotonicTime(); std::chrono::microseconds currentTime{m_loopStartTimeUs}; callback.func(); diff --git a/wpilibc/src/main/native/cpp/system/RobotController.cpp b/wpilibc/src/main/native/cpp/system/RobotController.cpp index a81b372801..90c9d13084 100644 --- a/wpilibc/src/main/native/cpp/system/RobotController.cpp +++ b/wpilibc/src/main/native/cpp/system/RobotController.cpp @@ -16,7 +16,7 @@ using namespace wpi; std::function RobotController::m_timeSource = [] { - return RobotController::GetFPGATime(); + return RobotController::GetMonotonicTime(); }; std::string RobotController::GetSerialNumber() { @@ -47,11 +47,8 @@ uint64_t RobotController::GetTime() { return m_timeSource(); } -uint64_t RobotController::GetFPGATime() { - int32_t status = 0; - uint64_t time = HAL_GetFPGATime(&status); - WPILIB_CheckErrorStatus(status, "GetFPGATime"); - return time; +uint64_t RobotController::GetMonotonicTime() { + return HAL_GetMonotonicTime(); } wpi::units::volt_t RobotController::GetBatteryVoltage() { diff --git a/wpilibc/src/main/native/cpp/system/Timer.cpp b/wpilibc/src/main/native/cpp/system/Timer.cpp index fd1e7b58f9..f6a3d5aff4 100644 --- a/wpilibc/src/main/native/cpp/system/Timer.cpp +++ b/wpilibc/src/main/native/cpp/system/Timer.cpp @@ -16,7 +16,7 @@ void Wait(wpi::units::second_t seconds) { std::this_thread::sleep_for(std::chrono::duration(seconds.value())); } -wpi::units::second_t GetTime() { +wpi::units::second_t GetSystemTime() { using std::chrono::duration; using std::chrono::duration_cast; using std::chrono::system_clock; @@ -92,9 +92,10 @@ wpi::units::second_t Timer::GetTimestamp() { return wpi::units::second_t{wpi::RobotController::GetTime() * 1.0e-6}; } -wpi::units::second_t Timer::GetFPGATimestamp() { - // FPGA returns the timestamp in microseconds - return wpi::units::second_t{wpi::RobotController::GetFPGATime() * 1.0e-6}; +wpi::units::second_t Timer::GetMonotonicTimestamp() { + // Monotonic timestamp is in microseconds + return wpi::units::second_t{wpi::RobotController::GetMonotonicTime() * + 1.0e-6}; } wpi::units::second_t Timer::GetMatchTime() { diff --git a/wpilibc/src/main/native/cpp/system/Tracer.cpp b/wpilibc/src/main/native/cpp/system/Tracer.cpp index f63ebee245..e30233366b 100644 --- a/wpilibc/src/main/native/cpp/system/Tracer.cpp +++ b/wpilibc/src/main/native/cpp/system/Tracer.cpp @@ -17,7 +17,7 @@ Tracer::Tracer() { } void Tracer::ResetTimer() { - m_startTime = wpi::hal::fpga_clock::now(); + m_startTime = wpi::hal::monotonic_clock::now(); } void Tracer::ClearEpochs() { @@ -26,7 +26,7 @@ void Tracer::ClearEpochs() { } void Tracer::AddEpoch(std::string_view epochName) { - auto currentTime = wpi::hal::fpga_clock::now(); + auto currentTime = wpi::hal::monotonic_clock::now(); m_epochs[epochName] = currentTime - m_startTime; m_startTime = currentTime; } @@ -44,7 +44,7 @@ void Tracer::PrintEpochs(wpi::util::raw_ostream& os) { using std::chrono::duration_cast; using std::chrono::microseconds; - auto now = wpi::hal::fpga_clock::now(); + auto now = wpi::hal::monotonic_clock::now(); if (now - m_lastEpochsPrintTime > kMinPrintPeriod) { m_lastEpochsPrintTime = now; for (const auto& epoch : m_epochs) { diff --git a/wpilibc/src/main/native/cpp/system/Watchdog.cpp b/wpilibc/src/main/native/cpp/system/Watchdog.cpp index 789c13c6ee..fb48f5d484 100644 --- a/wpilibc/src/main/native/cpp/system/Watchdog.cpp +++ b/wpilibc/src/main/native/cpp/system/Watchdog.cpp @@ -87,7 +87,6 @@ void Watchdog::Impl::UpdateAlarm() { void Watchdog::Impl::Main() { for (;;) { - int32_t status = 0; HAL_NotifierHandle notifier = m_notifier.load(); if (notifier == 0) { break; @@ -95,7 +94,7 @@ void Watchdog::Impl::Main() { if (WPI_WaitForObject(notifier) == 0) { break; } - uint64_t curTime = HAL_GetFPGATime(&status); + uint64_t curTime = HAL_GetMonotonicTime(); std::unique_lock lock(m_mutex); @@ -163,11 +162,11 @@ Watchdog& Watchdog::operator=(Watchdog&& rhs) { } wpi::units::second_t Watchdog::GetTime() const { - return Timer::GetFPGATimestamp() - m_startTime; + return Timer::GetMonotonicTimestamp() - m_startTime; } void Watchdog::SetTimeout(wpi::units::second_t timeout) { - m_startTime = Timer::GetFPGATimestamp(); + m_startTime = Timer::GetMonotonicTimestamp(); m_tracer.ClearEpochs(); std::scoped_lock lock(m_impl->m_mutex); @@ -203,7 +202,7 @@ void Watchdog::Reset() { } void Watchdog::Enable() { - m_startTime = Timer::GetFPGATimestamp(); + m_startTime = Timer::GetMonotonicTimestamp(); m_tracer.ClearEpochs(); std::scoped_lock lock(m_impl->m_mutex); diff --git a/wpilibc/src/main/native/include/wpi/framework/TimedRobot.hpp b/wpilibc/src/main/native/include/wpi/framework/TimedRobot.hpp index 6bc34ffc23..b05eb823bc 100644 --- a/wpilibc/src/main/native/include/wpi/framework/TimedRobot.hpp +++ b/wpilibc/src/main/native/include/wpi/framework/TimedRobot.hpp @@ -64,9 +64,10 @@ class TimedRobot : public IterativeRobotBase { /** * Return the system clock time in microseconds for the start of the current - * periodic loop. This is in the same time base as Timer.GetFPGATimestamp(), - * but is stable through a loop. It is updated at the beginning of every - * periodic callback (including the normal periodic loop). + * periodic loop. This is in the same time base as + * Timer.GetMonotonicTimestamp(), but is stable through a loop. It is updated + * at the beginning of every periodic callback (including the normal periodic + * loop). * * @return Robot running time in microseconds, as of the start of the current * periodic function. @@ -107,11 +108,11 @@ class TimedRobot : public IterativeRobotBase { std::chrono::microseconds period, std::chrono::microseconds offset) : func{std::move(func)}, period{period}, - expirationTime( - startTime + offset + period + - (std::chrono::microseconds{wpi::RobotController::GetFPGATime()} - - startTime) / - period * period) {} + expirationTime(startTime + offset + period + + (std::chrono::microseconds{ + wpi::RobotController::GetMonotonicTime()} - + startTime) / + period * period) {} bool operator>(const Callback& rhs) const { return expirationTime > rhs.expirationTime; diff --git a/wpilibc/src/main/native/include/wpi/hardware/motor/MotorSafety.hpp b/wpilibc/src/main/native/include/wpi/hardware/motor/MotorSafety.hpp index 78f981ce7a..f4e2784c34 100644 --- a/wpilibc/src/main/native/include/wpi/hardware/motor/MotorSafety.hpp +++ b/wpilibc/src/main/native/include/wpi/hardware/motor/MotorSafety.hpp @@ -114,7 +114,7 @@ class MotorSafety { bool m_enabled = false; // The FPGA clock value when the motor has expired - wpi::units::second_t m_stopTime = Timer::GetFPGATimestamp(); + wpi::units::second_t m_stopTime = Timer::GetMonotonicTimestamp(); mutable wpi::util::mutex m_thisMutex; }; diff --git a/wpilibc/src/main/native/include/wpi/opmode/PeriodicOpMode.hpp b/wpilibc/src/main/native/include/wpi/opmode/PeriodicOpMode.hpp index 41b262d189..610ed583e9 100644 --- a/wpilibc/src/main/native/include/wpi/opmode/PeriodicOpMode.hpp +++ b/wpilibc/src/main/native/include/wpi/opmode/PeriodicOpMode.hpp @@ -91,9 +91,10 @@ class PeriodicOpMode : public OpMode { /** * Return the system clock time in microseconds for the start of the current - * periodic loop. This is in the same time base as Timer.getFPGATimestamp(), - * but is stable through a loop. It is updated at the beginning of every - * periodic callback (including the normal periodic loop). + * periodic loop. This is in the same time base as + * Timer::GetMonotonicTimestamp(), but is stable through a loop. It is updated + * at the beginning of every periodic callback (including the normal periodic + * loop). * * @return Robot running time in microseconds, as of the start of the current * periodic function. diff --git a/wpilibc/src/main/native/include/wpi/system/RobotController.hpp b/wpilibc/src/main/native/include/wpi/system/RobotController.hpp index 10f3f7eb6a..7f2f1a89fe 100644 --- a/wpilibc/src/main/native/include/wpi/system/RobotController.hpp +++ b/wpilibc/src/main/native/include/wpi/system/RobotController.hpp @@ -60,22 +60,21 @@ class RobotController { static void SetTimeSource(std::function supplier); /** - * Read the microsecond timestamp. By default, the time is based on the FPGA - * hardware clock in microseconds since the FPGA started. However, the return - * value of this method may be modified to use any time base, including - * non-monotonic and non-continuous time bases. + * Read the microsecond timestamp. By default, the time is based on the + * monotonic clock. However, the return value of this method may be modified + * to use any time base, including non-monotonic and non-continuous time + * bases. * * @return The current time in microseconds. */ static uint64_t GetTime(); /** - * Read the microsecond-resolution timer on the FPGA. + * Read the microsecond-resolution monotonic timer. * - * @return The current time in microseconds according to the FPGA (since FPGA - * reset). + * @return The current monotonic time in microseconds. */ - static uint64_t GetFPGATime(); + static uint64_t GetMonotonicTime(); /** * Read the battery voltage. diff --git a/wpilibc/src/main/native/include/wpi/system/Timer.hpp b/wpilibc/src/main/native/include/wpi/system/Timer.hpp index e9264ddcc6..23f5f93afb 100644 --- a/wpilibc/src/main/native/include/wpi/system/Timer.hpp +++ b/wpilibc/src/main/native/include/wpi/system/Timer.hpp @@ -25,7 +25,7 @@ void Wait(wpi::units::second_t seconds); * @return The time, just in case you want the robot to start autonomous at 8pm * on Saturday. */ -wpi::units::second_t GetTime(); +wpi::units::second_t GetSystemTime(); /** * A timer class. @@ -119,24 +119,22 @@ class Timer { bool IsRunning() const; /** - * Return the clock time in seconds. By default, the time is based on the FPGA - * hardware clock in seconds since the FPGA started. However, the return value - * of this method may be modified to use any time base, including - * non-monotonic time bases. + * Return the clock time in seconds. By default, the time is the time returned + * by GetMonotonicTimestamp(). However, the return value of this method may be + * modified to use any time base, including non-monotonic time bases. * * @returns Robot running time in seconds. */ static wpi::units::second_t GetTimestamp(); /** - * Return the FPGA system clock time in seconds. + * Return the monotonic clock time in seconds. * - * Return the time from the FPGA hardware clock in seconds since the FPGA - * started. Rolls over after 71 minutes. + * Return the time from the monotonic clock in seconds. * - * @returns Robot running time in seconds. + * @returns Monotonic time in seconds. */ - static wpi::units::second_t GetFPGATimestamp(); + static wpi::units::second_t GetMonotonicTimestamp(); /** * Return the approximate match time. The FMS does not send an official match diff --git a/wpilibc/src/main/native/include/wpi/system/Tracer.hpp b/wpilibc/src/main/native/include/wpi/system/Tracer.hpp index 3839ae7e8d..e7fa4524b3 100644 --- a/wpilibc/src/main/native/include/wpi/system/Tracer.hpp +++ b/wpilibc/src/main/native/include/wpi/system/Tracer.hpp @@ -7,7 +7,7 @@ #include #include -#include "wpi/hal/cpp/fpga_clock.hpp" +#include "wpi/hal/monotonic_clock.hpp" #include "wpi/util/StringMap.hpp" namespace wpi::util { @@ -65,9 +65,9 @@ class Tracer { private: static constexpr std::chrono::milliseconds kMinPrintPeriod{1000}; - wpi::hal::fpga_clock::time_point m_startTime; - wpi::hal::fpga_clock::time_point m_lastEpochsPrintTime = - wpi::hal::fpga_clock::epoch(); + wpi::hal::monotonic_clock::time_point m_startTime; + wpi::hal::monotonic_clock::time_point m_lastEpochsPrintTime = + wpi::hal::monotonic_clock::epoch(); wpi::util::StringMap m_epochs; }; diff --git a/wpilibc/src/main/python/semiwrap/RobotController.yml b/wpilibc/src/main/python/semiwrap/RobotController.yml index 422ba4cdac..86c611392a 100644 --- a/wpilibc/src/main/python/semiwrap/RobotController.yml +++ b/wpilibc/src/main/python/semiwrap/RobotController.yml @@ -14,7 +14,7 @@ classes: GetTeamNumber: SetTimeSource: GetTime: - GetFPGATime: + GetMonotonicTime: IsSysActive: IsBrownedOut: GetRSLState: diff --git a/wpilibc/src/main/python/semiwrap/Timer.yml b/wpilibc/src/main/python/semiwrap/Timer.yml index 869d27d118..bb8af2c2fb 100644 --- a/wpilibc/src/main/python/semiwrap/Timer.yml +++ b/wpilibc/src/main/python/semiwrap/Timer.yml @@ -1,6 +1,6 @@ functions: Wait: - GetTime: + GetSystemTime: classes: wpi::Timer: methods: @@ -10,7 +10,7 @@ classes: Start: Restart: Stop: - GetFPGATimestamp: + GetMonotonicTimestamp: GetMatchTime: HasElapsed: AdvanceIfElapsed: diff --git a/wpilibc/src/main/python/wpilib/__init__.py b/wpilibc/src/main/python/wpilib/__init__.py index 5c89e9fb29..170fa05c2e 100644 --- a/wpilibc/src/main/python/wpilib/__init__.py +++ b/wpilibc/src/main/python/wpilib/__init__.py @@ -99,7 +99,7 @@ from ._wpilib import ( getDeployDirectory, getErrorMessage, getOperatingDirectory, - getTime, + getSystemTime, setCurrentThreadPriority, wait, ) @@ -202,7 +202,7 @@ __all__ = [ "getDeployDirectory", "getErrorMessage", "getOperatingDirectory", - "getTime", + "getSystemTime", "setCurrentThreadPriority", "wait", ] diff --git a/wpilibc/src/test/native/cpp/TimerTest.cpp b/wpilibc/src/test/native/cpp/TimerTest.cpp index 9523d881b7..f386853165 100644 --- a/wpilibc/src/test/native/cpp/TimerTest.cpp +++ b/wpilibc/src/test/native/cpp/TimerTest.cpp @@ -112,9 +112,9 @@ TEST_F(TimerTest, AdvanceIfElapsed) { EXPECT_FALSE(timer.AdvanceIfElapsed(400_ms)); } -TEST_F(TimerTest, GetFPGATimestamp) { - auto start = wpi::Timer::GetFPGATimestamp(); +TEST_F(TimerTest, GetMonotonicTimestamp) { + auto start = wpi::Timer::GetMonotonicTimestamp(); wpi::sim::StepTiming(500_ms); - auto end = wpi::Timer::GetFPGATimestamp(); + auto end = wpi::Timer::GetMonotonicTimestamp(); EXPECT_EQ(start + 500_ms, end); } diff --git a/wpilibj/src/main/java/org/wpilib/framework/TimedRobot.java b/wpilibj/src/main/java/org/wpilib/framework/TimedRobot.java index bd4205f4b5..36cc513228 100644 --- a/wpilibj/src/main/java/org/wpilib/framework/TimedRobot.java +++ b/wpilibj/src/main/java/org/wpilib/framework/TimedRobot.java @@ -44,7 +44,7 @@ public class TimedRobot extends IterativeRobotBase { startTime + offset + this.period - + (RobotController.getFPGATime() - startTime) / this.period * this.period; + + (RobotController.getMonotonicTime() - startTime) / this.period * this.period; } @Override @@ -89,7 +89,7 @@ public class TimedRobot extends IterativeRobotBase { */ protected TimedRobot(double period) { super(period); - m_startTimeUs = RobotController.getFPGATime(); + m_startTimeUs = RobotController.getMonotonicTime(); addPeriodic(this::loopFunc, period); NotifierJNI.setNotifierName(m_notifier, "TimedRobot"); @@ -146,7 +146,7 @@ public class TimedRobot extends IterativeRobotBase { break; } - long currentTime = RobotController.getFPGATime(); + long currentTime = RobotController.getMonotonicTime(); m_loopStartTimeUs = currentTime; callback.func.run(); @@ -182,7 +182,7 @@ public class TimedRobot extends IterativeRobotBase { /** * Return the system clock time in microseconds for the start of the current periodic loop. This - * is in the same time base as Timer.getFPGATimestamp(), but is stable through a loop. It is + * is in the same time base as Timer.getMonotonicTimestamp(), but is stable through a loop. It is * updated at the beginning of every periodic callback (including the normal periodic loop). * * @return Robot running time in microseconds, as of the start of the current periodic function. diff --git a/wpilibj/src/main/java/org/wpilib/hardware/motor/MotorSafety.java b/wpilibj/src/main/java/org/wpilib/hardware/motor/MotorSafety.java index 16b466c5f8..e623bd561d 100644 --- a/wpilibj/src/main/java/org/wpilib/hardware/motor/MotorSafety.java +++ b/wpilibj/src/main/java/org/wpilib/hardware/motor/MotorSafety.java @@ -25,7 +25,7 @@ public abstract class MotorSafety { private double m_expiration = kDefaultSafetyExpiration; private boolean m_enabled; - private double m_stopTime = Timer.getFPGATimestamp(); + private double m_stopTime = Timer.getMonotonicTimestamp(); private final Object m_thisMutex = new Object(); private static final Set m_instanceList = new LinkedHashSet<>(); private static final Object m_listMutex = new Object(); @@ -83,7 +83,7 @@ public abstract class MotorSafety { */ public void feed() { synchronized (m_thisMutex) { - m_stopTime = Timer.getFPGATimestamp() + m_expiration; + m_stopTime = Timer.getMonotonicTimestamp() + m_expiration; } } @@ -116,7 +116,7 @@ public abstract class MotorSafety { */ public boolean isAlive() { synchronized (m_thisMutex) { - return !m_enabled || m_stopTime > Timer.getFPGATimestamp(); + return !m_enabled || m_stopTime > Timer.getMonotonicTimestamp(); } } @@ -138,7 +138,7 @@ public abstract class MotorSafety { return; } - if (stopTime < Timer.getFPGATimestamp()) { + if (stopTime < Timer.getMonotonicTimestamp()) { DriverStation.reportError( getDescription() + "... Output not updated often enough. See https://docs.wpilib.org/motorsafety for more information.", diff --git a/wpilibj/src/main/java/org/wpilib/opmode/PeriodicOpMode.java b/wpilibj/src/main/java/org/wpilib/opmode/PeriodicOpMode.java index 064cea93e9..f7562b6209 100644 --- a/wpilibj/src/main/java/org/wpilib/opmode/PeriodicOpMode.java +++ b/wpilibj/src/main/java/org/wpilib/opmode/PeriodicOpMode.java @@ -66,7 +66,7 @@ public abstract class PeriodicOpMode implements OpMode { startTime + offset + this.period - + (RobotController.getFPGATime() - startTime) / this.period * this.period; + + (RobotController.getMonotonicTime() - startTime) / this.period * this.period; } @Override @@ -120,7 +120,7 @@ public abstract class PeriodicOpMode implements OpMode { * @param period period (in seconds) for callbacks to the periodic() function */ protected PeriodicOpMode(double period) { - m_startTimeUs = RobotController.getFPGATime(); + m_startTimeUs = RobotController.getMonotonicTime(); m_period = period; m_watchdog = new Watchdog(period, this::printLoopOverrunMessage); @@ -157,8 +157,8 @@ public abstract class PeriodicOpMode implements OpMode { /** * Return the system clock time in micrseconds for the start of the current periodic loop. This is - * in the same time base as Timer.getFPGATimestamp(), but is stable through a loop. It is updated - * at the beginning of every periodic callback (including the normal periodic loop). + * in the same time base as Timer.getMonotonicTimestamp(), but is stable through a loop. It is + * updated at the beginning of every periodic callback (including the normal periodic loop). * * @return Robot running time in microseconds, as of the start of the current periodic function. */ @@ -290,8 +290,8 @@ public abstract class PeriodicOpMode implements OpMode { break; } - long currentTime = RobotController.getFPGATime(); - m_loopStartTimeUs = RobotController.getFPGATime(); + long currentTime = RobotController.getMonotonicTime(); + m_loopStartTimeUs = RobotController.getMonotonicTime(); callback.func.run(); diff --git a/wpilibj/src/main/java/org/wpilib/system/RobotController.java b/wpilibj/src/main/java/org/wpilib/system/RobotController.java index 3ed227ad2f..47034b4501 100644 --- a/wpilibj/src/main/java/org/wpilib/system/RobotController.java +++ b/wpilibj/src/main/java/org/wpilib/system/RobotController.java @@ -22,7 +22,7 @@ import org.wpilib.units.measure.Voltage; /** Contains functions for roboRIO functionality. */ public final class RobotController { - private static LongSupplier m_timeSource = RobotController::getFPGATime; + private static LongSupplier m_timeSource = RobotController::getMonotonicTime; private RobotController() { throw new UnsupportedOperationException("This is a utility class!"); @@ -69,9 +69,9 @@ public final class RobotController { } /** - * Read the microsecond timestamp. By default, the time is based on the FPGA hardware clock in - * microseconds since the FPGA started. However, the return value of this method may be modified - * to use any time base, including non-monotonic and non-continuous time bases. + * Read the microsecond timestamp. By default, the time is based on the monotonic clock. However, + * the return value of this method may be modified to use any time base, including non-monotonic + * and non-continuous time bases. * * @return The current time in microseconds. */ @@ -80,9 +80,9 @@ public final class RobotController { } /** - * Read the microsecond timestamp. By default, the time is based on the FPGA hardware clock in - * microseconds since the FPGA started. However, the return value of this method may be modified - * to use any time base, including non-monotonic and non-continuous time bases. + * Read the microsecond timestamp. By default, the time is based on the monotonic clock. However, + * the return value of this method may be modified to use any time base, including non-monotonic + * and non-continuous time bases. * * @return The current time in a measure. */ @@ -91,21 +91,21 @@ public final class RobotController { } /** - * Read the microsecond timer from the FPGA. + * Read the microsecond monotonic timer. * - * @return The current time in microseconds according to the FPGA. + * @return The current monotonic time in microseconds. */ - public static long getFPGATime() { - return HALUtil.getFPGATime(); + public static long getMonotonicTime() { + return HALUtil.getMonotonicTime(); } /** - * Read the microsecond timer in a measure from the FPGA. + * Read the microsecond monotonic timer in a measure. * - * @return The current time according to the FPGA in a measure. + * @return The current monotonic time in a measure. */ - public static Time getMeasureFPGATime() { - return Microseconds.of(HALUtil.getFPGATime()); + public static Time getMeasureMonotonicTime() { + return Microseconds.of(HALUtil.getMonotonicTime()); } /** diff --git a/wpilibj/src/main/java/org/wpilib/system/Timer.java b/wpilibj/src/main/java/org/wpilib/system/Timer.java index 5620d24da7..b438150f48 100644 --- a/wpilibj/src/main/java/org/wpilib/system/Timer.java +++ b/wpilibj/src/main/java/org/wpilib/system/Timer.java @@ -17,9 +17,9 @@ import org.wpilib.units.measure.Time; */ public class Timer { /** - * Return the clock time in seconds. By default, the time is based on the FPGA hardware clock in - * seconds since the FPGA started. However, the return value of this method may be modified to use - * any time base, including non-monotonic time bases. + * Return the clock time in seconds. By default, the time is the time returned by + * getMonotonicTimestamp(). However, the return value of this method may be modified to use any + * time base, including non-monotonic time bases. * * @return Robot running time in seconds. */ @@ -28,13 +28,12 @@ public class Timer { } /** - * Return the system clock time in seconds. Return the time from the FPGA hardware clock in - * seconds since the FPGA started. + * Return the monotonic clock time in seconds. * - * @return Robot running time in seconds. + * @return Monotonic time in seconds. */ - public static double getFPGATimestamp() { - return RobotController.getFPGATime() / 1000000.0; + public static double getMonotonicTimestamp() { + return RobotController.getMonotonicTime() / 1000000.0; } /** diff --git a/wpilibj/src/main/java/org/wpilib/system/Tracer.java b/wpilibj/src/main/java/org/wpilib/system/Tracer.java index b28387a374..63091e6081 100644 --- a/wpilibj/src/main/java/org/wpilib/system/Tracer.java +++ b/wpilibj/src/main/java/org/wpilib/system/Tracer.java @@ -38,7 +38,7 @@ public class Tracer { /** Restarts the epoch timer. */ public final void resetTimer() { - m_startTime = RobotController.getFPGATime(); + m_startTime = RobotController.getMonotonicTime(); } /** @@ -53,7 +53,7 @@ public class Tracer { * @param epochName The name to associate with the epoch. */ public void addEpoch(String epochName) { - long currentTime = RobotController.getFPGATime(); + long currentTime = RobotController.getMonotonicTime(); m_epochs.put(epochName, currentTime - m_startTime); m_startTime = currentTime; } @@ -71,7 +71,7 @@ public class Tracer { * @param output the stream that the output is sent to */ public void printEpochs(Consumer output) { - long now = RobotController.getFPGATime(); + long now = RobotController.getMonotonicTime(); if (now - m_lastEpochsPrintTime > kMinPrintPeriod) { StringBuilder sb = new StringBuilder(); m_lastEpochsPrintTime = now; diff --git a/wpilibj/src/main/java/org/wpilib/system/Watchdog.java b/wpilibj/src/main/java/org/wpilib/system/Watchdog.java index 7e4bf9eb21..df016e7cd7 100644 --- a/wpilibj/src/main/java/org/wpilib/system/Watchdog.java +++ b/wpilibj/src/main/java/org/wpilib/system/Watchdog.java @@ -100,7 +100,7 @@ public class Watchdog implements Closeable, Comparable { * @return The time in seconds since the watchdog was last fed. */ public double getTime() { - return Timer.getFPGATimestamp() - m_startTime; + return Timer.getMonotonicTimestamp() - m_startTime; } /** @@ -109,7 +109,7 @@ public class Watchdog implements Closeable, Comparable { * @param timeout The watchdog's timeout in seconds with microsecond resolution. */ public void setTimeout(double timeout) { - m_startTime = Timer.getFPGATimestamp(); + m_startTime = Timer.getMonotonicTimestamp(); m_tracer.clearEpochs(); m_queueMutex.lock(); @@ -184,7 +184,7 @@ public class Watchdog implements Closeable, Comparable { /** Enables the watchdog timer. */ public void enable() { - m_startTime = Timer.getFPGATimestamp(); + m_startTime = Timer.getMonotonicTimestamp(); m_tracer.clearEpochs(); m_queueMutex.lock(); @@ -247,7 +247,7 @@ public class Watchdog implements Closeable, Comparable { Thread.currentThread().interrupt(); break; } - long curTime = HALUtil.getFPGATime(); + long curTime = HALUtil.getMonotonicTime(); m_queueMutex.lock(); try { diff --git a/wpilibj/src/test/java/org/wpilib/hardware/led/LEDPatternTest.java b/wpilibj/src/test/java/org/wpilib/hardware/led/LEDPatternTest.java index e7d1fb033b..5e41d1855e 100644 --- a/wpilibj/src/test/java/org/wpilib/hardware/led/LEDPatternTest.java +++ b/wpilibj/src/test/java/org/wpilib/hardware/led/LEDPatternTest.java @@ -69,7 +69,7 @@ class LEDPatternTest { @AfterEach void tearDown() { - RobotController.setTimeSource(RobotController::getFPGATime); + RobotController.setTimeSource(RobotController::getMonotonicTime); } @Test diff --git a/wpilibj/src/test/java/org/wpilib/system/TimerTest.java b/wpilibj/src/test/java/org/wpilib/system/TimerTest.java index d9dabfbb7d..1cc3f0d464 100644 --- a/wpilibj/src/test/java/org/wpilib/system/TimerTest.java +++ b/wpilibj/src/test/java/org/wpilib/system/TimerTest.java @@ -127,10 +127,10 @@ class TimerTest { @Test @ResourceLock("timing") - void getFPGATimestampTest() { - double start = Timer.getFPGATimestamp(); + void getMonotonicTimestampTest() { + double start = Timer.getMonotonicTimestamp(); SimHooks.stepTiming(0.5); - double end = Timer.getFPGATimestamp(); + double end = Timer.getMonotonicTimestamp(); assertEquals(start + 0.5, end, 1e-9); } } diff --git a/wpimath/src/main/java/org/wpilib/math/estimator/PoseEstimator.java b/wpimath/src/main/java/org/wpilib/math/estimator/PoseEstimator.java index de8d941630..c39186a2be 100644 --- a/wpimath/src/main/java/org/wpilib/math/estimator/PoseEstimator.java +++ b/wpimath/src/main/java/org/wpilib/math/estimator/PoseEstimator.java @@ -272,9 +272,9 @@ public class PoseEstimator { * @param timestamp The timestamp of the vision measurement in seconds. Note that if you don't use * your own time source by calling {@link * PoseEstimator#updateWithTime(double,Rotation2d,Object)} then you must use a timestamp with - * an epoch since FPGA startup (i.e., the epoch of this timestamp is the same epoch as {@link - * org.wpilib.system.Timer#getFPGATimestamp()}.) This means that you should use {@link - * org.wpilib.system.Timer#getFPGATimestamp()} as your time source or sync the epochs. + * the same epoch as {@link org.wpilib.system.Timer#getMonotonicTimestamp()}.) This means that + * you should use {@link org.wpilib.system.Timer#getMonotonicTimestamp()} as your time source + * or sync the epochs. */ public void addVisionMeasurement(Pose2d visionRobotPose, double timestamp) { // Step 0: If this measurement is old enough to be outside the pose buffer's timespan, skip. @@ -344,9 +344,9 @@ public class PoseEstimator { * @param visionRobotPose The pose of the robot as measured by the vision camera. * @param timestamp The timestamp of the vision measurement in seconds. Note that if you don't use * your own time source by calling {@link #updateWithTime}, then you must use a timestamp with - * an epoch since FPGA startup (i.e., the epoch of this timestamp is the same epoch as {@link - * org.wpilib.system.Timer#getFPGATimestamp()}). This means that you should use {@link - * org.wpilib.system.Timer#getFPGATimestamp()} as your time source in this case. + * the same epoch as {@link org.wpilib.system.Timer#getMonotonicTimestamp()}). This means that + * you should use {@link org.wpilib.system.Timer#getMonotonicTimestamp()} as your time source + * in this case. * @param visionMeasurementStdDevs Standard deviations of the vision pose measurement (x position * in meters, y position in meters, and heading in radians). Increase these numbers to trust * the vision pose measurement less. diff --git a/wpimath/src/main/java/org/wpilib/math/estimator/PoseEstimator3d.java b/wpimath/src/main/java/org/wpilib/math/estimator/PoseEstimator3d.java index 4442102f19..799a599003 100644 --- a/wpimath/src/main/java/org/wpilib/math/estimator/PoseEstimator3d.java +++ b/wpimath/src/main/java/org/wpilib/math/estimator/PoseEstimator3d.java @@ -283,9 +283,9 @@ public class PoseEstimator3d { * @param timestamp The timestamp of the vision measurement in seconds. Note that if you don't use * your own time source by calling {@link * PoseEstimator3d#updateWithTime(double,Rotation3d,Object)} then you must use a timestamp - * with an epoch since FPGA startup (i.e., the epoch of this timestamp is the same epoch as - * {@link org.wpilib.system.Timer#getFPGATimestamp()}.) This means that you should use {@link - * org.wpilib.system.Timer#getFPGATimestamp()} as your time source or sync the epochs. + * with the same epoch as {@link org.wpilib.system.Timer#getMonotonicTimestamp()}.) This means + * that you should use {@link org.wpilib.system.Timer#getMonotonicTimestamp()} as your time + * source or sync the epochs. */ public void addVisionMeasurement(Pose3d visionRobotPose, double timestamp) { // Step 0: If this measurement is old enough to be outside the pose buffer's timespan, skip. @@ -359,9 +359,9 @@ public class PoseEstimator3d { * @param visionRobotPose The pose of the robot as measured by the vision camera. * @param timestamp The timestamp of the vision measurement in seconds. Note that if you don't use * your own time source by calling {@link #updateWithTime}, then you must use a timestamp with - * an epoch since FPGA startup (i.e., the epoch of this timestamp is the same epoch as {@link - * org.wpilib.system.Timer#getFPGATimestamp()}). This means that you should use {@link - * org.wpilib.system.Timer#getFPGATimestamp()} as your time source in this case. + * the same epoch as {@link org.wpilib.system.Timer#getMonotonicTimestamp()}). This means that + * you should use {@link org.wpilib.system.Timer#getMonotonicTimestamp()} as your time source + * in this case. * @param visionMeasurementStdDevs Standard deviations of the vision pose measurement (x position * in meters, y position in meters, z position in meters, and angle in radians). Increase * these numbers to trust the vision pose measurement less. diff --git a/wpimath/src/main/native/include/wpi/math/estimator/PoseEstimator.hpp b/wpimath/src/main/native/include/wpi/math/estimator/PoseEstimator.hpp index 7207e26357..b822044257 100644 --- a/wpimath/src/main/native/include/wpi/math/estimator/PoseEstimator.hpp +++ b/wpimath/src/main/native/include/wpi/math/estimator/PoseEstimator.hpp @@ -280,10 +280,9 @@ class WPILIB_DLLEXPORT PoseEstimator { * camera. * @param timestamp The timestamp of the vision measurement in seconds. Note * that if you don't use your own time source by calling UpdateWithTime(), - * then you must use a timestamp with an epoch since FPGA startup (i.e., - * the epoch of this timestamp is the same epoch as - * wpi::math::Timer::GetTimestamp(). This means that you should use - * wpi::math::Timer::GetTimestamp() as your time source in this case. + * then you must use a timestamp with the same epoch as + * wpi::Timer::GetMonotonicTimestamp(). This means that you should use + * wpi::Timer::GetMonotonicTimestamp() as your time source in this case. */ void AddVisionMeasurement(const Pose2d& visionRobotPose, wpi::units::second_t timestamp) { @@ -365,10 +364,9 @@ class WPILIB_DLLEXPORT PoseEstimator { * camera. * @param timestamp The timestamp of the vision measurement in seconds. Note * that if you don't use your own time source by calling UpdateWithTime(), - * then you must use a timestamp with an epoch since FPGA startup (i.e., - * the epoch of this timestamp is the same epoch as - * wpi::math::Timer::GetTimestamp(). This means that you should use - * wpi::math::Timer::GetTimestamp() as your time source in this case. + * then you must use a timestamp with the same epoch as + * wpi::Timer::GetMonotonicTimestamp(). This means that you should use + * wpi::Timer::GetMonotonicTimestamp() as your time source in this case. * @param visionMeasurementStdDevs Standard deviations of the vision pose * measurement (x position in meters, y position in meters, and heading in * radians). Increase these numbers to trust the vision pose measurement diff --git a/wpimath/src/main/native/include/wpi/math/estimator/PoseEstimator3d.hpp b/wpimath/src/main/native/include/wpi/math/estimator/PoseEstimator3d.hpp index c8501e72aa..b16376656f 100644 --- a/wpimath/src/main/native/include/wpi/math/estimator/PoseEstimator3d.hpp +++ b/wpimath/src/main/native/include/wpi/math/estimator/PoseEstimator3d.hpp @@ -288,10 +288,9 @@ class WPILIB_DLLEXPORT PoseEstimator3d { * camera. * @param timestamp The timestamp of the vision measurement in seconds. Note * that if you don't use your own time source by calling UpdateWithTime(), - * then you must use a timestamp with an epoch since FPGA startup (i.e., - * the epoch of this timestamp is the same epoch as - * wpi::math::Timer::GetFPGATimestamp(). This means that you should use - * wpi::math::Timer::GetFPGATimestamp() as your time source in this case. + * then you must use a timestamp with the same epoch as + * wpi::Timer::GetMonotonicTimestamp(). This means that you should use + * wpi::Timer::GetMonotonicTimestamp() as your time source in this case. */ void AddVisionMeasurement(const Pose3d& visionRobotPose, wpi::units::second_t timestamp) { @@ -379,10 +378,9 @@ class WPILIB_DLLEXPORT PoseEstimator3d { * camera. * @param timestamp The timestamp of the vision measurement in seconds. Note * that if you don't use your own time source by calling UpdateWithTime(), - * then you must use a timestamp with an epoch since FPGA startup (i.e., - * the epoch of this timestamp is the same epoch as - * wpi::math::Timer::GetFPGATimestamp(). This means that you should use - * wpi::math::Timer::GetFPGATimestamp() as your time source in this case. + * then you must use a timestamp with the same epoch as + * wpi::Timer::GetMonotonicTimestamp(). This means that you should use + * wpi::Timer::GetMonotonicTimestamp() as your time source in this case. * @param visionMeasurementStdDevs Standard deviations of the vision pose * measurement (x position in meters, y position in meters, and heading in * radians). Increase these numbers to trust the vision pose measurement