wpilibsuite / wpilibsuite/SystemcoreTesting
[A301] Absolute-position control corrupts encoder telemetry and triggers Sensor Fault
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 186
- Forks
- 24
- Avg merge
- 8h 27m
- Merged PRs (30d)
- 9
Description
Summary
We are bringing up A301 motors on Systemcore + Motioncore while building and testing a single swerve-module pod. The pod uses one A301 for steering (theta) and another A301 for wheel drive.
Both encoders appear to work correctly in REV Hardware Client 2 when no robot program is deployed/running. They also update plausibly while running ordinary open-loop robot code that only calls setThrottle(...) and does not use encoder-based position control.
The failure appears when we try to use the A301 position-control APIs from robot code:
- Earlier relative-position/relative-feedback testing on another A301 produced unusable feedback and could not stop at the requested travel.
- The current swerve theta test uses the absolute encoder and the documented absolute-position APIs. Running it causes the encoder telemetry to become physically impossible, the controller to pulse, and
Sensor Fault/Other Faultto appear. - Reinstalling
27.0.0-prerelease-15restores normal-looking encoder telemetry. Running the absolute-position test causes the failure to return.
This makes the problem look specific to using encoder-based position control through REVLib, rather than a disconnected encoder or an encoder that is always defective.
[!IMPORTANT]
We stopped using the position-control test because the reported feedback cannot be trusted and the motor can react to fictional position error.
Environment
| Component | Version / Configuration |
|---|---|
| Controller | Systemcore + Motioncore |
| WPILib / GradleRIO | 2027.0.0-alpha-6 |
| REVLib | 2027.0.0-alpha-4 |
| A301 firmware | 27.0.0-prerelease-15 |
| A301 bootloader | 1.3 |
| REV Hardware Client 2 | 1.2.1 on Systemcore |
| Theta A301 | Motioncore D11, default CAN ID 3, 500 RPM gearbox |
| Drive A301 | Motioncore D10, default CAN ID 3 |
| Earlier relative test A301 | Motioncore D4, default CAN ID 3 |
| Supply voltage visible in recording | Approximately 16.46-16.48 V |
| Language | Java |
All A301 objects use CANBusMap rather than raw integer bus IDs.
public final A301 armJoint0 = new A301(CANBusMap.CAN_D4);
public final A301 swerveDrive = new A301(CANBusMap.CAN_D10);
public final A301 swerveTheta = new A301(CANBusMap.CAN_D11);
Intended Swerve-Pod Behavior
The current test is intended to prove one swerve pod before expanding to a complete drivetrain:
- Use the left joystick as a unit circle.
- Map joystick direction to the theta motor's single-turn absolute position.
- Treat absolute encoder position
0.042as straight ahead. - Use continuous absolute input so the theta motor takes the shortest path across the
-0.5/0.5boundary. - Drive the wheel from joystick magnitude after theta is close to its target.
- Read the drive A301's relative encoder as distance from its starting position.
Expected angle mapping with the current calibration:
| Joystick direction | Expected absolute target |
|---|---|
| Forward | 0.042 |
| Right | Approximately 0.292 |
| Left | Approximately -0.208 |
| Backward | Approximately -0.458 after wrapping |
What Works Before Position Control
RHC2 with no robot code controlling the motors
Before deploying/running the position-control code, RHC2 telemetry behaves as expected:
- The theta absolute encoder reports a stable position while the pod is stationary.
- The theta absolute encoder changes with physical steering rotation and wraps normally between
-0.5and0.5. - The drive relative encoder changes when the drive motor physically rotates.
- Encoder movement corresponds to actual motor movement.
- The telemetry does not continuously run around the entire range while the motor is stationary.
Open-loop robot code
We also have a separate Swerve Pod Manual Test OpMode that only sends throttle commands:
double thetaThrottle = applyDeadband(gamepad.getRightX()) * kThetaMaxThrottle;
double driveThrottle = -applyDeadband(gamepad.getLeftY()) * kDriveMaxThrottle;
robot.swerveTheta.setThrottle(thetaThrottle);
robot.swerveDrive.setThrottle(driveThrottle);
During this ordinary open-loop test:
- Both motors respond to joystick commands.
- RHC2 encoder telemetry responds to physical movement.
- The absolute and relative values update plausibly.
- We do not see the same continuous impossible encoder motion caused by the position-control test.
This is an important distinction: the D10/D11 encoder hardware and read-only telemetry appear functional before encoder-based position control is engaged.
Absolute-Position Failure: Swerve Theta on D11
The swerve test follows the documented continuous absolute-position workflow:
REVLibError continuousInputError =
robot.swerveTheta.enableAbsolutePositionContinuousInput();
REVLibError commandError =
robot.swerveTheta.setAbsolutePositionWithSpeed(targetAbsolutePosition, 15.0);
The target is always normalized into the documented -0.5 to 0.5 range:
private static double wrapRotations(double rotations) {
return rotations - Math.floor(rotations + 0.5);
}
The test also checks Signal.isValid() before using the absolute position.
Observed result
After running the absolute-position test, RHC2 shows the absolute encoder continuously moving around the single-turn range. Representative values from a short recording are:
0.234
-0.047
-0.344
0.359
0.094
-0.219
-0.359
At the same time:
| Signal | Observed behavior |
|---|---|
| Absolute position | Continuously cycles through the single-turn range |
| Relative position | Changes even though the displayed current is 0.00 A |
| Velocity | Remains near 104857.594 RPM |
| Motor current | Remains 0.00 A in the recording |
| Gearbox rating | 500 RPM |
| Faults | Sensor Fault and Other Fault appear intermittently |
| Warning | Has Reset Warning appears as sticky |
104857.594 RPM is physically impossible for the 500 RPM A301 and looks like an invalid, saturated, sentinel, or incorrectly decoded value rather than real velocity.
The motor/controller also pulses as the control loop reacts to the changing feedback.
Relative-Feedback Failure: Earlier D4 Test
Before the swerve-pod test, we tested another A301 on Motioncore D4 as the first arm joint. We initially attempted both absolute and relative position-control approaches. The physical behavior did not follow the requested position targets, so we reduced the test to low open-loop throttle with encoder logging and a six-second safety timeout.
During the logged D4 run:
| Signal | Observed value / behavior |
|---|---|
| Commanded throttle | -0.150000 |
| Reported throttle | -0.150000 |
| Applied output | Approximately -0.149988 |
| Relative position | 486685.3125, remained fixed during motion |
| Absolute position | -0.25, remained fixed during motion |
| Velocity | Approximately -104000 RPM |
| Current | 0.0 A |
| Sticky fault | Present |
| Sticky warning | Present |
Because the relative position did not change with physical movement, code could not stop after one requested rotation. The timeout did execute and returned the state machine to idle, showing that the OpMode itself continued to run.
This was a different A301 and port from the current swerve theta motor, but it showed a similar impossible velocity scale and unusable encoder feedback when attempting encoder-dependent control.
Reproduction After Firmware Reinstall
We reinstalled A301 firmware 27.0.0-prerelease-15 through RHC2.
- Use RHC2
1.2.1on Systemcore. - Reinstall A301 firmware
27.0.0-prerelease-15. - Power-cycle the A301.
- Observe normal/stable encoder telemetry in RHC2.
- Deploy and enable the absolute-position swerve test.
- Move the joystick to request a theta target.
- Observe continuously cycling absolute position, impossible velocity, pulsing, and sensor/other faults.
The reflash recovers normal-looking telemetry, but using absolute-position control causes the failure to return.
Questions
- Is this a known issue in A301 firmware
27.0.0-prerelease-15or REVLib2027.0.0-alpha-4? - Is
104857.594 RPMa sentinel/error value that should cause the returnedSignal<Double>to be invalid? - Does
Signal.isValid()indicate only CAN-frame freshness, or should it also become false when the A301 reportsSensor Fault? - Can enabling continuous absolute input put the A301 into a persistent bad sensor/control state?
- Is there another required configuration or calibration step before using A301 absolute-position control?
- Should application code explicitly inspect
getFaults().sensorbefore accepting encoder values, even when theSignalitself is valid? - Is reinstalling or force-reflashing currently the expected recovery after this failure occurs?
Minimal Absolute-Control Reproduction
public final A301 theta = new A301(CANBusMap.CAN_D11);
public void start() {
theta.absoluteEncoderPositionPeriodMs(20);
System.out.println(theta.enableAbsolutePositionContinuousInput());
}
public void periodic(double target) {
Signal<Double> position = theta.getAbsoluteEncoderPosition();
if (!position.isValid()) {
theta.disable();
return;
}
target = target - Math.floor(target + 0.5);
System.out.printf(
"position=%f target=%f commandResult=%s%n",
position.get(),
target,
theta.setAbsolutePositionWithSpeed(target, 15.0));
}
public void end() {
theta.disable();
}
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the minimal Java absolute-control reproduction on the A301 at Motioncore D11, using WPILib 2027.0.0-alpha-6, REVLib 2027.0.0-alpha-4, and firmware 27.0.0-prerelease-15; compare RHC2 telemetry before and after enabling continuous input. Check the reported Signal validity and sensor faults alongside the impossible velocity, then document whether the failure is reproducible and which component or recovery behavior is confirmed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- embedded-iot, robotics
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100