[wpilib] Add timestamp getters with configurable time base (#7378)

This commit is contained in:
Jonah Bonner
2024-11-16 10:43:38 -05:00
committed by GitHub
parent 91142ba5fe
commit ca51197486
27 changed files with 180 additions and 53 deletions

View File

@@ -113,7 +113,7 @@ public class Alert implements AutoCloseable {
}
if (active) {
m_activeStartTime = RobotController.getFPGATime();
m_activeStartTime = RobotController.getTime();
m_activeAlerts.add(new PublishedAlert(m_activeStartTime, m_text));
} else {
m_activeAlerts.remove(new PublishedAlert(m_activeStartTime, m_text));

View File

@@ -1328,7 +1328,7 @@ public final class DriverStation {
* the DS.
*/
private static void reportJoystickUnpluggedError(String message) {
double currentTime = Timer.getFPGATimestamp();
double currentTime = Timer.getTimestamp();
if (currentTime > m_nextMessageTime) {
reportError(message, false);
m_nextMessageTime = currentTime + JOYSTICK_UNPLUGGED_MESSAGE_INTERVAL;
@@ -1341,7 +1341,7 @@ public final class DriverStation {
*/
private static void reportJoystickUnpluggedWarning(String message) {
if (isFMSAttached() || !m_silenceJoystickWarning) {
double currentTime = Timer.getFPGATimestamp();
double currentTime = Timer.getTimestamp();
if (currentTime > m_nextMessageTime) {
reportWarning(message, false);
m_nextMessageTime = currentTime + JOYSTICK_UNPLUGGED_MESSAGE_INTERVAL;

View File

@@ -191,7 +191,7 @@ public interface LEDPattern {
return (reader, writer) -> {
int bufLen = reader.getLength();
long now = WPIUtilJNI.now();
long now = RobotController.getTime();
// index should move by (buf.length) / (period)
double t = (now % (long) periodMicros) / periodMicros;
@@ -242,7 +242,7 @@ public interface LEDPattern {
return (reader, writer) -> {
int bufLen = reader.getLength();
long now = WPIUtilJNI.now();
long now = RobotController.getTime();
// every step in time that's a multiple of microsPerLED will increment the offset by 1
var offset = now / microsPerLED;
@@ -271,7 +271,7 @@ public interface LEDPattern {
final long onTimeMicros = (long) onTime.in(Microseconds);
return (reader, writer) -> {
if (WPIUtilJNI.now() % totalTimeMicros < onTimeMicros) {
if (RobotController.getTime() % totalTimeMicros < onTimeMicros) {
applyTo(reader, writer);
} else {
kOff.applyTo(reader, writer);
@@ -323,7 +323,7 @@ public interface LEDPattern {
reader,
(i, r, g, b) -> {
// How far we are in the cycle, in the range [0, 1)
double t = (WPIUtilJNI.now() % periodMicros) / (double) periodMicros;
double t = (RobotController.getTime() % periodMicros) / (double) periodMicros;
double phase = t * 2 * Math.PI;
// Apply the cosine function and shift its output from [-1, 1] to [0, 1]

View File

@@ -118,7 +118,7 @@ public abstract class RobotBase implements AutoCloseable {
@Override
public double getTimestamp() {
return WPIUtilJNI.now() * 1.0e-6;
return Timer.getTimestamp();
}
});
}

View File

@@ -19,9 +19,12 @@ import edu.wpi.first.units.measure.Current;
import edu.wpi.first.units.measure.Temperature;
import edu.wpi.first.units.measure.Time;
import edu.wpi.first.units.measure.Voltage;
import java.util.function.LongSupplier;
/** Contains functions for roboRIO functionality. */
public final class RobotController {
private static LongSupplier m_timeSource = RobotController::getFPGATime;
private RobotController() {
throw new UnsupportedOperationException("This is a utility class!");
}
@@ -76,6 +79,38 @@ public final class RobotController {
return HALUtil.getTeamNumber();
}
/**
* Sets a new source to provide the clock time in microseconds. Changing this affects the return
* value of {@code getTime} in Java.
*
* @param supplier Function to return the time in microseconds.
*/
public static void setTimeSource(LongSupplier supplier) {
m_timeSource = 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.
*
* @return The current time in microseconds.
*/
public static long getTime() {
return m_timeSource.getAsLong();
}
/**
* 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.
*
* @return The current time in a measure.
*/
public static Time getMeasureTime() {
return Microseconds.of(m_timeSource.getAsLong());
}
/**
* Read the microsecond timer from the FPGA.
*

View File

@@ -73,6 +73,7 @@ public class TimedRobot extends IterativeRobotBase {
private final int m_notifier = NotifierJNI.initializeNotifier();
private long m_startTimeUs;
private long m_loopStartTimeUs;
private final PriorityQueue<Callback> m_callbacks = new PriorityQueue<>();
@@ -128,6 +129,8 @@ public class TimedRobot extends IterativeRobotBase {
break;
}
m_loopStartTimeUs = RobotController.getFPGATime();
callback.func.run();
// Increment the expiration time by the number of full periods it's behind
@@ -159,6 +162,17 @@ public class TimedRobot extends IterativeRobotBase {
NotifierJNI.stopNotifier(m_notifier);
}
/**
* 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).
*
* @return Robot running time in microseconds, as of the start of the current periodic function.
*/
public long getLoopStartTime() {
return m_loopStartTimeUs;
}
/**
* Add a callback to run at a specific period.
*

View File

@@ -11,6 +11,17 @@ package edu.wpi.first.wpilibj;
* get() won't return a negative duration.
*/
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 Robot running time in seconds.
*/
public static double getTimestamp() {
return RobotController.getTime() / 1000000.0;
}
/**
* Return the system clock time in seconds. Return the time from the FPGA hardware clock in
* seconds since the FPGA started.
@@ -60,7 +71,7 @@ public class Timer {
}
private double getMsClock() {
return RobotController.getFPGATime() / 1000.0;
return RobotController.getTime() / 1000.0;
}
/**

View File

@@ -43,10 +43,10 @@ import edu.wpi.first.networktables.StringSubscriber;
import edu.wpi.first.networktables.StringTopic;
import edu.wpi.first.networktables.Subscriber;
import edu.wpi.first.networktables.Topic;
import edu.wpi.first.util.WPIUtilJNI;
import edu.wpi.first.util.function.BooleanConsumer;
import edu.wpi.first.util.function.FloatConsumer;
import edu.wpi.first.util.function.FloatSupplier;
import edu.wpi.first.wpilibj.RobotController;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BooleanSupplier;
@@ -180,7 +180,7 @@ public class SendableBuilderImpl implements NTSendableBuilder {
/** Update the network table values by calling the getters for all properties. */
@Override
public void update() {
long time = WPIUtilJNI.now();
long time = RobotController.getTime();
for (Property<?, ?> property : m_properties) {
property.update(m_controllable, time);
}