VEX V5 PYTHON | 04.6 GPS AND FIELD POSITION

Guide objective

Configure GPS for a supported field, interpret robot position and heading, and check readings before using them in autonomous routines.

01 | GPS NEEDS THE RIGHT FIELD

The V5 GPS Sensor is a Game Positioning System. It reads special Field Code around the perimeter to estimate position and orientation. It does not use satellites.

A classroom floor, an ordinary wall or a field without the correct code does not provide the required visual reference. Confirm that your practice setup has compatible, correctly installed code before planning GPS navigation.

Check the current event rules and supplied field equipment separately. Owning a GPS Sensor does not establish that a particular competition supports your intended use.

If your setup is unsupported, continue with motor encoders, an inertial sensor and tracking-wheel odometry. You can still practise coordinate calculations with simulated data.

02 | PREPARE THE VIEW

  1. Secure the sensor upright with a clear view of the perimeter code.
  2. A rear-facing mount near code height is a useful starting arrangement.
  3. Inspect the view with mechanisms in their different positions.
  4. Check visibility at several field positions, not just the centre.
  5. Keep the robot still for startup calibration and initial tests.

A mounting bracket that flexes changes the relationship between the sensor and robot. Include the bracket and cable routing in your inspection.

Use the Brain’s Devices screen to inspect the GPS view and readings before writing movement code. Record which positions have poor visibility.

03 | UNDERSTAND FIELD COORDINATES

A fixed field map, not the driver’s current viewpoint
ReadingMeaningExample
XAcross the field; positive to the right on the field mapX = 600 mm
YUp the field map; positive upwardY = -400 mm
HeadingClockwise from field-map up90 degrees faces map right

The standard coded field has its origin at the centre and spans approximately -1.8 m to +1.8 m along each axis. Use millimetres consistently in your project: 0.6 m is 600 mm.

At (600, -400), your configured reference point is 600 mm right and 400 mm below the centre. Rotating the robot changes heading; it does not rotate the field axes.

Draw the field map on your test sheet. Label the code-defined orientation so everyone uses the same meaning of up, right and zero heading.

04 | CHOOSE THE ROBOT REFERENCE POINT

Choose a point that makes navigation meaningful, such as the centre of the drivetrain turning axis. Put a visible marker there for measurement tests.

The sensor is usually somewhere else on the robot. Enter its mounting offsets relative to the chosen point in Devices. Body-frame positive X is to the robot’s right and positive Y is forward.

Example values only; measure the actual robot
Example mountingDevices value
50 mm right of the reference pointX offset: +50 mm
200 mm behind the reference pointY offset: -200 mm
Sensor faces straight behind the robotAngle offset: 180 degrees

These offsets belong to the robot, so they rotate with it. They are not field coordinates. VEXcode compensates for configured offsets when reporting the reference point; do not subtract them again from X and Y.

Choose one reference point for the whole project. Mixing a drivetrain-centre waypoint with a sensor-position reading creates a systematic error.

05 | CONFIGURE WITHOUT DUPLICATING DEVICES

  1. Open the desktop VEXcode V5 Python project.
  2. In Devices, add GPS on Smart Port 10 for this example.
  3. Name it gps_sensor and enter measured X, Y and angle offsets.
  4. Save the configuration and confirm the generated device declaration.
  5. Keep your own code below # Begin project code.

Devices manages the generated configuration. Do not edit that region or create a second gps_sensor object below it. If your project uses another port or name, update the lesson code to match.

This lesson deliberately uses Devices for the complete mounting configuration, including the angle offset. The diagnostic below contains no drivetrain declaration because it commands no motors.

06 | QUALITY IS PART OF THE READING

GPS quality describes sensing state, not an accuracy percentage
QualityHow to treat position
100API reports valid positional and heading data
Around 90Position is being estimated without current Field Code capture
0 to 80Do not accept X/Y as a fresh visual position fix
0Data may be frozen and invalid

The starter accepts position only at quality 100. This conservative teaching policy is not a universal navigation standard. Even a passing value still needs a correct mount, field configuration and physical verification.

Reading the sensor repeatedly does not prove that its visual position has just updated. A loop timestamp records when your code read the values, not when the sensor acquired the image.

Never retain a previous accepted position and silently present it as current after quality drops.

07 | SENSOR-ONLY DIAGNOSTIC PROJECT

Configure the named GPS device first, then paste this below the generated configuration. It displays raw measurements and a separate acceptance status. No movement is commanded.

# =============================================================================
# TEAM [MY TEAM NAME / NUMBER] | GPS DIAGNOSTIC ONLY
# =============================================================================
# ROBOT CONFIGURATION (use the VEXcode Devices window)
# - GPS Sensor: Smart Port 10, named gps_sensor
# - Reference point: centre of drivetrain turning axis
# - Example mounting: 50 mm right, 200 mm behind this point
# - Devices offsets: X = 50 mm, Y = -200 mm, angle = 180 degrees
# - Measure your own robot; these numbers are examples.
# - gps_sensor is generated by Devices. Do not declare it twice.
# Paste below '# Begin project code', outside the generated region.
# No motor commands, no competition movement in this diagnostic.

import math

FIELD_LIMIT_MM = 1850.0   # Plausibility bound for this example field
REQUIRED_QUALITY = 100    # Conservative position acceptance policy

# =============================================================================
# POSITION ACCEPTANCE (not a guarantee of accuracy or freshness)
# =============================================================================
def acceptable_pose(x, y, heading, quality_before, quality_after):
    values = (x, y, heading, quality_before, quality_after)
    for value in values:
        if not math.isfinite(value):
            return False
    return (quality_before >= REQUIRED_QUALITY
            and quality_after >= REQUIRED_QUALITY
            and abs(x) <= FIELD_LIMIT_MM
            and abs(y) <= FIELD_LIMIT_MM
            and 0 <= heading < 360)

# =============================================================================
# STARTUP AND DISPLAY
# =============================================================================
# Keep the robot completely still during calibration.
# This call may block; the display loop is not a calibration timeout.
gps_sensor.calibrate()

while True:
    try:
        q_before = gps_sensor.quality()
        x = gps_sensor.x_position(MM)
        y = gps_sensor.y_position(MM)
        heading = gps_sensor.heading()
        q_after = gps_sensor.quality()
        accepted = acceptable_pose(x, y, heading, q_before, q_after)
        status = "CHECKS PASSED" if accepted else "REJECT POSITION"
        brain.screen.clear_screen()
        brain.screen.set_cursor(1, 1)
        brain.screen.print(status)
        brain.screen.set_cursor(2, 1)
        brain.screen.print("X %.0f mm  Y %.0f mm" % (x, y))
        brain.screen.set_cursor(3, 1)
        brain.screen.print("Heading %.1f deg" % heading)
        brain.screen.set_cursor(4, 1)
        brain.screen.print("Quality %.0f / %.0f" % (q_before, q_after))
        print("%s, x=%.1f, y=%.1f, h=%.1f, q=%.0f/%.0f" %
              (status, x, y, heading, q_before, q_after))
    except Exception:
        brain.screen.clear_screen()
        brain.screen.set_cursor(1, 1)
        brain.screen.print("GPS READ ERROR")
        print("GPS read failed; position rejected")
    wait(200, MSEC)

The 1850 mm bound is a coarse sanity check for the example field, not permission to drive to its edge. Replace it for another supported layout. Robot footprint and clearance require separate planning.

Quality is sampled before and after the coordinates to reject an obvious change during reading. The separate calls are not an atomic pose snapshot; passing this check does not prove freshness.

If calibration does not finish, stop the diagnostic and investigate the sensor/setup. This program does not implement a bounded calibration supervisor.

08 | VERIFY WITH PHYSICAL LANDMARKS

Place the marked reference point at a measured location with a clear view of the code. Compare the expected position with the diagnostic result after the robot settles.

Measure the reference point, not the sensor bracket
TestWhat to inspect
Near field centreX and Y close to zero for the marked point
Move to the right on the mapX increases
Move upward on the mapY increases
Rotate around the chosen pointHeading changes; position stays close to the point
Return to the same markRepeatability across three trials

Record expected X/Y, reported X/Y, heading and quality. Compute error X = reported X - expected X and error Y = reported Y - expected Y.

A consistent offset suggests a reference or mounting problem. Position varying with rotation suggests incorrect offsets or an unsuitable reference test. Intermittent jumps call for a visibility and mounting investigation.

09 | CALCULATE A WAYPOINT WITHOUT DRIVING

Suppose the accepted pose is (200, -300) mm and the target is (800, 500) mm. The displacement is dx = 600 mm and dy = 800 mm. The straight-line distance is 1000 mm.

import math

def waypoint_geometry(x, y, target_x, target_y):
    dx = target_x - x
    dy = target_y - y
    distance = math.sqrt(dx * dx + dy * dy)
    if distance < 1.0:
        return distance, None  # No useful bearing at the target
    # atan2 arguments match clockwise heading from positive Y.
    bearing = math.degrees(math.atan2(dx, dy)) % 360
    return distance, bearing

# Calculation only: does not command motors.
distance_mm, bearing_deg = waypoint_geometry(200, -300, 800, 500)
print(distance_mm, bearing_deg)

The bearing is approximately 36.9 degrees. It describes the direction of the target from the current point, not necessarily the robot’s present heading.

A straight line can cross obstacles or require more clearance than the robot has. A waypoint calculation is geometry, not a complete autonomous routine.

10 | INITIAL POSITION AND SENSOR COMBINATIONS

The API provides set_location(x, y, MM, heading, DEGREES) for a known starting pose. Use measured start coordinates and field heading; do not supply desired coordinates to hide a bad reading.

It can assist initialization where little code is visible near a wall. It does not replace the required supported field or a verified mount.

GPS can provide a field position reference while encoders and tracking wheels estimate movement between observations. An inertial sensor can support short-term heading control. Those measurements have different frames and errors.

Before combining them, align their units, reference points and heading conventions. Gate GPS corrections by quality and plausibility. Avoid snapping an estimate to a distant new value while driving without investigating the discrepancy.

11 | COMMON SETUP MISTAKES

Diagnose before changing navigation gains
SymptomCheck first
Good numbers on a field without codeQuality and whether position is visually supported
Heading reversed by about 180 degreesSensor orientation and configured angle offset
Position shifts when rotating in placeMounting offsets and actual turning point
Brain display and Python heading look differentBrain may use signed angles; normalize modulo 360
Poor readings near a wallHow much code is visible
Worked at the centre, fails elsewhereVisibility throughout the planned route
Position always off by a similar amountReference-point measurement and duplicated compensation

Change one variable at a time and repeat the same landmark test. Keep the previous configuration and log so a change can be evaluated against evidence.

CHALLENGES | MAP, VERIFY AND REJECT

  1. Map: label the field origin, axes and four cardinal headings.
  2. Measure: draw your reference point and record signed mounting offsets.
  3. Configure: save a project with GPS on a documented Smart Port.
  4. Verify: compare readings at three measured marks and two headings.
  5. Reject: test acceptable_pose with simulated low-quality and out-of-range values.
  6. Calculate: find the distance and bearing between two waypoints without commanding movement.
  7. Explain: describe why a stable number is not proof of a fresh position fix.
  8. Plan: identify where a proposed route loses code visibility and choose an appropriate fallback.
Success evidence

A labelled field sketch, saved configuration, diagnostic project and landmark log. Explain the acceptance policy and demonstrate rejected simulated readings. If no supported field is available, label results as simulation rather than hardware measurements.

OFFICIAL REFERENCES

Technical references: VEX Robotics. The diagnostic policy, examples and challenges are independently written learning material. VEX and VEXcode are trademarks of their respective owners.