[hal] Merge WaitForCachedData into WaitForDSData (#2587)

Remove WaitForCachedData as it's no longer required.

Also properly handle caching / transition detection logic that occurs at the
WPILib level.

This also changes DriverStation::IsNewControlData() to check for WPILib-level
caching instead of wrapping the HAL function.
This commit is contained in:
Peter Johnson
2020-07-13 21:57:54 -07:00
committed by GitHub
parent f0a34ea64e
commit 16ef372b53
6 changed files with 86 additions and 120 deletions

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2019 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2020 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. */
@@ -68,6 +68,15 @@ using namespace frc;
static constexpr double kJoystickUnpluggedMessageInterval = 1.0;
static int& GetDSLastCount() {
// There is a rollover error condition here. At Packet# = n * (uintmax), this
// will return false when instead it should return true. However, this at a
// 20ms rate occurs once every 2.7 years of DS connected runtime, so not
// worth the cycles to check.
thread_local int lastCount{0};
return lastCount;
}
DriverStation::~DriverStation() {
m_isRunning = false;
// Trigger a DS mutex release in case there is no driver station running.
@@ -367,7 +376,14 @@ bool DriverStation::IsDSAttached() const {
return controlWord.dsAttached;
}
bool DriverStation::IsNewControlData() const { return HAL_IsNewControlData(); }
bool DriverStation::IsNewControlData() const {
std::unique_lock lock(m_waitForDataMutex);
int& lastCount = GetDSLastCount();
int currentCount = m_waitForDataCounter;
if (lastCount == currentCount) return false;
lastCount = currentCount;
return true;
}
bool DriverStation::IsFMSAttached() const {
HAL_ControlWord controlWord;
@@ -448,7 +464,12 @@ bool DriverStation::WaitForData(double timeout) {
std::chrono::steady_clock::now() + std::chrono::duration<double>(timeout);
std::unique_lock lock(m_waitForDataMutex);
int& lastCount = GetDSLastCount();
int currentCount = m_waitForDataCounter;
if (lastCount != currentCount) {
lastCount = currentCount;
return true;
}
while (m_waitForDataCounter == currentCount) {
if (timeout > 0) {
auto timedOut = m_waitForDataCond.wait_until(lock, timeoutTime);
@@ -459,6 +480,7 @@ bool DriverStation::WaitForData(double timeout) {
m_waitForDataCond.wait(lock);
}
}
lastCount = m_waitForDataCounter;
return true;
}

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2019 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2020 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. */
@@ -313,6 +313,9 @@ class DriverStation : public ErrorBase {
*
* This is a good way to delay processing until there is new driver station
* data to act on.
*
* Checks if new control data has arrived since the last waitForData call
* on the current thread. If new data has not arrived, returns immediately.
*/
void WaitForData();
@@ -320,6 +323,9 @@ class DriverStation : public ErrorBase {
* Wait until a new packet comes from the driver station, or wait for a
* timeout.
*
* Checks if new control data has arrived since the last waitForData call
* on the current thread. If new data has not arrived, returns immediately.
*
* If the timeout is less then or equal to 0, wait indefinitely.
*
* Timeout is in milliseconds
@@ -446,7 +452,7 @@ class DriverStation : public ErrorBase {
std::thread m_dsThread;
std::atomic<bool> m_isRunning{false};
wpi::mutex m_waitForDataMutex;
mutable wpi::mutex m_waitForDataMutex;
wpi::condition_variable m_waitForDataCond;
int m_waitForDataCounter;