Simulator
Overview
OpenMowerNext uses Webots as its simulation backend. Gazebo is no longer maintained in this repository.
The simulation is built around Webots-native resources:
worlds/openmower.wbtdefines the world, clock source, GPS reference, robot and docking station.protos/OpenMower.protodefines the robot model and stable Webots device names.protos/DockingStation.protodefines the charging dock model.resource/openmower_webots.urdfmaps Webots devices to ROS 2 topics andros2_control.
Getting Started
Install ROS dependencies first:
make depsRun the simulator from the repository root:
make simBy default this starts Webots with streaming enabled on port 1234, so another machine on the same LAN can open http://<host>:1234/index.html, for example http://lord.local:1234/index.html. The / endpoint is not a normal HTTP page and may return an empty response; the actual simulation stream is a WebSocket on the same port. If the viewer defaults to ws://localhost:1234, change it to ws://<host>:1234, for example ws://lord.local:1234, and click Connect. Foxglove is intentionally not started by the simulator launch; run it separately with make foxglove when needed.
For headless smoke tests on the development host, run:
WEBOTS_OFFSCREEN=1 ros2 launch open_mower_next sim.launch.py gui:=false mode:=fastIf Webots was installed by webots_ros2_driver, set WEBOTS_HOME=~/.ros/webotsR2025a/webots or use make sim, which sets it automatically when that directory exists. Headless Webots also needs xvfb and libxcb-cursor0 on Ubuntu.
The canonical development flow runs Webots and ROS 2 on the development host. GUI access can be done through Webots streaming, browser/VNC, or SSH forwarding depending on the workstation setup.
ROS Contract
The simulator publishes or serves the same ROS-facing contract used by the rest of the stack:
/clockfromRos2Supervisor/gps/fixfrom the Webots GPS device/imu/data_rawfrom the Webots IMU plugin/diff_drive_base_controller/odomfromdiff_drive_controller/power/charger_present,/power/charge_voltage, and/powerfromsim_node
Velocity commands still flow through twist_mux to /diff_drive_base_controller/cmd_vel.
Current State
- ✅ Webots world and robot model
- ✅ Webots ROS 2 driver launch
- ✅
webots_ros2_controlintegration - ✅ GPS device mapping
- ✅ IMU device mapping
- ✅ Charging and battery emulation using sim node
World Definition
#VRML_SIM R2025a utf8
EXTERNPROTO "../protos/OpenMower.proto"
EXTERNPROTO "../protos/DockingStation.proto"
WorldInfo {
title "OpenMowerNext Webots simulation"
basicTimeStep 10
coordinateSystem "ENU"
gpsCoordinateSystem "WGS84"
gpsReference -22.9 -43.2 0
}
Viewpoint {
orientation -0.330491 0.451759 0.828566 1.32217
position -2.3 -4.4 3.0
follow "openmower"
}
Background {
skyColor [
0.45 0.62 0.85
]
}
DirectionalLight {
direction -0.4 -0.2 -1
intensity 1
}
Solid {
translation 0 0 -0.005
children [
Shape {
appearance PBRAppearance {
baseColor 0.12 0.42 0.12
roughness 1
metalness 0
}
geometry DEF FLOOR_BOX Box {
size 20 20 0.01
}
}
]
name "grass_floor"
boundingObject USE FLOOR_BOX
}
OpenMower {
translation 0 0 0.0925
rotation 0 0 1 2.0944
name "openmower"
controller "<extern>"
}
DockingStation {
translation 1.5 1.5 0
name "docking_station"
}
Robot {
name "Ros2Supervisor"
controller "<extern>"
supervisor TRUE
}