Autonomous Rover
Prototype
A four-wheeled ground rover capable of basic obstacle avoidance using ultrasonic sensors. The chassis was designed in SolidWorks and 3D-printed; navigation logic runs on an Arduino Uno.
Mechanical Design
The challenge was to build a rover that could navigate an obstacle course entirely on its own, without any remote input. I needed a compact chassis stiff enough to handle uneven surfaces, yet light enough that two small DC motors could propel it at a usable speed.
Starting in SolidWorks, I modelled every structural component — the base plate, motor mounts, and sensor arm — as a parametric assembly so dimensions could be tweaked quickly. After a few FEA checks for stress at the motor mounts, I exported the parts for FDM 3D printing in PLA. Tolerances were dialled in over three print iterations until the wheel fit was snug with no slop.
The final chassis weighs just 340 g, runs on a 7.4 V LiPo pack, and has a ground clearance of 12 mm — plenty for indoor testing on carpet and tile.
Software & Sensing
An HC-SR04 ultrasonic sensor sits on a pan servo at the front. The Arduino Uno fires 40 kHz pulses every 60 ms and measures the echo return time. If an obstacle is detected within 25 cm, the rover halts, sweeps the servo left and right to compare distances, then steers toward the clearer path.
Motor speed is handled via PWM through an L298N H-bridge, giving independent control of each side. A simple PD correction loop keeps the rover tracking straight on open ground.
// Measure distance via HC-SR04
long getDistance() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH);
return duration * 0.034 / 2; // cm
}
void loop() {
long dist = getDistance();
if (dist < OBSTACLE_THRESHOLD) {
stopMotors();
int leftDist = scanSide(-60);
int rightDist = scanSide( 60);
(leftDist > rightDist) ? turnLeft() : turnRight();
} else {
driveForward();
}
}
// Reflection
What I Learned
Sensor Noise & Filtering
Raw ultrasonic readings are surprisingly noisy — stray echoes from walls and carpet fibres caused the rover to brake erratically. I implemented a five-sample rolling-median filter which cut false positives by ~80% and made steering decisions far more stable.
Motor Speed Calibration
No two DC motors are identical — even from the same pack, one side ran ~12% faster. I measured the open-loop RPM of each motor and offset the PWM duty cycle accordingly. Future iterations will use encoders for closed-loop speed matching.
Iterative 3D Printing
Tolerances that looked fine in SolidWorks didn't survive the printer's dimensional variance. I learned to design 0.3 mm of clearance into every press-fit joint and to prototype moving parts at 20% infill first before committing to structural prints.
// Explore Further
See It in Action
The full source code is on GitHub. A demo video walkthrough is on YouTube.