Skip to content

Latest commit

 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🤖 Lawn-Mowing Robot Using ROS

An autonomous lawn-mowing robot built on a custom differential-drive platform in ROS and simulated in Gazebo. Give it the size of the lawn and a number of laps, and it plans its own boustrophedon coverage route, drives it, and steers around obstacles using a Hokuyo LiDAR — then rejoins the route and carries on.

ROS Gazebo Python LiDAR License

The robot steering around an obstacle in Gazebo

The robot rounding an obstacle it has never seen before. Nothing is mapped in advance — the detour comes entirely from the live LiDAR scan.

Overview

The brief was to cover an entire bounded area with a differential-drive robot, with the boundary supplied as input. That splits cleanly into two problems that fight each other: following a planned route, and reacting to things the route knows nothing about. Solving them in one controller tends to produce a robot that either ignores obstacles or wanders off and never finishes the lawn.

Here they are two separate ROS nodes with a service between them, so exactly one is driving at any moment — and, crucially, a geometric condition that decides when the obstacle-avoider gives control back.

See It in Action

Driving the route Avoiding an obstacle
Robot driving straight toward a waypoint Robot steering around an obstacle
With a clear path the robot heads straight for the next waypoint. When the front LiDAR region sees something within 1 m, the wall follower takes over.

The planned sweep across the lawn:

Boustrophedon coverage pattern

Vertical passes one unit apart, alternating direction on each pass, repeated for the requested number of laps.

How It Works

flowchart LR
    G[Gazebo simulation] -->|/scan| P[go_to_point<br/>project.py]
    G -->|/odom| P
    G -->|/scan| W[wall_follower<br/>follow_wall.py]
    P -->|/cmd_vel| G
    W -->|/cmd_vel| G
    P -.->|/wall_follower_switch<br/>std_srvs/SetBool| W
Loading

1. Coverage planning (project.py). From the lawn length, width and lap count, goals() generates the boustrophedon waypoint list — up column 1, down column 2, up column 3, and so on, with the direction reversed on each successive lap. Consecutive duplicate points are collapsed so the path stays clean.

2. Waypoint driving. A four-state machine walks that list:

State Behaviour
0 fix yaw Rotate in place until the heading points at the next waypoint (tolerance π/90)
1 go straight Drive at 0.2 m/s with a proportional yaw correction, until within 0.1 m of the waypoint
2 wall following Hand control to the wall follower
3 done Stop and exit

3. Obstacle avoidance (follow_wall.py). The 720-sample LiDAR scan is reduced to five angular regions — right, fright, front, fleft, left — each the minimum range in its sector. A 1.5 m threshold selects one of three behaviours: find the wall, turn left, or follow the wall, keeping the obstacle to one side while circling it.

4. Handing control back. This is the part that makes the whole thing terminate. Re-entry is decided by the perpendicular distance from the robot to the straight line joining the last waypoint to the next one; once that drops below 0.1 m the planner takes back over. It is the classic Bug2 leave condition, and without it an obstacle detour has no principled end — the robot would either rejoin too early and re-collide, or keep following the obstacle's contour forever.

The Robot

Defined in lawn_mover/urdf/lawn_mover.urdf:

  • Differential drive — left and right driven wheels plus a front caster, via libgazebo_ros_diff_drive.so
  • Hokuyo LiDAR on hokuyo_link — 720 samples across a 180° field of view (−π/2 to π/2), 30 m maximum range, via libgazebo_ros_laser.so. Top-mounted, so obstacles cannot strike the sensor.
  • Joint states published by libgazebo_ros_joint_state_publisher.so

The lawn is a custom Gazebo world, lawn_mover/worlds/lawn_world.world.

Tech Stack

  • Middleware: ROS 1 (rospy, roslaunch, ROS services)
  • Simulation: Gazebo, URDF robot description, custom .world
  • Sensing: Hokuyo LiDAR via sensor_msgs/LaserScan, odometry via nav_msgs/Odometry
  • Control: geometry_msgs/Twist on /cmd_vel
  • Build: catkin (CMakeLists.txt, package.xml)

Repository Structure

LawnMoving-Robot-Using-ROS/
├── lawn_mover/                  # the ROS (catkin) package
│   ├── src/
│   │   ├── project.py           # go_to_point: coverage planning + waypoint driving
│   │   └── follow_wall.py       # wall_follower: LiDAR obstacle avoidance
│   ├── launch/
│   │   └── lawn_mover.launch    # Gazebo + world + robot + wall follower
│   ├── urdf/
│   │   ├── lawn_mover.urdf      # differential-drive robot with Hokuyo LiDAR
│   │   └── lawn_mover2.urdf
│   ├── worlds/
│   │   └── lawn_world.world     # custom Gazebo lawn with obstacles
│   ├── CMakeLists.txt
│   └── package.xml
├── docs/
│   ├── ROS-REPORT.docx          # full project report
│   └── ROSPPT.pptx              # project presentation
├── assets/                      # figures used in this README
├── README.md
└── LICENSE

Running the Project

Requires ROS 1 (Melodic or Noetic) on Linux with Gazebo, plus gazebo_ros, rospy, std_srvs, nav_msgs, sensor_msgs, geometry_msgs and tf.

  1. Copy the package into a catkin workspace and build it:

    cp -r lawn_mover ~/catkin_ws/src/
    cd ~/catkin_ws && catkin_make && source devel/setup.bash
  2. Launch Gazebo with the world, the robot, and the wall-following node:

    roslaunch lawn_mover lawn_mover.launch
  3. In a second sourced terminal, start the coverage planner:

    rosrun lawn_mover project.py

    It prompts for the lawn dimensions:

    Enter Length of lawn : 8
    Enter Width of lawn  : 8
    Enter number of laps : 1
    

The robot prints each waypoint as it reaches it and stops with Process Finished once the route is complete.

Note — the launch file starts only follow_wall.py. project.py runs separately because it needs an interactive terminal for the lawn dimensions.

Dataset

None. This is a simulation and control project — the robot acts on live LiDAR and odometry from Gazebo, so there is nothing to download.

Future Scope

  • Replace the fixed rectangular sweep with coverage of arbitrary polygonal boundaries.
  • Add SLAM so the robot builds and reuses a map of static obstacles across laps.
  • Track battery state and plan a return-to-base leg before it runs out.

Acknowledgments

Built for 19AIE213 – Robotic Operating System and Robot Simulation at Amrita School of Engineering, Bangalore (Amrita Vishwa Vidyapeetham), 2021, guided by Mr. Nippun Kumaar A. A., by Vishnu Sainadh Kedarisetty, Satwik Kukkadapu and Ashrith Vadde.

Documentation

About

Autonomous lawn-mowing robot in ROS + Gazebo: a differential-drive robot plans a boustrophedon coverage path and avoids obstacles from LiDAR using two cooperating ROS nodes.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages