A cooperative perception and navigation framework for a team of mobile robots tasked with locating the source of a gas plume in a cluttered environment.
The architecture abandons the traditional leader–follower paradigm in favor of a fully decentralized strategy: each robot maintains its own state estimation, perception modules, and decision-making, exchanging information with neighboring agents through peer-to-peer (V2V) communication. Perception, estimation, and control all emerge from local sensing and the sharing of asynchronous measurements.
Authors: AlexBarbi · matteogrisenti · Moska002 — University of Trento
- Overview
- System Architecture
- Project Structure
- Installation
- Running the Simulation
- Running Playback
- Tests & Experiments
A team of mobile robots is deployed in an unknown, cluttered environment containing a gas source and an ambient wind field. Without any centralized coordination, the swarm must autonomously:
- Explore the environment,
- Estimate each robot's pose (SLAM), and
- Collaboratively localize the source of the gas release.
The system combines several complementary modules — local EKF-based localization, cooperative V2V updates, particle-filter gas source estimation, linear consensus, and adaptive formation control — so the swarm can jointly explore and progressively converge toward the gas source.
- Gas dispersion is modeled with a 2D turbulent puff-dispersion model, combining a Lattice Boltzmann Method (LBM) wind engine with a plume framework (Pompy). Continuous emission is discretized into expanding spherical puffs; puffs colliding with walls are removed (no tunneling), and a time-decay mechanism ages them out.
- Robots use a unicycle model with zero-mean Gaussian noise injected into the control inputs to emulate odometry degradation. Each agent carries a heterogeneous sensor suite: a 2D LiDAR (obstacles + peer tracking), a Metal-Oxide (MOX) gas sensor, and an ultrasonic anemometer (wind vane). Every sensor model adds calibrated white Gaussian noise.
Each robot solves its own SLAM problem. The Extended Kalman Filter is used exclusively for pose estimation, while mapping is handled separately via a passively-updated occupancy grid — a deliberate choice favoring robust localization and multi-robot computational efficiency over full-covariance mapping.
- Prediction from odometry / commanded control.
- Scan-matching update: a grid-based scan matcher searches candidate poses to produce a pseudo-measurement of the robot pose.
- Loop-closure: keyframes (pose + normalized LiDAR signature) are compared over time; a valid match below a cost threshold triggers an extra EKF correction that bounds long-term drift.
- Occupancy grid maintained in log-odds via Bresenham ray tracing, used for collision checking during navigation.
20-loop test: full EKF-SLAM vs. dead-reckoning — estimated trajectories, uncertainty |Σ|, and cumulative RMSE.
Robots periodically broadcast their pose belief and a compact summary of their gas-source belief. Peers detected in the LiDAR scan are associated to broadcast poses, and the relative detection is folded into the same EKF as an additional measurement — correcting both position and heading. Measurement noise is computed dynamically by combining the local LiDAR covariance with the peer's broadcast uncertainty.
The report analyzes the classic EKF weakness of untracked cross-correlation (data incest) by comparing No-V2V, bidirectional, and unidirectional topologies, showing how a unidirectional chain provides a drift-free anchor that keeps the receiving robots' error bounded.
Each robot independently runs a Particle Filter over source hypotheses
s = [x, y, Q] (position + emission rate). A particle filter is used because
the concentration measurement model is strongly non-linear.
- Likelihood uses a downwind Gaussian-plume model with a near-field radial fallback, evaluated in log-space. Two regimes are handled: a no-gas-detected exponential decay penalty and a gas-detected log-normal likelihood.
- GDM modifier penalizes particles in explored-but-empty areas and gently rewards those in confirmed-gas zones.
- Tempering scales the log-likelihood to avoid overconfidence from high sampling frequency.
- Systematic resampling (triggered on effective sample size) with exploratory injection and a random-walk perturbation to avoid degeneracy.
Particle-filter source estimation with full Gas Distribution Map (GDM) integration.
A secondary spatial memory that maps detected concentrations with an associated uncertainty (from SLAM position uncertainty + olfactory noise). It maintains a coverage map and a weighted-readings map, giving the swarm a global, temporary understanding of the gas used to correct the (non-persistent) particle filter.
To converge on a common estimate, each robot fits a Gaussian to its local
particle distribution, converts it to information form, and runs a fixed number
of average-consensus steps over a bidirectional-ring communication graph using
Metropolis weights. Every agent then reconstructs the network-average source
estimate μ_LC, so a single robot losing the plume no longer compromises the
swarm.
A two-layer hierarchy separating strategy from tactics:
- Target Definition (strategic) — two macro-states:
- SCATTER: no gas detected yet; robots disperse to maximize coverage.
- FORMATION: once any node detects gas above threshold, the whole fleet
transitions and selects a target from the consensus estimate
μ_LC, the local particle population, and GDM coverage, via three sequential rules (Direct Exploration → Guided Exploration → Exploitation).
- Navigation Policy (tactical / APF) — a potential-field superposition of formation, mission, inter-robot repulsion, and obstacle forces, plus an anti-stall spiral recovery to re-enter the plume edge.
Representative final run: the swarm in formation around the current source estimate.
The project is organized into the following main directories:
| Directory | Contents |
|---|---|
config/ |
YAML configuration files for the different simulation scenarios. |
controllers/ |
Low-level navigation and autonomous exploration / swarm-control logic. |
estimation/ |
Estimator classes: EKF-SLAM, particle filter, gas map, linear consensus, fusion, and shared utils (scan matcher, loop closure). |
record/ |
Recording of simulation runs, storing data for post-evaluation and playback. |
sim/ |
Core Simulation class integrating all components + environment, gas, wind, robot, and sensor models. |
test/ |
Test scripts and experiments validating the individual components. |
viz/ |
Render class for live visualization, playback, and gas-specific rendering panels. |
sudo apt-get update
sudo apt-get install libopenmpi-dev openmpi-bin python3.12-devpip install -r requirements.txtpython -m sim.wind_modelRun the main simulation loop:
python -m test.test_simulationRun with profiling:
python -m cProfile -s cumtime test/test_simulation.py > profile_results.txtPlay back a recorded simulation:
python -m test.test_visualization_recordNB: Open the test file and set the
file_to_playvariable to the path of the record you want to replay.



