Two motor drivers, stacked
Why the first board had to go
The chassis originally drove its two gearmotors through an L298N — a bipolar Darlington bridge that drops about 2.5 V across its own outputs, so on a 12 V rail the motor sees roughly 9.5 V and the rest leaves as heat, rated 2 A per channel continuous. Two 37D gearmotors driving a six-bar walking linkage — and the friction of that linkage throws up current spikes constantly — do not sit comfortably under that number. It failed in the lab on stall current.
The brown-out was not a serial bug
Every time the motors accelerated or reversed under teleop the Arduino’s USB dropped,
the bridge logged Serial write failed, and it fell into a reconnect loop. It
reads like a driver problem and is not: motor back-EMF dumped current into the ground
return, the Arduino’s ground bounced with it, its USB 5 V went out of spec, and
the host concluded the device had been unplugged.
The two fixes
- A ground lead from the Arduino’s POWER header straight to the pack negative, bypassing two stacked shield connectors
- A 1000 µF / 35 V electrolytic across board #1’s POWER terminals, to absorb the current peaks
Frontier exploration
130 s of real exploration, at 3×Real robotThe map it is building, same 130 seconds
The robot is picking its own goals — nobody is driving it. Left and right are the same 130 seconds.
Reading the map. Gray is confirmed free space, dark navy occupied, cyan and pink Nav2’s inflation layers. Green is a frontier — the boundary between known and unknown. The shape opening on the right is a corridor and a stairwell, neither in the map when the run started.
The contribution
The classic frontier rule scores a candidate on distance and information gain. On a wheeled base that is fine — spinning in place is nearly free. On a six-bar walker it is the most expensive thing you can ask for: it slips constantly, which costs a great deal of extra distance, and every slip corrupts the odometry that localization depends on.
So I added an explicit turning penalty to the utility, and ran a controlled 2×2 ablation in simulation — penalty on/off, crossed with ideal vs. walking-mechanism physics — five runs per condition.
| β = 0 | β = 2.5 | |
| Accumulated heading change | 1899° | 1056° |
| Integrated path length | 20.97 m | 13.49 m |
| Coverage | 75.8% | 82.4% |
Cheaper and more complete at once. −44% turning and −36% path length would be worth little if the robot simply gave up early — coverage going up is what says it did not.
Navigation on the saved map
ROS 2 Humble · slam_toolbox · AMCL · Nav2Real robotPlanned path and live pose
What the stack is
slam_toolbox for graph SLAM, AMCL for localization on the saved map, and Nav2 with the Smac global planner, the DWB local controller and a behavior-tree navigator — all re-tuned for a velocity envelope about a third of what the defaults expect (0.31 → 0.10 m/s, 1.9 → 0.60 rad/s), with acceleration limits cut roughly eightfold.
The hard part
Textbook differential-drive kinematics did not describe this machine. Rather than trust the nominal geometry, I measured the four scalars that reconcile the model with the prototype: 15623 ticks per meter (1.57× the geometric value), a 0.3913 m effective wheelbase, a right-encoder correction, and a 120/255 PWM dead-zone below which the robot simply does not move.
How wrong is it, in meters?
| Sample points | N = 35 |
|---|---|
| Mean position error | 0.199 m |
| RMSE | 0.211 m |
| 95th percentile | 0.311 m |
| Specification ≤ 0.25 m | satisfied |
How the 35 samples were taken
The marks are strips of tape on the floor, surveyed once. A trial teleops the robot
through all seven; at each one the robot is stopped,
localization_rmse.py logs what AMCL believes, and the true
(x, y) is measured by hand off the tape. Five
trials × seven marks = 35 paired samples.
Why no IMU
Fusing an IMU through an EKF would absorb slip and sharpen heading, and it is the obvious next step. I left it out on purpose: I wanted to know what the LiDAR scan-matcher and the calibration were worth on their own. 0.211 m is that number.
What I actually did
The walking platform is not mine — it is the McCarthy-lab build at UC Irvine of an existing six-bar design. Mine is everything that makes it navigate: the electrical integration, the 20 Hz Arduino firmware, the parameter identification, the ROS 2 and Nav2 stack, the frontier utility and its ablation, and the physical error measurement.
- Electronics — two 70:1 gearmotors, stacked Cytron MD10 R2 drivers, an Arduino UNO trading velocity commands and encoder deltas with a Jetson Orin Nano at 20 Hz over USB-CDC, behind a 500 ms watchdog
- Operator interface — the RViz dock on the laptop screen in the opening clip is a custom plugin: emergency stop, phase switching, saved-map loading, pose reset, global speed scale
- Written up — submitted as the degree thesis at Dalian University of Technology