Class QuestNav

java.lang.Object
gg.questnav.questnav.QuestNav

public class QuestNav extends Object
The QuestNav class provides a comprehensive interface for communicating with an Oculus/Meta Quest VR headset for robot localization and tracking in FRC robotics applications.

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:

Since:
2025.1.0
See Also:
  • Constructor Summary

    Constructors
    Constructor
    Description
    Creates a new QuestNav instance for communicating with a Quest headset.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    Processes 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.
    double
    Gets 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.
    boolean
    Determines if the Quest headset is currently connected to the robot.
    boolean
    Gets the current tracking state of the Quest headset.
    void
    onCommandFailure(Consumer<gg.questnav.questnav.protos.generated.Commands.ProtobufQuestNavCommandResponse> callback)
    Registers a callback that fires for each command response where the command failed.
    void
    onCommandSuccess(Consumer<gg.questnav.questnav.protos.generated.Commands.ProtobufQuestNavCommandResponse> callback)
    Registers a callback that fires for each command response where the command succeeded.
    void
    Registers a callback that fires once when the Quest headset transitions from disconnected to connected.
    void
    Registers a callback that fires once when the Quest headset transitions from connected to disconnected.
    void
    onLowBattery(int thresholdPercent, IntConsumer callback)
    Registers a callback that fires once when the Quest battery level drops at or below the given threshold.
    void
    Registers a callback that fires once when the Quest headset transitions from not-tracking to actively tracking.
    void
    Registers a callback that fires once when the Quest headset transitions from actively tracking to not-tracking.
    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.
    void
    setVersionCheckEnabled(boolean enabled)
    Turns the version check on or off.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • 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

      public void onConnected(Runnable callback)
      Registers a callback that fires once when the Quest headset transitions from disconnected to connected. The callback is evaluated each commandPeriodic() call.
      Parameters:
      callback - Runnable to invoke on connection
    • onDisconnected

      public void onDisconnected(Runnable callback)
      Registers a callback that fires once when the Quest headset transitions from connected to disconnected. The callback is evaluated each commandPeriodic() call.
      Parameters:
      callback - Runnable to invoke on disconnection
    • onTrackingAcquired

      public void onTrackingAcquired(Runnable callback)
      Registers a callback that fires once when the Quest headset transitions from not-tracking to actively tracking. The callback is evaluated each commandPeriodic() call.
      Parameters:
      callback - Runnable to invoke when tracking is acquired
    • onTrackingLost

      public void onTrackingLost(Runnable callback)
      Registers a callback that fires once when the Quest headset transitions from actively tracking to not-tracking. The callback is evaluated each commandPeriodic() call.
      Parameters:
      callback - Runnable to invoke when tracking is lost
    • onLowBattery

      public void onLowBattery(int thresholdPercent, IntConsumer callback)
      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 fires
      callback - 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 from commandPeriodic().
      Parameters:
      callback - Consumer receiving the raw Commands.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 from commandPeriodic(). The failure is also reported to the DriverStation regardless of whether a callback is registered.
      Parameters:
      callback - Consumer receiving the raw Commands.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) and onCommandFailure(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

      public OptionalInt 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 OptionalInt containing the battery percentage (0-100), or empty if no device data is available or Quest is disconnected
      See Also:
    • getFrameCount

      public OptionalInt getFrameCount()
      Gets the current frame count from the Quest headset.
      Returns:
      The frame count value, or empty if no frame data is available
    • getTrackingLostCounter

      public OptionalInt 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

      public OptionalDouble 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 OptionalDouble containing 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:
      true if the Quest is actively tracking and pose data is reliable, false if tracking is lost or no device data is available
      See Also:
    • getAllUnreadPoseFrames

      public PoseFrame[] 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 PoseFrame objects containing pose data and timestamps that can be fed directly into a PoseEstimator.

      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 PoseFrame objects 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:

      Usage Pattern:

      
       public class Robot extends TimedRobot {
         private QuestNav questNav = new QuestNav();
      
         @Override
         public void robotPeriodic() {
           questNav.commandPeriodic(); // Call every loop
         }
       }
       
      See Also:
    • getLibVersion

      public String getLibVersion()
      Retrieves the QuestNav-lib version number.
      Returns:
      The version number as a String.
    • getQuestNavVersion

      public String getQuestNavVersion()
      Retrieves the QuestNav app version running on the Quest headset.
      Returns:
      The version number as a String, or "unknown" if unable to retrieve.