mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
committed by
Peter Johnson
parent
761bc3ef85
commit
7112add67f
@@ -27,8 +27,8 @@ IterativeRobotBase::IterativeRobotBase(double period)
|
||||
: IterativeRobotBase(units::second_t(period)) {}
|
||||
|
||||
IterativeRobotBase::IterativeRobotBase(units::second_t period)
|
||||
: m_period(period.to<double>()),
|
||||
m_watchdog(period.to<double>(), [this] { PrintLoopOverrunMessage(); }) {}
|
||||
: m_period(period),
|
||||
m_watchdog(period, [this] { PrintLoopOverrunMessage(); }) {}
|
||||
|
||||
void IterativeRobotBase::RobotInit() {
|
||||
wpi::outs() << "Default " << __FUNCTION__ << "() method... Override me!\n";
|
||||
@@ -174,7 +174,8 @@ void IterativeRobotBase::PrintLoopOverrunMessage() {
|
||||
wpi::SmallString<128> str;
|
||||
wpi::raw_svector_ostream buf(str);
|
||||
|
||||
buf << "Loop time of " << wpi::format("%.6f", m_period) << "s overrun\n";
|
||||
buf << "Loop time of " << wpi::format("%.6f", m_period.to<double>())
|
||||
<< "s overrun\n";
|
||||
|
||||
DriverStation::ReportWarning(str);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ void TimedRobot::StartCompetition() {
|
||||
// Tell the DS that the robot is ready to be enabled
|
||||
HAL_ObserveUserProgramStarting();
|
||||
|
||||
m_expirationTime = Timer::GetFPGATimestamp() + m_period;
|
||||
m_expirationTime = units::second_t{Timer::GetFPGATimestamp()} + m_period;
|
||||
UpdateAlarm();
|
||||
|
||||
// Loop forever, calling the appropriate mode-dependent function
|
||||
|
||||
@@ -54,7 +54,7 @@ void Watchdog::Thread::Main() {
|
||||
if (!watchdog->m_suppressTimeoutMessage) {
|
||||
wpi::outs() << "Watchdog not fed within "
|
||||
<< wpi::format("%.6f",
|
||||
watchdog->m_timeout.count() / 1.0e6)
|
||||
watchdog->m_timeout.count() / 1.0e9)
|
||||
<< "s\n";
|
||||
}
|
||||
}
|
||||
@@ -78,9 +78,10 @@ void Watchdog::Thread::Main() {
|
||||
}
|
||||
|
||||
Watchdog::Watchdog(double timeout, std::function<void()> callback)
|
||||
: m_timeout(static_cast<int64_t>(timeout * 1.0e6)),
|
||||
m_callback(callback),
|
||||
m_owner(&GetThreadOwner()) {}
|
||||
: Watchdog(units::second_t{timeout}, callback) {}
|
||||
|
||||
Watchdog::Watchdog(units::second_t timeout, std::function<void()> callback)
|
||||
: m_timeout(timeout), m_callback(callback), m_owner(&GetThreadOwner()) {}
|
||||
|
||||
Watchdog::~Watchdog() { Disable(); }
|
||||
|
||||
@@ -89,6 +90,13 @@ double Watchdog::GetTime() const {
|
||||
}
|
||||
|
||||
void Watchdog::SetTimeout(double timeout) {
|
||||
SetTimeout(units::second_t{timeout});
|
||||
}
|
||||
|
||||
void Watchdog::SetTimeout(units::second_t timeout) {
|
||||
using std::chrono::duration_cast;
|
||||
using std::chrono::microseconds;
|
||||
|
||||
m_startTime = hal::fpga_clock::now();
|
||||
m_epochs.clear();
|
||||
|
||||
@@ -96,11 +104,11 @@ void Watchdog::SetTimeout(double timeout) {
|
||||
auto thr = m_owner->GetThread();
|
||||
if (!thr) return;
|
||||
|
||||
m_timeout = std::chrono::microseconds(static_cast<int64_t>(timeout * 1.0e6));
|
||||
m_timeout = timeout;
|
||||
m_isExpired = false;
|
||||
|
||||
thr->m_watchdogs.remove(this);
|
||||
m_expirationTime = m_startTime + m_timeout;
|
||||
m_expirationTime = m_startTime + duration_cast<microseconds>(m_timeout);
|
||||
thr->m_watchdogs.emplace(this);
|
||||
thr->m_cond.notify_all();
|
||||
}
|
||||
@@ -109,7 +117,7 @@ double Watchdog::GetTimeout() const {
|
||||
// Locks mutex
|
||||
auto thr = m_owner->GetThread();
|
||||
|
||||
return m_timeout.count() / 1.0e6;
|
||||
return m_timeout.count() / 1.0e9;
|
||||
}
|
||||
|
||||
bool Watchdog::IsExpired() const {
|
||||
@@ -140,6 +148,9 @@ void Watchdog::PrintEpochs() {
|
||||
void Watchdog::Reset() { Enable(); }
|
||||
|
||||
void Watchdog::Enable() {
|
||||
using std::chrono::duration_cast;
|
||||
using std::chrono::microseconds;
|
||||
|
||||
m_startTime = hal::fpga_clock::now();
|
||||
m_epochs.clear();
|
||||
|
||||
@@ -150,7 +161,7 @@ void Watchdog::Enable() {
|
||||
m_isExpired = false;
|
||||
|
||||
thr->m_watchdogs.remove(this);
|
||||
m_expirationTime = m_startTime + m_timeout;
|
||||
m_expirationTime = m_startTime + duration_cast<microseconds>(m_timeout);
|
||||
thr->m_watchdogs.emplace(this);
|
||||
thr->m_cond.notify_all();
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ class IterativeRobotBase : public RobotBase {
|
||||
|
||||
void LoopFunc();
|
||||
|
||||
double m_period;
|
||||
units::second_t m_period;
|
||||
|
||||
private:
|
||||
enum class Mode { kNone, kDisabled, kAutonomous, kTeleop, kTest };
|
||||
|
||||
@@ -63,7 +63,7 @@ class TimedRobot : public IterativeRobotBase, public ErrorBase {
|
||||
hal::Handle<HAL_NotifierHandle> m_notifier;
|
||||
|
||||
// The absolute expiration time
|
||||
double m_expirationTime = 0;
|
||||
units::second_t m_expirationTime{0};
|
||||
|
||||
/**
|
||||
* Update the HAL alarm time.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2018 FIRST. All Rights Reserved. */
|
||||
/* Copyright (c) 2018-2019 FIRST. 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 the root directory of */
|
||||
/* the project. */
|
||||
@@ -12,9 +12,11 @@
|
||||
#include <utility>
|
||||
|
||||
#include <hal/cpp/fpga_clock.h>
|
||||
#include <units/units.h>
|
||||
#include <wpi/SafeThread.h>
|
||||
#include <wpi/StringMap.h>
|
||||
#include <wpi/StringRef.h>
|
||||
#include <wpi/deprecated.h>
|
||||
|
||||
namespace frc {
|
||||
|
||||
@@ -36,10 +38,25 @@ class Watchdog {
|
||||
* resolution.
|
||||
* @param callback This function is called when the timeout expires.
|
||||
*/
|
||||
WPI_DEPRECATED("Use unit-safe version instead")
|
||||
Watchdog(double timeout, std::function<void()> callback);
|
||||
|
||||
/**
|
||||
* Watchdog constructor.
|
||||
*
|
||||
* @param timeout The watchdog's timeout in seconds with microsecond
|
||||
* resolution.
|
||||
* @param callback This function is called when the timeout expires.
|
||||
*/
|
||||
Watchdog(units::second_t timeout, std::function<void()> callback);
|
||||
|
||||
template <typename Callable, typename Arg, typename... Args>
|
||||
WPI_DEPRECATED("Use unit-safe version instead")
|
||||
Watchdog(double timeout, Callable&& f, Arg&& arg, Args&&... args)
|
||||
: Watchdog(units::second_t{timeout}, arg, args...) {}
|
||||
|
||||
template <typename Callable, typename Arg, typename... Args>
|
||||
Watchdog(units::second_t timeout, Callable&& f, Arg&& arg, Args&&... args)
|
||||
: Watchdog(timeout,
|
||||
std::bind(std::forward<Callable>(f), std::forward<Arg>(arg),
|
||||
std::forward<Args>(args)...)) {}
|
||||
@@ -60,8 +77,17 @@ class Watchdog {
|
||||
* @param timeout The watchdog's timeout in seconds with microsecond
|
||||
* resolution.
|
||||
*/
|
||||
WPI_DEPRECATED("Use unit-safe version instead")
|
||||
void SetTimeout(double timeout);
|
||||
|
||||
/**
|
||||
* Sets the watchdog's timeout.
|
||||
*
|
||||
* @param timeout The watchdog's timeout in seconds with microsecond
|
||||
* resolution.
|
||||
*/
|
||||
void SetTimeout(units::second_t timeout);
|
||||
|
||||
/**
|
||||
* Returns the watchdog's timeout in seconds.
|
||||
*/
|
||||
@@ -119,13 +145,13 @@ class Watchdog {
|
||||
static constexpr std::chrono::milliseconds kMinPrintPeriod{1000};
|
||||
|
||||
hal::fpga_clock::time_point m_startTime;
|
||||
std::chrono::microseconds m_timeout;
|
||||
std::chrono::nanoseconds m_timeout;
|
||||
hal::fpga_clock::time_point m_expirationTime;
|
||||
std::function<void()> m_callback;
|
||||
hal::fpga_clock::time_point m_lastTimeoutPrintTime = hal::fpga_clock::epoch();
|
||||
hal::fpga_clock::time_point m_lastEpochsPrintTime = hal::fpga_clock::epoch();
|
||||
|
||||
wpi::StringMap<std::chrono::microseconds> m_epochs;
|
||||
wpi::StringMap<std::chrono::nanoseconds> m_epochs;
|
||||
bool m_isExpired = false;
|
||||
|
||||
bool m_suppressTimeoutMessage = false;
|
||||
|
||||
@@ -24,7 +24,7 @@ TEST(WatchdogTest, EnableDisable) {
|
||||
#endif
|
||||
uint32_t watchdogCounter = 0;
|
||||
|
||||
Watchdog watchdog(0.4, [&] { watchdogCounter++; });
|
||||
Watchdog watchdog(0.4_s, [&] { watchdogCounter++; });
|
||||
|
||||
wpi::outs() << "Run 1\n";
|
||||
watchdog.Enable();
|
||||
@@ -59,7 +59,7 @@ TEST(WatchdogTest, Reset) {
|
||||
#endif
|
||||
uint32_t watchdogCounter = 0;
|
||||
|
||||
Watchdog watchdog(0.4, [&] { watchdogCounter++; });
|
||||
Watchdog watchdog(0.4_s, [&] { watchdogCounter++; });
|
||||
|
||||
watchdog.Enable();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
@@ -77,11 +77,11 @@ TEST(WatchdogTest, SetTimeout) {
|
||||
#endif
|
||||
uint32_t watchdogCounter = 0;
|
||||
|
||||
Watchdog watchdog(1.0, [&] { watchdogCounter++; });
|
||||
Watchdog watchdog(1.0_s, [&] { watchdogCounter++; });
|
||||
|
||||
watchdog.Enable();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
watchdog.SetTimeout(0.2);
|
||||
watchdog.SetTimeout(0.2_s);
|
||||
|
||||
EXPECT_EQ(0.2, watchdog.GetTimeout());
|
||||
EXPECT_EQ(0u, watchdogCounter) << "Watchdog triggered early";
|
||||
@@ -98,7 +98,7 @@ TEST(WatchdogTest, DISABLED_IsExpired) {
|
||||
#else
|
||||
TEST(WatchdogTest, IsExpired) {
|
||||
#endif
|
||||
Watchdog watchdog(0.2, [] {});
|
||||
Watchdog watchdog(0.2_s, [] {});
|
||||
EXPECT_FALSE(watchdog.IsExpired());
|
||||
watchdog.Enable();
|
||||
|
||||
@@ -120,7 +120,7 @@ TEST(WatchdogTest, Epochs) {
|
||||
#endif
|
||||
uint32_t watchdogCounter = 0;
|
||||
|
||||
Watchdog watchdog(0.4, [&] { watchdogCounter++; });
|
||||
Watchdog watchdog(0.4_s, [&] { watchdogCounter++; });
|
||||
|
||||
wpi::outs() << "Run 1\n";
|
||||
watchdog.Enable();
|
||||
@@ -153,8 +153,8 @@ TEST(WatchdogTest, MultiWatchdog) {
|
||||
uint32_t watchdogCounter1 = 0;
|
||||
uint32_t watchdogCounter2 = 0;
|
||||
|
||||
Watchdog watchdog1(0.2, [&] { watchdogCounter1++; });
|
||||
Watchdog watchdog2(0.6, [&] { watchdogCounter2++; });
|
||||
Watchdog watchdog1(0.2_s, [&] { watchdogCounter1++; });
|
||||
Watchdog watchdog2(0.6_s, [&] { watchdogCounter2++; });
|
||||
|
||||
watchdog2.Enable();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
|
||||
Reference in New Issue
Block a user