← Back to work
Autonomous Lawn Mower

Autonomous Lawn Mower

Personal robotics project: a fully custom autonomous mowing stack for a differential-drive robot with Livox LiDAR, running onboard on Linux with ROS 2 Jazzy. The goal was reliable coverage of an irregular lawn perimeter including plants along the edge without leaning on Nav2’s generic navigation servers. I designed a layered pipeline: LiDAR localization, 2.5D global costmap fusion, boustrophedon coverage planning, and a C++ path follower with its own state machine (mowing stripes, orthogonal turns, transit connectors, and local obstacle handling). An Android app over Bluetooth drives mission start, pause/resume, zone selection, and live map view. Field runs are logged to CSV telemetry so every stall, ghost obstacle, and corner trim can be traced back to the code.

Role

Software Engineering, Embedded Systems, ROS 2, Mobile (Android)

Sector

Robotics & Autonomous Systems

Year

2025-2026

Standard ROS navigation failed on the real lawn. Stripes drifted, corners were messy, and the robot kept replanning around grass, plants, and fence clutter. Nav2 worked great to reach a goal, not to mow a full garden in 17 cm zig-zags.

I rebuilt the stack around coverage. A planner breaks the lawn into ordered segments: mow, turn, transit, perimeter, with 90° corners instead of wide arcs. A C++ follower executes them with straight-line tracking and pivot assist on turns.

Perception is tuned for mower height: tall grass is filtered out, real obstacles are fused into a live costmap. At plants along the edge, the path trims in close and cuts a sharp corner instead of detouring around every bush.

Real missions exposed problems the sim tests didn't: phantom obstacles from grass speckle, pointless detours that left the mower braking for half a minute, deadlocks during stripe alignment, and blade control that had to match what the robot was actually doing, not what it planned to do next.

Each issue was traced and fixed from field data, not guesswork. Spin direction latched on entry. Escape routes only triggered when the mower was truly stuck. Ground filtering was widened so grass stays grass. Blade stop logic tied to segment type, so cutting only pauses on real transit, not mid-stripe.

Motion runs end-to-end: navigation commands down to closed-loop wheel control with SimpleFOC, plus serial drivers for the blade and drive motors, so path following and physical motion stay in sync on uneven grass.

Stack: ROS 2 Jazzy · C++ path follower · Python coverage planner · Livox + NDT · SimpleFOC motor control · Kotlin/Compose Android app · Foxglove sim (real stack, dummy mower)

More projects

Open to new opportunities

Get in touch

I'm always open to hearing from new people about their ideas, projects, or potential collaborations.