libstp.step.calibration.calibrate_distance

Distance calibration step using the new UI library.

Supports two calibration modes: - Runtime calibration: Apply measured ticks_to_rad for this run (best accuracy now) - Persistent learning: Update YAML baseline using EMA (converges over multiple runs)

Attributes

DEFAULT_EMA_ALPHA

Exceptions

CalibrationRequiredError

Raised when an operation requires calibration but none has been performed.

Classes

DistanceCalibrationResult

Result of distance calibration.

PerWheelCalibration

Result of per-wheel distance calibration.

CalibrateDistance

Step for calibrating robot distance estimation via per-wheel ticks_to_rad adjustment.

Functions

is_distance_calibrated(→ bool)

Check if distance calibration has been performed.

check_distance_calibration(→ None)

Log a warning when distance calibration has not been performed yet.

reset_distance_calibration(→ None)

Reset the calibration flag (for testing).

calibrate_distance(→ CalibrateDistance)

Calibrate per-wheel distance estimation via encoder measurement.

Module Contents

libstp.step.calibration.calibrate_distance.DEFAULT_EMA_ALPHA = 0.7
exception libstp.step.calibration.calibrate_distance.CalibrationRequiredError

Bases: Exception

Raised when an operation requires calibration but none has been performed.

libstp.step.calibration.calibrate_distance.is_distance_calibrated() bool

Check if distance calibration has been performed.

libstp.step.calibration.calibrate_distance.check_distance_calibration() None

Log a warning when distance calibration has not been performed yet.

libstp.step.calibration.calibrate_distance.reset_distance_calibration() None

Reset the calibration flag (for testing).

class libstp.step.calibration.calibrate_distance.DistanceCalibrationResult

Result of distance calibration.

requested_distance_cm: float
measured_distance_cm: float
scale_factor: float
class libstp.step.calibration.calibrate_distance.PerWheelCalibration

Result of per-wheel distance calibration.

motor_port: int
old_ticks_to_rad: float
new_ticks_to_rad: float
delta_ticks: int
ema_baseline: float = 0.0
motor_name: str | None = None
class libstp.step.calibration.calibrate_distance.CalibrateDistance(calibration_distance_cm: float = 30.0, calibrate_light_sensors: bool = False, persist_to_yaml: bool = True, ema_alpha: float = DEFAULT_EMA_ALPHA, calibration_sets: List[str] | None = None, exclude_ir_sensors: List[libstp.sensor_ir.IRSensor] | None = None)

Bases: libstp.ui.step.UIStep

Step for calibrating robot distance estimation via per-wheel ticks_to_rad adjustment.

Two calibration mechanisms: 1. Runtime: Apply the measured ticks_to_rad directly for best accuracy this run 2. Persistent: Update YAML baseline using EMA so it converges over multiple runs

The EMA formula: new_baseline = old_baseline × α + measured × (1 - α) With α=0.7, after ~5 calibrations the baseline absorbs ~83% of any systematic error.

calibration_distance_cm = 30.0
calibrate_light_sensors = False
persist_to_yaml = True
ema_alpha = 0.7
calibration_sets = ['default']
exclude_ir_sensors: List[libstp.sensor_ir.IRSensor] = []
result: DistanceCalibrationResult | None = None
per_wheel_results: List[PerWheelCalibration] = []
libstp.step.calibration.calibrate_distance.calibrate_distance(distance_cm: float = 30.0, calibrate_light_sensors: bool = False, persist_to_yaml: bool = True, ema_alpha: float = DEFAULT_EMA_ALPHA, calibration_sets: List[str] | None = None, exclude_ir_sensors: List[libstp.sensor_ir.IRSensor] | None = None) CalibrateDistance

Calibrate per-wheel distance estimation via encoder measurement.

Drives the robot a known distance, then prompts the user to enter the actual measured distance. The step computes a corrected ticks_to_rad value for each drive motor so that odometry matches real-world distances.

The calibration operates in two modes simultaneously:

  • Runtime: Applies the measured ticks_to_rad directly for best accuracy during this run.

  • Persistent: Updates the YAML baseline using an exponential moving average (EMA) so the stored value converges toward the true value over multiple calibration runs. The EMA formula is: new_baseline = old * alpha + measured * (1 - alpha).

Convergence rates for different alpha values:

  • alpha=0.5: ~97% of error absorbed after 5 calibrations (responsive)

  • alpha=0.7 (default): ~83% after 5 calibrations (balanced)

  • alpha=0.9: ~41% after 5 calibrations (very stable)

Prerequisites:

The robot must have drive motors with encoder feedback and a configured kinematics model providing wheel radius.

Parameters:
  • distance_cm – Distance (in cm) the robot drives during calibration. Default is 30 cm. Longer distances yield better accuracy.

  • calibrate_light_sensors – If True, run IR sensor calibration after the distance calibration is confirmed. Sensors are sampled during an additional drive over calibration surfaces.

  • persist_to_yaml – If True, write the EMA-filtered baseline to raccoon.project.yml so it persists across program runs.

  • ema_alpha – EMA smoothing coefficient between 0.0 and 1.0. Higher values produce slower convergence but a more stable baseline.

  • calibration_sets – List of named IR calibration surface sets (e.g. ["default", "transparent"]). Only used when calibrate_light_sensors is True.

  • exclude_ir_sensors – List of IRSensor instances to skip during IR calibration.

Returns:

A step that performs the interactive distance calibration flow.

Return type:

CalibrateDistance

Example:

from libstp.step.calibration import calibrate_distance

# Distance-only calibration with defaults
seq([
    calibrate_distance(),
    drive_forward(100),
])

# Distance + IR sensor calibration, slower EMA convergence
calibrate_distance(
    distance_cm=50.0,
    calibrate_light_sensors=True,
    ema_alpha=0.9,
    calibration_sets=["default", "transparent"],
)