Skip to content

Race condition causes Encoder.reset() (for the XRP motor encoders) and XRPGyro.reset() to fail at startup #8537

@hugheaves

Description

@hugheaves

Describe the bug
Like other WPILib example Java projects, the XRP example calls the Encoder.reset() and XRPGyro.reset() methods during startup. (i.e.

)
However, due to a startup race condition, neither of these methods reset the position encoder / gyro.

This is because:

  1. The reset() methods don't send "reset" the XRP robot's internal state - they just store the current position in the HAL as the "zero offset", which is the subtracted from any future values returned by the HAL
  2. The current position stored in the HAL is zero until the HAL receives a UDP update packet from the XRP
  3. The UDP update packet arrives after the startup code has been executed

In other words, as the startup code doesn't wait for the first packet from the XRP - the reset() methods are called before the actual positions are known. In all tests I have done, the UDP packet is always received about 20-40ms after the reset() has been called.

I noticed this when extending the XRP example project to include pose estimation. After the first one or two periodic() calls, the position of the robot would all of a sudden jump many meters. This was due to the HAL receiving the current encoder positions from the XRP after the reset() call.

To Reproduce
Steps to reproduce the behavior:

  1. Modify the XRP example project (https://github.com/wpilibsuite/allwpilib/blob/main/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/xrpreference) to log the encoder and gyro position during the periodic() call.
  2. Notice that during the first few calls, the positions are zero as if reset() had worked, but then there is a jump in value to the XRP robots encoder and gyro positions.

Expected behavior
After a reset() call, calls to get the position of the gyro and encoders should return zero, unless the gyro and or motors have actually been moved.

Screenshots
N/A

Desktop (please complete the following information):

  • OS: Windows 11
  • Project Information:
    WPILib Information:
    Project Version: 2026.1.1-beta-1
    VS Code Version: 1.105.1
    WPILib Extension Version: 2026.1.1-beta-1
    Project Year: 2026beta
    Language: java
    C++ Extension Version: 1.28.3
    Java Extension Version: 1.38.0
    Java Debug Extension Version: 0.58.2
    Java Dependencies Extension Version 0.24.1
    Java Version: 17
    Java Location: C:\Users\Public\wpilib\2026\jdk
    Vendor Libraries:
    PathplannerLib (2025.2.7)
    CTRE-Phoenix (v6) (26.0.0-beta-1)
    photonlib (v2026.0.1-beta)
    WPILib-New-Commands (1.0.0)
    XRP-Vendordep (1.0.0)

Additional context
We've hacked around this by adding logic to our periodic() loop that waits for the first non-zero value from the gyro or encoders, and then calls reset() to set that non-zero position as the "zero offset". That is obviously an inelegant solution as the code is effectively ignoring the first non-zero value received.

Metadata

Metadata

Assignees

No one assigned

    Labels

    type: bugSomething isn't working.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions