RL Robotics LabSearch ↗
Handbook / guide

Hardware, setup and device experiments

The main course targets Pololu 3pi+ 2040, the RP2040 robot with MicroPython support. It is different from the older 3pi+ 32U4. The assembled Turtle Edition is the introductory proposal; confirm the exact edition on your robot/order before using its speed or gearing assumptions. No hardware purchase is made by this course.

What the robot provides

The official guide documents two driven wheels with encoders, five downward reflectance sensors, front bump sensing, an IMU, display and buttons. Reflectance sensors observe the nearby floor; bump sensors detect contact. Built-in forward non-contact distance sensing is not assumed. The core navigation project uses a surveyed known map, wheel odometry and contact/floor stop guards. Optional distance hardware requires its own model-specific power, logic-voltage, mounting and driver checks.

The robot uses four AAA cells as specified by the vendor. Follow the current guide for supported cells, polarity, USB power behaviour and firmware installation. Do not substitute improvised battery packs. BB-8 and Dash are optional Week 1 comparison devices: record exact model, current app availability, pairing and observed capabilities rather than assuming they can run this course’s code.

Equipment checklist

First connection and transfer

  1. Read the vendor getting-started section for your exact edition. Photograph/record model and current firmware. Back up existing device files before changing firmware or main.py.
  2. Install/connect through the documented MicroPython/Thonny workflow. Confirm that the device interpreter can import from pololu_3pi_2040_robot import robot. A desktop import failing is expected because the hardware package is device-specific.
  3. Start with an official display example. Change one message, transfer a named file, run it and restart. Record the source revision and observed message.
  4. Keep new programs under explicit filenames and run them manually during development. Do not configure automatic motor startup. Record which file actually ran; a Git push does not transfer it.

Verify signs before motion on the floor

With motors off and wheels accessible, run the stationary sensor logger. Rotate each wheel forward by hand and check which signed encoder count changes. Run a tiny raised-wheel pulse and observe both commanded directions. If signs differ from your model, resolve the physical/firmware convention first. Do not “fix” a sign by taking absolute values: reverse travel and turning need signed increments.

One bounded pulse — Weeks 1 and 4

Download bounded-pulse.py. It uses official APIs: robot.Motors(), set_speeds(left,right), off(), robot.Encoders().get_counts(), buttons and bump readings. The library maximum is 6000 device command units; the example uses 300 for 0.5 seconds. This is deliberately small, not a guarantee of safe speed for every edition/surface.

Release bumpers during calibration. With wheels raised, run it explicitly, press A to arm, and test C and each bumper stop. Arming expires in 30 seconds; cleanup calls motors.off(). Then use a clear level floor lane and one supervised pilot pulse. If it stalls, stop and inspect setup; do not jump to large commands. Measure distance/time independently. Keep an accessible physical power switch because software can fail.

Do not test on a tabletop, near steps, people, pets or fragile objects. The pulse example has contact/button guards but no calibrated floor-edge guard. A clear contained floor area remains essential.

Encoder and sensor collection — Weeks 6 and 13

The sensor logger keeps motors off and prints 100 samples at roughly 50 ms intervals. Save the terminal CSV output as raw data; record the actual timestamps, not just the requested delay. Counts are cumulative. Calculate consecutive differences for odometry; do not add the cumulative count every sample or reset unexpectedly.

For encoder calibration, mark the wheel/start position, collect counts and ruler travel for several short movements, fit distance/count and validate on fresh distances. Use separate left/right scales if justified. Do not infer your scale from another edition’s gear ratio.

For floor sensing, collect readings over the actual light mat, dark markings and transitions under several lighting conditions. Raw readings are not centimetres. Label the floor condition independently. Choose thresholds/hysteresis from data. read_calibrated() requires valid light/dark calibration first; this course’s logger uses raw read() to avoid silently assuming calibration.

The official infrared implementation shares acquisition resources between line and bump sensors; use sequential reads as in the examples. Calibrate bump sensors with both bumpers released, then verify actual pressed/released detection. Save the installed firmware/source version.

Wheel speed, pose and waypoint integration — Weeks 9–22

The complete teaching adapter robot-controller.py implements a bounded one-waypoint baseline, signed encoder increments, midpoint odometry, heading/forward targets, wheel P/optional-I control, command limits, floor/contact/button guards, stall checks and mission/waypoint timeouts. It does not build a map or detect an obstacle at range; feed it the independently surveyed route you validated with the desktop planner.

It intentionally refuses motion until you enter your measured left/right metres-per-count, track width, raw dark-floor threshold and selected speed-loop gain. These are calibration inputs, not missing lesson text. Fictional example values are unsuitable for device actuation. The default route is a 15 cm segment in the surveyed +x direction. Start with P; add integral only after Week 11 evidence. Recheck signs, thresholds, units and raised-wheel stops before any floor run.

Inspect the first loops carefully: measurement precedes control; hazard/invalid/timeout takes priority; estimated arrival ends motion; final cleanup stops motors. At an arrival, measure the real endpoint with a ruler. A printed estimated_arrival is not independent evidence of physical arrival. Logging and blocking reads affect dt; the adapter stops on a sampling gap above 0.2 s. Test your actual timing before extending the route.

The adapter uses a simple conditional integral bound, not a universal optimal controller. It stops on any dark reading at/above the calibrated threshold; designated dark landmark crossings therefore require a separately validated landmark policy. The baseline can use stopped manual landmark corrections from Week 18 rather than enabling unreviewed automatic crossings. It does not provide automatic reverse recovery because rear sensing is limited.

Optional extensions

An IMU can support heading experiments, but gyro bias and magnetic interference need independent calibration. A forward range sensor can improve advance obstacle detection only after electrical and software compatibility is verified. Camera SLAM, unsurveyed dynamic replanning and automatic retries are beyond the core baseline. Record an extension’s new assumptions and tests before relying on it.

Verification status and primary sources

These original teaching programs are API/source checked and syntax checked, not physically piloted. Device behaviour, calibration, traction and stopping remain learner/owner validation tasks. Never treat a simulator result as a hardware test.