Class QuestNav
This class handles all aspects of Quest-robot communication including:
- Real-time pose tracking and localization data
- Command sending and response handling
- Device status monitoring (battery, tracking state, connectivity)
- NetworkTables-based communication protocol
- Event-driven callbacks for connection, tracking, battery, and command state changes
Basic Usage
// Create QuestNav instance
QuestNav questNav = new QuestNav();
// Register callbacks
questNav.onConnected(() -> System.out.println("Quest connected!"));
questNav.onDisconnected(() -> DriverStation.reportWarning("Quest disconnected!", false));
questNav.onTrackingLost(() -> DriverStation.reportWarning("Quest tracking lost!", false));
questNav.onTrackingAcquired(() -> System.out.println("Quest tracking acquired!"));
questNav.onLowBattery(20, level -> DriverStation.reportWarning("Quest battery low: " + level + "%", false));
// Set initial robot pose (required for field-relative tracking)
Pose2d initialPose = new Pose2d(1.0, 2.0, Rotation2d.fromDegrees(90));
questNav.setPose(initialPose);
// In robot periodic methods
public void robotPeriodic() {
questNav.commandPeriodic(); // Process command responses and fire callbacks
// Get latest pose data
PoseFrame[] newFrames = questNav.getAllUnreadPoseFrames();
for (PoseFrame frame : newFrames) {
// Use frame.questPose() and frame.dataTimestamp() with pose estimator
}
}
Coordinate Systems
QuestNav uses the WPILib field coordinate system:
- X-axis: Forward direction (towards opposing alliance)
- Y-axis: Left direction (when facing forward)
- Rotation: Counter-clockwise positive (standard mathematical convention)
- Units: Meters for translation, radians for rotation
Threading and Performance
This class is designed for use in FRC robot code and follows WPILib threading conventions:
- All methods are thread-safe for typical FRC usage patterns
- Uses cached objects to minimize garbage collection pressure
- NetworkTables handles the underlying communication asynchronously
- Call
commandPeriodic()regularly to process command responses and fire callbacks
Error Handling
The class provides robust error handling:
- Methods return
Optionaltypes when data might not be available - Connection status can be checked with
isConnected() - Tracking status can be monitored with
isTracking() - Command failures are reported through DriverStation error logging and via
onCommandFailure(Consumer)
- Since:
- 2025.1.0
- See Also:
-
PoseFramePose2dNetworkTableInstance
-
Constructor Summary
ConstructorsConstructorDescriptionQuestNav()Creates a new QuestNav instance for communicating with a Quest headset. -
Method Summary
Modifier and TypeMethodDescriptionvoidProcesses command responses from the Quest headset, fires command success/failure callbacks, and evaluates connection, tracking, and battery state callbacks.Retrieves all new pose frames received from the Quest since the last call to this method.Returns the Quest app's uptime timestamp for debugging and diagnostics.Returns the Quest headset's current battery level as a percentage.Gets the current frame count from the Quest headset.doubleGets the latency of the Quest > Robot Connection.Retrieves the QuestNav-lib version number.Retrieves the QuestNav app version running on the Quest headset.Gets the number of tracking lost events since the Quest connected to the robot.booleanDetermines if the Quest headset is currently connected to the robot.booleanGets the current tracking state of the Quest headset.voidonCommandFailure(Consumer<gg.questnav.questnav.protos.generated.Commands.ProtobufQuestNavCommandResponse> callback) Registers a callback that fires for each command response where the command failed.voidonCommandSuccess(Consumer<gg.questnav.questnav.protos.generated.Commands.ProtobufQuestNavCommandResponse> callback) Registers a callback that fires for each command response where the command succeeded.voidonConnected(Runnable callback) Registers a callback that fires once when the Quest headset transitions from disconnected to connected.voidonDisconnected(Runnable callback) Registers a callback that fires once when the Quest headset transitions from connected to disconnected.voidonLowBattery(int thresholdPercent, IntConsumer callback) Registers a callback that fires once when the Quest battery level drops at or below the given threshold.voidonTrackingAcquired(Runnable callback) Registers a callback that fires once when the Quest headset transitions from not-tracking to actively tracking.voidonTrackingLost(Runnable callback) Registers a callback that fires once when the Quest headset transitions from actively tracking to not-tracking.voidsetPose(edu.wpi.first.math.geometry.Pose3d pose) Sets the field-relative pose of the Quest headset by commanding it to reset its tracking.voidsetVersionCheckEnabled(boolean enabled) Turns the version check on or off.
-
Constructor Details
-
QuestNav
public QuestNav()Creates a new QuestNav instance for communicating with a Quest headset.This constructor initializes all necessary NetworkTables subscribers and publishers for communication with the Quest device. The instance is ready to use immediately, but you should call
setPose(Pose3d)to establish field-relative tracking before relying on pose data.The constructor sets up:
- NetworkTables communication on the "QuestNav" table
- Protobuf serialization for efficient data transfer
- Cached objects to minimize garbage collection
- Subscribers for frame data, device data, and command responses
- Publisher for sending commands to the Quest
-
-
Method Details
-
onConnected
Registers a callback that fires once when the Quest headset transitions from disconnected to connected. The callback is evaluated eachcommandPeriodic()call.- Parameters:
callback- Runnable to invoke on connection
-
onDisconnected
Registers a callback that fires once when the Quest headset transitions from connected to disconnected. The callback is evaluated eachcommandPeriodic()call.- Parameters:
callback- Runnable to invoke on disconnection
-
onTrackingAcquired
Registers a callback that fires once when the Quest headset transitions from not-tracking to actively tracking. The callback is evaluated eachcommandPeriodic()call.- Parameters:
callback- Runnable to invoke when tracking is acquired
-
onTrackingLost
Registers a callback that fires once when the Quest headset transitions from actively tracking to not-tracking. The callback is evaluated eachcommandPeriodic()call.- Parameters:
callback- Runnable to invoke when tracking is lost
-
onLowBattery
Registers a callback that fires once when the Quest battery level drops at or below the given threshold. The callback will not fire again until the battery rises above the threshold and drops back down.- Parameters:
thresholdPercent- Battery percentage (0–100) at or below which the callback firescallback- IntConsumer receiving the current battery percentage when the threshold is crossed
-
onCommandSuccess
public void onCommandSuccess(Consumer<gg.questnav.questnav.protos.generated.Commands.ProtobufQuestNavCommandResponse> callback) Registers a callback that fires for each command response where the command succeeded. Called fromcommandPeriodic().- Parameters:
callback- Consumer receiving the rawCommands.ProtobufQuestNavCommandResponse
-
onCommandFailure
public void onCommandFailure(Consumer<gg.questnav.questnav.protos.generated.Commands.ProtobufQuestNavCommandResponse> callback) Registers a callback that fires for each command response where the command failed. Called fromcommandPeriodic(). The failure is also reported to the DriverStation regardless of whether a callback is registered.- Parameters:
callback- Consumer receiving the rawCommands.ProtobufQuestNavCommandResponse
-
setVersionCheckEnabled
public void setVersionCheckEnabled(boolean enabled) Turns the version check on or off. When on, a warning will be reported to the DriverStation if the QuestNavLib and QuestNav app versions do not match.- Parameters:
enabled- true to enable version checking, false to disable it. Default is true.
-
setPose
public void setPose(edu.wpi.first.math.geometry.Pose3d pose) Sets the field-relative pose of the Quest headset by commanding it to reset its tracking.This method sends a pose reset command to the Quest headset, telling it where the Quest is currently located on the field. This is essential for establishing field-relative tracking and should be called:
- At the start of autonomous or teleop when the Quest position is known
- When the robot (and Quest) is placed at a known location (e.g., against field walls)
- After significant tracking drift is detected
- When integrating with other localization systems (vision, odometry)
Important: This should be the Quest's pose, not the robot's pose. If you know the robot's pose, you need to apply the mounting offset to get the Quest's pose before calling this method.
The command is sent asynchronously. Success or failure is reported via
onCommandSuccess(Consumer)andonCommandFailure(Consumer)respectively, and failures are also logged to the DriverStation.Usage Example:
// Set Quest pose at autonomous start (if you know the Quest's position directly) Pose3d questPose = new Pose3d(1.5, 5.5, new Rotation3d(0.0, 0.0, 0.0))); questNav.setPose(questPose); // If you know the robot pose, apply mounting offset to get Quest pose Pose2d robotPose = poseEstimator.getEstimatedPosition(); Pose3d questPose = new Pose3d(robotPose).transformBy(mountingOffset); questNav.setPose(questPose);- Parameters:
pose- The Quest's current field-relative pose in WPILib coordinates (meters for translation, radians for rotation)- Throws:
IllegalArgumentException- if pose contains NaN or infinite values- See Also:
-
getBatteryPercent
Returns the Quest headset's current battery level as a percentage.Battery level guidelines:
- 80-100%: Excellent - full match capability
- 50-80%: Good - normal operation expected
- 20-50%: Fair - consider charging after match
- 10-20%: Low - charge soon, monitor closely
- 0-10%: Critical - immediate charging required
- Returns:
- An
OptionalIntcontaining the battery percentage (0-100), or empty if no device data is available or Quest is disconnected - See Also:
-
getFrameCount
Gets the current frame count from the Quest headset.- Returns:
- The frame count value, or empty if no frame data is available
-
getTrackingLostCounter
Gets the number of tracking lost events since the Quest connected to the robot.- Returns:
- The tracking lost counter value, or empty if no device data is available
-
isConnected
public boolean isConnected()Determines if the Quest headset is currently connected to the robot. Connection is determined by how stale the last received frame from the Quest is.- Returns:
- Boolean indicating if the Quest is connected (true) or not (false)
-
getLatency
public double getLatency()Gets the latency of the Quest > Robot Connection. Returns the latency between the current time and the last frame data update.- Returns:
- The latency in milliseconds
-
getAppTimestamp
Returns the Quest app's uptime timestamp for debugging and diagnostics.Important: For integration with a pose estimator, use the timestamp from
PoseFrame.dataTimestamp()instead.- Returns:
- An
OptionalDoublecontaining the Quest app uptime in seconds, or empty if no frame data is available - See Also:
-
isTracking
public boolean isTracking()Gets the current tracking state of the Quest headset.Important: When tracking is lost, pose data becomes unreliable and should not be used for robot control. Implement fallback localization methods (wheel odometry, vision, etc.) for when Quest tracking is unavailable.
- Returns:
trueif the Quest is actively tracking and pose data is reliable,falseif tracking is lost or no device data is available- See Also:
-
getAllUnreadPoseFrames
Retrieves all new pose frames received from the Quest since the last call to this method.This is the primary method for integrating QuestNav with FRC pose estimation systems. It returns an array of
PoseFrameobjects containing pose data and timestamps that can be fed directly into aPoseEstimator.Important: This method consumes the frame queue, so each frame is only returned once. Call this method regularly (every robot loop) to avoid missing frames.
Integration with Pose Estimator:
PoseFrame[] newFrames = questNav.getAllUnreadPoseFrames(); for (PoseFrame frame : newFrames) { if (questNav.isTracking() && questNav.isConnected()) { poseEstimator.addVisionMeasurement( frame.questPose(), frame.dataTimestamp(), VecBuilder.fill(0.1, 0.1, 0.05) ); } }- Returns:
- Array of new
PoseFrameobjects received since the last call. Empty array if no new frames are available or Quest is disconnected. - See Also:
-
commandPeriodic
public void commandPeriodic()Processes command responses from the Quest headset, fires command success/failure callbacks, and evaluates connection, tracking, and battery state callbacks.This method must be called regularly (typically in
robotPeriodic()) to:- Process responses to commands sent via
setPose(Pose3d) - Fire
onCommandSuccess(Consumer)andonCommandFailure(Consumer)callbacks - Detect and fire connection state change callbacks (
onConnected(Runnable),onDisconnected(Runnable)) - Detect and fire tracking state change callbacks (
onTrackingAcquired(Runnable),onTrackingLost(Runnable)) - Evaluate low battery threshold and fire
onLowBattery(int, IntConsumer)callback - Log command failures to the DriverStation
- Prevent command response queue overflow
Usage Pattern:
public class Robot extends TimedRobot { private QuestNav questNav = new QuestNav(); @Override public void robotPeriodic() { questNav.commandPeriodic(); // Call every loop } } - Process responses to commands sent via
-
getLibVersion
Retrieves the QuestNav-lib version number.- Returns:
- The version number as a String.
-