Distance sensor wall resets
Use known field geometry to correct accumulated position error when the sensor has a clear view of a wall.
The odometry pose convention and update loop, plus a front-facing V5 Distance Sensor. Shared configuration ↗
On this pageWhat a wall reading tells you
What a wall reading tells you
A distance sensor reports the nearest detected object along its viewing direction. It does not know whether that object is the intended wall. A game object or another robot can produce a plausible reading, so choose reset locations with a clear line of sight.
A vertical wall constrains X; a horizontal wall constrains Y. One reading does not determine X, Y, and heading together. This example keeps the odometry heading and corrects only X using a known east wall.
References: VEX Robotics: Distance Sensor — C++ API (opens in a new tab)
Include sensor position and heading
Measure the sensor’s position relative to the tracking center, not the bumper. A sensor 5 inches forward of center is already 5 inches closer to a wall when the robot faces it. At an angle, both the mounting offset and the measured range must be projected into field coordinates.
Let f be the sensor’s forward offset, l its left offset, d the range in inches, and θ the counterclockwise robot heading. For a forward-facing sensor and a vertical wall at x = W, the equations below give the center’s X. If the sensor is angled relative to the robot, use its ray angle θ + mounting angle for the range projection.
sensor offset X = f cos(θ) − l sin(θ) robot X = W − sensor offset X − d cos(θ)
References: Purdue SIGBots / Team 5225A: Odometry (opens in a new tab)
Reset X from the east wall
Add this to the odometry example. Call it from the same task that owns pose, while stationary, immediately after updateOdometry(). Supply the measured inner wall X coordinate; do not assume a nominal field width matches the measurement surface.
The example accepts headings within 10° of +X, a conservative 50–1,500 mm range, and a maximum 6-inch pose correction. Those are example gates to tune. VEX lists a wider 20–2,000 mm operating range; choosing a narrower range here does not change the sensor’s specification.
vex::distance frontDistance(PORT6);
constexpr double sensorForwardOffset = 5.0;
constexpr double sensorLeftOffset = 0.0;
bool resetXFromEastWall(double wallX) {
if (!frontDistance.installed() || !frontDistance.isObjectDetected())
return false;
double rangeMm = frontDistance.objectDistance(mm);
if (!std::isfinite(rangeMm) || rangeMm < 50 || rangeMm > 1500)
return false;
double theta = pose.theta;
double rayX = std::cos(theta);
if (rayX < std::cos(10.0 * pi / 180.0)) return false;
double offsetX = sensorForwardOffset * std::cos(theta)
- sensorLeftOffset * std::sin(theta);
double measuredX = wallX - offsetX - rangeMm / 25.4 * rayX;
if (!std::isfinite(measuredX) || std::fabs(measuredX - pose.x) > 6)
return false;
pose.x = measuredX;
return true;
}References: VEX Robotics: Distance Sensor — C++ API (opens in a new tab)
Reject bad resets
- First confirm that the ray reaches the intended wall without crossing a game object. Numeric gates alone cannot identify the wall.
- Take several readings while stationary, reject invalid samples, and compare their spread before using a median. A stable obstacle can still pass this test.
- Reject readings outside your tested range and geometry. A ray nearly parallel to a wall is a poor constraint.
- Compare the candidate coordinate with the current pose. Treat a large discrepancy as a reason to investigate rather than automatically jumping the pose.
- Log raw range, heading, candidate coordinate, and acceptance reason. Keep a rejected reading from changing pose.
Use another wall
The general vertical-wall equation is x = wallX − offsetX − d × rayX. The general horizontal-wall equation is y = wallY − offsetY − d × rayY. Ray components carry their signs, so the same equation can describe the opposite wall when the ray points toward it.
For a forward-facing sensor, rayX = cos θ and rayY = sin θ. The sensor’s field Y offset is f sin θ + l cos θ. Validate the direction toward the selected wall and that the intersection lies on the actual wall segment, not an extension past a corner.
vertical wall: x = wall X − offset X − range × ray X horizontal wall: y = wall Y − offset Y − range × ray Y
Continue tracking after a reset
Correcting pose.x does not require resetting encoder positions or inertial rotation. Keep the odometry baselines from the latest update so the next sample adds only new travel. A positional wall correction does not change headingOffset.
Apply the correction inside the pose-owning loop. If another task requests a reset, pass a request to that loop instead of writing pose directly. Test by resetting while stationary, taking another update, and confirming there is no second jump.
References: PROS: Multitasking and synchronization (opens in a new tab)
Sources for this guide
Examples are written for VEXcode C++. PROS and LemLib references explain related concepts; their APIs are different.
- VEX RoboticsDistance Sensor — C++ API (opens in a new tab)
Object detection, distance units, installation checks, and the stated 20–2,000 mm operating range.
- Purdue SIGBots / Team 5225AOdometry (opens in a new tab)
The PiLons tracking derivation: consistent units, tracking-center offsets, and arc-based position integration.
- PROSMultitasking and synchronization (opens in a new tab)
Why loops need delays and why concurrent tasks need an explicit ownership and synchronization model. PROS task APIs are not VEXcode APIs.