step.wait_for_light

Automatic wait-for-light using Kalman-filtered flank detection.

Designed for a downward-facing light sensor (no shielding required). A Kalman filter tracks the ambient baseline. When the start lamp turns on, light reflects off the table surface and the sensor value drops sharply. The step triggers when the raw reading falls below a configurable fraction of the filtered baseline for several consecutive samples.

Based on: “Comprehensive Light-Start Methods in Botball” (Gosling et al.)

Classes

WaitForLight

Wait for the start lamp using automatic Kalman-filtered flank detection.

WaitForLightLegacy

Wait for light using the legacy manual-calibration threshold method.

Module Contents

class step.wait_for_light.WaitForLight(sensor: raccoon.hal.AnalogSensor, drop_fraction: float = 0.15, confirm_count: int = 3, warmup_seconds: float = 1.0, poll_interval: float = 0.005)

Bases: raccoon.ui.UIStep

Wait for the start lamp using automatic Kalman-filtered flank detection.

Mount the light sensor facing downward with no shielding. The step establishes a stable baseline reading via a 1D Kalman filter during a short warm-up phase, then arms and polls for a sharp brightness increase (sensor value drop). When the raw reading falls below baseline * (1 - drop_fraction) for confirm_count consecutive samples, the step returns and the mission begins.

The downward-facing mount reduces environmental noise by up to 76% compared to a horizontal mount (Gosling et al., 2023). No black tape or straw shielding is required.

Prerequisites:

An analog light sensor (LDR) connected to the Wombat and mounted facing the table surface. The start lamp should be positioned diagonally above the sensor.

Parameters:
  • sensor – The AnalogSensor instance for the light sensor.

  • drop_fraction – Fraction the raw value must drop below the baseline to trigger. 0.15 means a 15% brightness increase triggers the start. Lower values are more sensitive (faster but riskier), higher values are safer but need a stronger signal.

  • confirm_count – Number of consecutive triggering samples required before starting. At the default 200 Hz poll rate, 3 samples equals ~15 ms of confirmation — effectively instant while rejecting single-sample noise spikes.

  • warmup_seconds – Duration in seconds to collect baseline samples before arming the detector.

  • poll_interval – Seconds between sensor reads. 0.005 gives ~200 Hz.

Example:

from raccoon.step.wait_for_light import wait_for_light

# Default settings — works well for most setups
wait_for_light(robot.defs.wait_for_light_sensor)

# More sensitive (10% drop, 2 confirms) for weak lamp signal
wait_for_light(robot.defs.wait_for_light_sensor, drop_fraction=0.10, confirm_count=2)
class step.wait_for_light.WaitForLightLegacy(sensor: raccoon.hal.AnalogSensor)

Bases: raccoon.ui.UIStep

Wait for light using the legacy manual-calibration threshold method.

Runs the traditional two-step calibration flow: the operator measures the sensor with the lamp off, then with it on, confirms the threshold, and the robot starts immediately. This approach requires manual interaction at the start of each run and uses a fixed midpoint threshold between the dark and light readings.

Use this only if the automatic flank-detection method (wait_for_light) does not work for your setup, for example when the sensor is not mounted downward or when the lamp signal is too weak for reliable flank detection.

Parameters:

sensor – The AnalogSensor instance for the light sensor.

Example:

from raccoon.step.wait_for_light import wait_for_light_legacy

wait_for_light_legacy(robot.defs.wait_for_light_sensor)