Distance sensor wall resets

Use known field geometry to correct accumulated position error when the sensor has a clear view of a wall.

Before you start

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.

A forward-facing distance sensor measures the ray from the robot to a known east wall.xy0Wall at x = Wrange dsensor offsetrobot Xθ = 0° · facing +X
A wall reading constrains one coordinate. Include the sensor’s offset from the tracking center.

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.

main.cpp · add resetXFromEastWall()
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

  1. First confirm that the ray reaches the intended wall without crossing a game object. Numeric gates alone cannot identify the wall.
  2. Take several readings while stationary, reject invalid samples, and compare their spread before using a median. A stable obstacle can still pass this test.
  3. Reject readings outside your tested range and geometry. A ray nearly parallel to a wall is a poor constraint.
  4. Compare the candidate coordinate with the current pose. Treat a large discrepancy as a reason to investigate rather than automatically jumping the pose.
  5. 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.

  1. 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.

  2. Purdue SIGBots / Team 5225AOdometry (opens in a new tab)

    The PiLons tracking derivation: consistent units, tracking-center offsets, and arc-based position integration.

  3. 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.

Search documentation

↑ ↓ to move Enter to openEsc to close