A Duckietown DB21 Duckiebot carrying a LIDAR and an environmental sensor, driving a space on its own, building a 2D map with SLAM, and geotagging temperature, humidity, pressure and air quality to exactly where each reading was taken — validated across eight simulated environments and on real hardware.
Everything below is built on a completely standard Duckietown DB21. Two sensors are bolted on, and the robot's own software only ever adds capability on top of the platform Duckietown already ships — nothing stock is modified.
An RPLIDAR C1 spins 360°, feeding a SLAM algorithm (gmapping, tuned against hector_mapping) that builds a 2D occupancy map and tracks the robot's position inside it as it drives.
Frontier exploration discovers the room's shape, then a coverage-aware patrol sweeps the known-free floor in rows — or down the centreline in a corridor too narrow to sweep — so the sensor actually crosses the whole space, not just the area near where it started.
A DFRobot SEN0335 (ENS160 + BME280) reads temperature, humidity, pressure and an air-quality index once a second. Every reading is stamped with the robot's map position at that instant and written to CSV.
The same pipeline runs whether the robot is real or simulated — only the sensor-facing nodes differ; every navigation and mapping node is identical code either way.
Stand still, take one LIDAR sweep, build a starting map.
Drive toward the nearest unmapped frontier until the map stops growing.
Lay out rows across the known floor, or a centreline in a narrow space.
Re-plan ~5×/second while driving; log every sensor reading, geotagged.
Map, actual path taken, and the CSV are pulled off before teardown.
Two independent safety layers run the entire time: a front-distance sensor feeds the path planner so it can route around close obstacles, and a last-resort veto refuses any forward command once something is too close — fail-closed, so a dead sensor stops the robot rather than silently permitting a collision. See the full report for the failure analysis this came out of.
Every room below is reconstructed live in your browser from the project's actual Gazebo world files — the exact geometry the simulated robot is tested against, not a mockup. Drag to rotate, scroll to zoom.
Rendered client-side with three.js, parsed directly from the project's .world SDF files — no server, no pre-baked 3D models.
Frontier exploration alone stops as soon as the map is complete — in an open room that can happen having barely moved the robot. The coverage-aware patrol that runs after it is what actually gets the sensor across the floor.
Each map is the robot's own SLAM output with every planned waypoint marked — green where the robot actually reached it, amber where it didn't.
Every simulated node above has a real-hardware counterpart running literally the same navigation and mapping code. The real corridor is the harder case on purpose — long, narrow, and feature-poor, which stresses SLAM far more than an open room.
Dashboard footage of a real autonomous corridor run, with an on-screen HUD showing live sensor readings and event captions synced to the robot's own logged data.
Gazebo GUI captures of complete, unattended autonomous runs — frontier exploration handing off to the coverage-aware patrol, in each of the project's simulated environments.
~5×4m, single obstacle — the baseline case.
Open space, sparse irregular obstacles.
Dense 3×4 desk grid — tight-aisle navigation.
Crossing a narrow doorway between separate spaces.
Long and feature-poor — a known SLAM stress test.
ROS Noetic packages, the Gazebo simulation setup, recorded hardware runs, and a devcontainer so the whole stack builds with no local ROS install.
gitlab.hua.gr/mobile-sensor-unitSystem design, the literature review, every ablation and failure analysis behind the numbers on this page.
Open the PDF