Class PhoenixOdometryThread
- All Implemented Interfaces:
Runnable
This thread is primarily intended to reduce latency and aliasing when collecting drivetrain sensor data (e.g., wheel encoders, gyro rates) used for odometry and state estimation.
Two categories of signals may be registered:
- Phoenix signals -
StatusSignalinstances that can be synchronized and timestamped by the CTRE Phoenix framework - Generic signals - arbitrary
DoubleSuppliers sampled at the same rate as Phoenix signals
Each registered signal is associated with a thread-safe Queue into which samples are
pushed. Consumers are expected to poll these queues from the main loop while holding the provided
odometry lock.
If running on a CAN-FD network, Phoenix signals are synchronized using
BaseStatusSignal.waitForAll(double, BaseStatusSignal...), allowing all signals to be
sampled at nearly the same timestamp. On non-CAN-FD networks, the thread sleeps for the
configured odometry period and explicitly refreshes signals.
The thread runs as a daemon and will terminate automatically when the JVM exits.
-
Nested Class Summary
Nested classes/interfaces inherited from class java.lang.Thread
Thread.State, Thread.UncaughtExceptionHandler -
Field Summary
Fields inherited from class java.lang.Thread
MAX_PRIORITY, MIN_PRIORITY, NORM_PRIORITY -
Constructor Summary
ConstructorsConstructorDescriptionPhoenixOdometryThread(Lock odometryLock) Creates a new odometry sampling thread. -
Method Summary
Modifier and TypeMethodDescriptionCreates a queue that receives timestamps corresponding to each sampling cycle.registerSignal(com.ctre.phoenix6.StatusSignal<?> signal) Registers a PhoenixStatusSignalto be sampled by the thread.registerSignal(DoubleSupplier signal) Registers a generic value supplier to be sampled at the odometry rate.voidrun()Main sampling loop.voidstart()Starts the thread if at least one signal has been registered.Methods inherited from class java.lang.Thread
activeCount, checkAccess, clone, countStackFrames, currentThread, dumpStack, enumerate, getAllStackTraces, getContextClassLoader, getDefaultUncaughtExceptionHandler, getId, getName, getPriority, getStackTrace, getState, getThreadGroup, getUncaughtExceptionHandler, holdsLock, interrupt, interrupted, isAlive, isDaemon, isInterrupted, join, join, join, onSpinWait, resume, setContextClassLoader, setDaemon, setDefaultUncaughtExceptionHandler, setName, setPriority, setUncaughtExceptionHandler, sleep, sleep, stop, suspend, toString, yield
-
Constructor Details
-
PhoenixOdometryThread
Creates a new odometry sampling thread.- Parameters:
odometryLock- lock shared with consumers to ensure that sampled values and timestamps are read atomically
-
-
Method Details
-
start
public void start()Starts the thread if at least one signal has been registered.This prevents spawning an idle background thread when no signals are being sampled.
-
registerSignal
Registers a PhoenixStatusSignalto be sampled by the thread.The returned queue will receive one value per odometry tick.
This method is thread-safe and may be called before the thread starts.
- Parameters:
signal- Phoenix status signal to sample- Returns:
- queue containing sampled signal values
-
registerSignal
Registers a generic value supplier to be sampled at the odometry rate.This is useful for signals not managed by Phoenix (e.g., WPILib sensors or computed values).
- Parameters:
signal- supplier producing the value to sample- Returns:
- queue containing sampled values
-
makeTimestampQueue
Creates a queue that receives timestamps corresponding to each sampling cycle.The timestamp represents FPGA time in seconds, adjusted for average Phoenix signal latency when applicable.
- Returns:
- queue of sample timestamps (seconds)
-
run
public void run()Main sampling loop.The thread runs indefinitely, sampling all registered signals at
Constants.Swerve.odometryFrequency.Sampling behavior differs depending on CAN capabilities:
- CAN-FD: waits for all Phoenix signals to update together
- Non-CAN-FD: sleeps for the target period and manually refreshes
All sampled values and timestamps are enqueued atomically under the odometry lock to ensure consistency for consumers.
-