
Andino
Evidence: the recorded runs and their sources ↓
An open-source ROS 2 robot from Ekumen, built to teach real robotics on a budget: two driven wheels and a caster, a spinning lidar on top, a Raspberry Pi for a brain. It is the first robot in the Robodex that RobotForge did not design — its spec here was read out of the official project's own files.
Spec
| Battery | 3x 18650 Li-ion cells, ~11.1 V nominal (official BOM holder); capacity varies by cell — the spec uses 2600 mAh as a labelled estimate |
|---|---|
| Chassis | 0.25 m long x 0.10 m wide base deck (official URDF base.yaml); overall width 0.153 m across the wheels, wheel track 0.128 m |
| Computer | Raspberry Pi 4 + Arduino Nano (official BOM) |
| Drivetrain | differential — 2 driven wheels + ball caster |
| Ground clearance | ~0.03 m — estimate; the URDF base plane rides at wheel radius (0.0331 m) |
| Height | ~0.18 m — estimate derived from the URDF deck stack |
| Mass | 3.364 kg — the sum of the official URDF link masses (several are round values upstream) |
| Motors | 2x DG01D-E gearmotors with encoders, 48:1 gearbox, rated 3-9 V (SparkFun listing linked from the official BOM), driven via an L298N |
| Sensors | RPLIDAR A1M8 2D lidar (top), Raspberry Pi Camera V2 (front), BNO055 IMU, wheel encoders |
| Wheels | 66.2 mm diameter x 25 mm — official wheel.yaml radius 0.0331 m |
examples/andino.jsonLicense is per-package LICENSE files in the repo (each reads BSD 3-Clause, (c) 2023 Ekumen Inc.); the repo root carries no single LICENSE file. Spec values were read from andino_description/config/andino/*.yaml and the andino_hardware BOM.GateA pass/fail test in the Gazebo simulator: the twin drives 1 m, turns 90° and stops, and the result is measured against where it really went. runs
Measured against simulator ground truth at the locked thresholds: pass ≤ 5% / 5°, fail over 10% / 10°. The gate tests the spec's simulated twin, not a physical robot.
| Run | Drive vs truth | Turn vs truth | Odometry distance | Odometry heading |
|---|---|---|---|---|
| Run 1 | 1.497% | 3.425° | 0.003% | 8.285° |
| Run 2 | 0.347% | 9.104° | 0.003% | 11.624° |
- Run 1: Gate run 1 on scythe, 2026-10-26, build/gate-andino-1/gate-report.json — run verdict MARGINAL (motion vs ground truth PASS; odometry heading MARGINAL)
- Run 2: Gate run 2 on scythe, 2026-10-26, build/gate-andino-2/gate-report.json — run verdict FAIL (turn vs ground truth MARGINAL at 9.104 deg; odometry heading FAIL at 11.624 deg)
HarnessThe robot’s wiring. The harness check adds up current on each power rail and flags wires that are too thin or rails that are overloaded. checks
Electrical checks over this robot's documented wiring. Not a simulation; the headline is counts, never a blanket pass.
2 checked clean · 1 with warnings · 0 with errors · 2 partial · 29 not checked · missing data: cable.gauge_awg ×12, connector at both ends (connector_from / connector_to) ×12, current_a for nano ×7
Check-by-check counts and missing data
| Check | Checked | Partial | Not checked |
|---|---|---|---|
| voltage drop | 0 | 0 | 6 |
| ampacity | 0 | 0 | 6 |
| logic levels | 3 | 0 | 3 |
| rail budget | 0 | 2 | 2 |
| connector match | 0 | 0 | 12 |
Findings (1):
- [WARN] controller -> nano: logic levels 3.3 V and 5 V do not agree and no level shifter is recorded on the link — a 3.3 V input is not 5 V tolerant; add a shifter or record one
Missing data — the datasheets still to hunt. A check that could not run says what it needs:
| Missing input | Blocks | Needed by |
|---|---|---|
cable.gauge_awg | 12 | battery -> driver, battery -> regulator, regulator -> controller, controller -> nano … |
connector at both ends (connector_from / connector_to) | 12 | battery -> driver, battery -> regulator, regulator -> controller, controller -> nano … |
current_a for nano | 7 | battery -> regulator, regulator -> controller, controller -> nano, controller rail |
cable.length_mm | 6 | battery -> driver, battery -> regulator, regulator -> controller, controller -> nano … |
current_a for motors | 5 | battery -> driver, driver -> motors, driver rail |
connection voltage (volts) | 2 | driver -> motors, controller -> lidar |
current_a for controller | 1 | regulator rail |
current_a for driver | 1 | battery rail |
current_a for regulator | 1 | battery rail |
logic_v for camera | 1 | controller -> camera |
logic_v for imu | 1 | controller -> imu |
logic_v for motors | 1 | motors -> nano |
rated output current for battery | 1 | battery rail |
rated output current for controller | 1 | controller rail |
Report: catalog/harness-reports/andino.json · checked 2026-10-27 · reproduce with robotforge harness examples/andino.json
Take it apart
Every spec becomes a kit of simple, 3D-printable parts (robotforge cad). This viewer lays the kit out the way the kit's own assembly file does, straight from the spec's numbers — flat views, or in 3D with the toggle. Click any part.
examples/andino.json…Parts kit
The take-apart kit robotforge cad generates from this robot's spec: every part the generator defines, what it does, and the parameters worth tweaking with the values this robot's kit ships with. Each parameter carries the generator's own source label — from spec numbers come out of the spec, derived numbers are computed from them, and assumption numbers are typical values the spec does not carry.
Chassis plate ×1
parts/chassis_plate.scadThe deck everything else bolts to.
250 x 100 mm footprint, 4 mm thick
| Parameter | Value | Where the number comes from |
|---|---|---|
chassis_length_mm | 250 mm | from spec length_m |
chassis_width_mm | 100 mm | from spec width_m |
plate_thickness_mm | 4 mm | assumption — not in the spec |
corner_radius_mm | 6 mm | assumption — not in the spec |
mount_hole_diameter_mm | 3.4 mm | assumption — M3 bolt clearance |
mount_hole_inset_mm | 12 mm | assumption — not in the spec |
Print note: Print flat as modeled. Suggestion: 3-4 walls, ~25% infill.
Wheel ×2
parts/wheel.scadRolls on the ground; one per wheel position on the robot.
66.2 mm diameter x 25 mm wide, 6 mm shaft hole
| Parameter | Value | Where the number comes from |
|---|---|---|
wheel_diameter_mm | 66.2 mm | from spec wheel.diameter_m |
wheel_width_mm | 25 mm | from spec wheel.width_m |
shaft_diameter_mm | 6 mm | assumption — typical DC gearmotor shaft; measure yours |
hub_diameter_mm | 26.5 mm | derived — 0.4 x wheel diameter, for looks/strength |
lightening_hole_diameter_mm | 7.9 mm | derived — decorative; delete the loop below for a solid wheel |
Print note: Print flat as modeled. Suggestion: print one first and check the shaft fit before printing the rest.
Motor mount ×2
parts/motor_mount.scadSide plate that holds one drive motor so its shaft lines up with a wheel's axle.
41 mm wide plate, shaft hole at axle height 33.1 mm
| Parameter | Value | Where the number comes from |
|---|---|---|
shaft_center_height_mm | 33.1 mm | from spec wheel radius (diameter_m / 2) — the axle height above ground |
mount_width_mm | 41 mm | derived — wheel width + 16 mm of plate around the motor |
mount_height_mm | 44.1 mm | derived — reaches from the ground past the axle to the chassis plate |
mount_thickness_mm | 4 mm | assumption — not in the spec |
shaft_hole_diameter_mm | 6.4 mm | derived — shaft diameter + 0.4 mm slip fit |
flange_depth_mm | 16 mm | assumption — how far the bolting flange reaches under the chassis |
flange_hole_diameter_mm | 3.4 mm | assumption — M3 bolt clearance |
Print note: Suggestion: 40% infill — this part takes the motor's twist. The motor itself is not a printed part.
Caster ×2
parts/caster.scadBall caster that keeps a two-wheel robot level (one front, one rear). Placeholder for a real ball-caster unit.
ball diameter 30 mm (= ground clearance, so the ball tops out at the deck)
| Parameter | Value | Where the number comes from |
|---|---|---|
caster_ball_diameter_mm | 30 mm | from spec ground_clearance_m — ball top meets the deck underside |
caster_stem_height_mm | 10 mm | derived — reaches into/past the deck plate for bolting |
caster_stem_diameter_mm | 15 mm | derived — half the ball diameter |
Print note: Suggestion: expect a loose fit — sand or scale 1-2% for a snug cup. A bought ball caster rolls far better.
Lidar mount ×1
parts/lidar_mount.scadPost that raises the 2D lidar to the top of the robot so its scan plane clears the chassis.
post 170 mm tall, top disc 70 mm diameter
| Parameter | Value | Where the number comes from |
|---|---|---|
post_height_mm | 170 mm | derived — spec height minus deck and disc thicknesses |
post_diameter_mm | 12 mm | assumption — not in the spec |
lidar_disc_diameter_mm | 70 mm | assumption — typical 2D lidar puck; measure yours |
disc_thickness_mm | 3 mm | assumption — not in the spec |
Print note: Print upright as modeled. Suggestion: ~25% infill; the lidar itself is not a printed part.
Camera bracket ×1
parts/camera_bracket.scadBracket that holds a camera (rgb_camera) at the front of the robot.
44 x 34 mm plate, 12 mm lens hole
| Parameter | Value | Where the number comes from |
|---|---|---|
bracket_width_mm | 44 mm | assumption — small-camera class; not in the spec |
bracket_height_mm | 34 mm | assumption — not in the spec |
bracket_thickness_mm | 3 mm | assumption — not in the spec |
lens_hole_diameter_mm | 12 mm | assumption — measure your camera |
foot_depth_mm | 20 mm | assumption — how far the bolting foot reaches |
Print note: Print flat as modeled. Suggestion: the lens hole is a visual guide — measure your camera before drilling.
Reproduce it
Run these from a clone of the repository.
robotforge validate examples/andino.json
robotforge urdf examples/andino.json --out build/andino.urdf
robotforge cad examples/andino.json
robotforge run-gate examples/andino.json
robotforge harness examples/andino.json