A real-time swarm intelligence simulation where autonomous agents cooperate to explore warehouses and retrieve objects. Built with a Python/FastAPI backend and a React/TypeScript frontend.
| Role | Colour | Responsibility |
|---|---|---|
| Scout | Green | Explore the map, report object locations to coordinators |
| Coordinator | Blue | Assign retrieval tasks, manage agent recharging |
| Retriever | Yellow | Navigate to objects, carry them to the deposit zone |
- A* pathfinding with dynamic replanning, forbidden-zone support and diagonal corner-cutting prevention
- Warehouse door directionality — entrance and exit cells are enforced via forbidden types so agents always enter/exit through the correct door
- A* path-distance warehouse selection — agents choose the optimal warehouse using real path length instead of Manhattan distance, combined with congestion and energy-feasibility scoring
- Swap & yield protocols — head-on corridor swaps,
ClearWayMessagechain negotiation, yield cooldown (3-step penalty after yielding)
- Frontier-based exploration with sub-linear distance weighting (
$d^{0.4}$ ), target lock, recent-targets blacklist and far-frontier preference - Two-level anti-clustering (hard distance filter + soft utility penalty)
- Stale coverage patrol — cyclic revisitation of old zones driven by a per-cell age matrix
- Passive relay + coordinator search — scouts relay map data and scan at 4× comm radius when no coordinator is nearby
- Vision-explored tracking with fog-of-war for
map_knownmode
- Object-biased centroid positioning — the centroid is weighted toward known objects when tasks are pending
- Boredom patrol — after 50 idle steps the coordinator leaves the centroid to explore
- Seek-retriever — actively moves toward the nearest retriever (with stale-position filtering) when tasks are pending
- Chokepoint detection and blocking heuristic for spatial awareness
- Sync rate limiting (max 1 sync every 10 steps per peer)
- Priority chain: P1 deliver → P2 recharge → P3 execute task → P3b opportunistic pickup → P4 self-assign → P4b verify dubious → P5 explore
- Hive-mind self-assignment with 4-layer safety (grid truth → claim age → peer queue → atomic claim); P4 now only considers vision-confirmed objects
- Stale claim takeover — claims older than 50 steps can be acquired by another retriever
- P3b opportunistic pickup — retriever claims extra objects within vision radius during transit
- Task queue reordering by Manhattan distance at every step; invalid tasks (absent from both
known_objectsanddubious_objects) are dropped immediately - Stale task cancellation on map share — tasks for missing objects are dropped immediately
- Peer yield via
TaskStatusMessageand peer-to-peer object/cargo broadcast viaRetrieverEventMessage - Cargo drop on energy depletion — objects are released on adjacent cells and broadcast to peers
- Dubious objects (
dubious_objects+dubious_objects_step) — two-tier knowledge model where only direct ray-cast vision confirms an object; relay/peer/coordinator-assigned unknowns are demoted to dubious and verified lazily at P4b- Four demotion paths: relay
MapDataMessagemerge, age-based stale-demote after 30 steps (active task-queue entries exempt), peerRetrieverEventMessage, unknownTaskAssignmenttarget - Timestamp-aware tombstone pruning: a tombstone clears a dubious entry only if it is at least as recent as the dubious record, preventing old tombstones from invalidating newer leads
- Four demotion paths: relay
- Exploration momentum fix —
_last_explore_targetis saved before clearing a reached frontier; used as directional fallback inselect_best_frontierso the retriever keeps pushing into unexplored territory instead of immediately backtracking map_knownexploration —_explored_ratiouses only walkable cells (nav_map == 0) as denominator, eliminating the obstacle-inflation artifact near walls;unknown_mass_atcallback counts walkable+unscanned cells in radius 8 around each frontier for accurate scoring
- Radius-based inter-agent communication (scout → coordinator → retriever)
- Timestamped message wrappers with "newest wins" merge
- Atomic
try_claim_objectprotocol with age-based takeover and energy preemption - Tombstone mechanism for stale objects — prevents re-propagation of already-collected objects;
_confirmed_goneset tracks cells directly observed as empty for pre-scrubbing outgoingMapDataMessage - Relay → dubious redirect — the retriever intercepts base-class relay merges: objects added to
known_objectsby aMapDataMessageare immediately moved todubious_objects; only the agent's own vision can promote an entry to confirmed, preventing the relay from reintroducing demoted objects every step messages_sentcounter per recipient for communication cost metrics
- HTML5 Canvas grid rendering streamed over Socket.IO
- Fog-of-war / scan fog — unexplored cells are dimmed, toggleable per-agent or global
- Resizable panel layout (agents · map · metrics · controls)
- Click on any agent in the grid to select it and view its details
- Timeline slider with step history — scrub back through past simulation states
- Benchmark panel with multi-run execution and CSV export
- Map editor for drawing custom scenarios
- Dirty settings reminder — visual warning when unsaved parameter changes exist
- Log-scale speed slider with 1× label
- ⚡ "Wake up backend" button — polls
/api/healthuntil Render cold-starts (~30 s)
Animated arcs appear at the start of each simulation step and fade out as agents move. Each arc represents a message sent from one agent to another during that step.
| Arc colour | Message type | Direction |
|---|---|---|
🔵 Blue (#60a5fa) — thick + glow |
task_assignment |
Coordinator → Retriever |
🟡 Amber (#fbbf24) |
object_location |
Scout → Coordinator |
🟠 Orange (#fb923c) |
retriever_event (spotted / cargo drop) |
Retriever → Coordinator or Peer |
🟢 Emerald (#34d399) |
task_status |
Retriever → Coordinator or Peer |
🟣 Violet (#a78bfa) — dashed |
map_data (map relay) |
Any agent → nearby agents |
🔷 Indigo (#818cf8) — dashed |
coordinator_sync |
Coordinator → Coordinator |
Arcs are drawn as quadratic Bézier curves with a perpendicular offset so overlapping arcs between the same two agents remain distinguishable. A small arrowhead indicates the direction of the message.
Receive a message when a simulation starts, completes or is stopped (see Environment variables).
├── 📁 backend
│ ├── 📁 agents
│ │ ├── 🐍 __init__.py
│ │ ├── 🐍 base_agent.py
│ │ ├── 🐍 coordinator_agent.py
│ │ ├── 🐍 retriever_agent.py
│ │ └── 🐍 scout_agent.py
│ ├── 📁 algorithms
│ │ ├── 🐍 __init__.py
│ │ ├── 🐍 collision_avoidance.py
│ │ ├── 🐍 exploration.py
│ │ └── 🐍 pathfinding.py
│ ├── 📁 api
│ │ ├── 🐍 __init__.py
│ │ ├── 🐍 main.py
│ │ ├── 🐍 session_registry.py
│ │ ├── 🐍 simulation_manager.py
│ │ ├── 🐍 telegram_notifier.py
│ │ └── 🐍 websocket_manager.py
│ ├── 📁 config
│ │ ├── 🐍 __init__.py
│ │ ├── 🐍 config_loader.py
│ │ ├── 🐍 schemas.py
│ │ └── 🐍 settings.py
│ ├── 📁 core
│ │ ├── 🐍 __init__.py
│ │ ├── 🐍 communication.py
│ │ ├── 🐍 decision_maker.py
│ │ ├── 🐍 framework.py
│ │ ├── 🐍 grid_manager.py
│ │ └── 🐍 warehouse_model.py
│ ├── 📁 metrics
│ │ ├── 🐍 __init__.py
│ │ └── 🐍 collector.py
│ └── 🐍 __init__.py
├── 📁 configs
│ ├── ⚙️ A.json
│ └── ⚙️ B.json
├── 📁 docs
│ ├── 📁 benchmarks
│ │ ├── 📁 A
│ │ │ ├── 🖼️ efficiency.png
│ │ │ ├── 🖼️ energy.png
│ │ │ ├── 🖼️ messages.png
│ │ │ ├── 🖼️ retrieval.png
│ │ │ ├── 🖼️ snapshot_0S-0C-5R_map_known.png
│ │ │ ├── 🖼️ snapshot_0S-0C-5R_unknown.png
│ │ │ ├── 🖼️ snapshot_1S-1C-3R_map_known.png
│ │ │ ├── 🖼️ snapshot_1S-1C-3R_map_known_no-seek.png
│ │ │ ├── 🖼️ snapshot_1S-1C-3R_unknown.png
│ │ │ ├── 🖼️ snapshot_1S-1C-3R_unknown__no-seek.png
│ │ │ ├── 🖼️ steps_comparison.png
│ │ │ └── 🖼️ summary_table.png
│ │ └── 📁 B
│ │ ├── 🖼️ efficiency.png
│ │ ├── 🖼️ energy.png
│ │ ├── 🖼️ messages.png
│ │ ├── 🖼️ retrieval.png
│ │ ├── 🖼️ snapshot_0S-0C-5R_map_known.png
│ │ ├── 🖼️ snapshot_0S-0C-5R_unknown.png
│ │ ├── 🖼️ snapshot_1S-1C-3R_map_known.png
│ │ ├── 🖼️ snapshot_1S-1C-3R_map_known_no-seek.png
│ │ ├── 🖼️ snapshot_1S-1C-3R_unknown.png
│ │ ├── 🖼️ snapshot_1S-1C-3R_unknown__no-seek.png
│ │ ├── 🖼️ steps_comparison.png
│ │ └── 🖼️ summary_table.png
│ ├── 📁 latex
│ │ ├── 📁 assets
│ │ ├── 📁 parts
│ │ │ ├── 📄 baseagent.tex
│ │ │ ├── 📄 benchmarks.tex
│ │ │ ├── 📄 coordinator.tex
│ │ │ ├── 📄 frontespizio.tex
│ │ │ ├── 📄 retriever.tex
│ │ │ └── 📄 scout.tex
│ │ ├── 📕 relazione.pdf
│ │ └── 📄 relazione.tex
│ ├── 📕 20260226-progetto.pdf
│ └── 📝 PARAMETERS.md
├── 📁 frontend
│ ├── 📁 public
│ │ └── 🖼️ favicon.svg
│ ├── 📁 src
│ │ ├── 📁 components
│ │ │ ├── 📄 AgentList.tsx
│ │ │ ├── 📄 BenchmarkPanel.tsx
│ │ │ ├── 📄 ControlPanel.tsx
│ │ │ ├── 📄 GridCanvas.tsx
│ │ │ ├── 📄 MapEditor.tsx
│ │ │ ├── 📄 MetricsDisplay.tsx
│ │ │ └── 📄 TimelineSlider.tsx
│ │ ├── 📁 hooks
│ │ │ ├── 📄 useBenchmark.ts
│ │ │ ├── 📄 useSimulation.ts
│ │ │ └── 📄 useStepHistory.ts
│ │ ├── 📁 presets
│ │ │ └── 📄 index.ts
│ │ ├── 📁 types
│ │ │ └── 📄 simulation.ts
│ │ ├── 📄 App.tsx
│ │ ├── 🎨 index.css
│ │ ├── 📄 main.tsx
│ │ └── 📄 vite-env.d.ts
│ ├── ⚙️ .eslintrc.cjs
│ ├── 📄 bun.lock
│ ├── 🌐 index.html
│ ├── ⚙️ package.json
│ ├── 📄 postcss.config.js
│ ├── 📄 tailwind.config.js
│ ├── ⚙️ tsconfig.json
│ ├── ⚙️ tsconfig.node.json
│ └── 📄 vite.config.ts
├── ⚙️ .gitignore
├── 📄 LICENSE
├── 📝 QUICK_START.md
├── 📝 README.md
├── 🐍 evaluation.py
├── 📄 format.ps1
├── ⚙️ pyproject.toml
├── ⚙️ render.yaml
├── 📄 start.ps1
├── 📄 start.sh
├── 📄 uv.lock
└── ⚙️ vercel.json
git clone https://github.com/GiuseppeBellamacina/Warehouse-Swarm-Intelligence-System.git
cd Warehouse-Swarm-Intelligence-SystemCopy and edit the backend environment file:
cp .env.example .env
# edit .env — set ALLOWED_ORIGINS, and optionally TELEGRAM_BOT_TOKEN / TELEGRAM_CHAT_IDCopy and edit the frontend environment file:
cp frontend/.env.example frontend/.env
# VITE_BACKEND_URL=http://localhost:8000 (default, no change needed for local dev)uv sync
uv run python -m backend.api.main
# → http://localhost:8000 | API docs: http://localhost:8000/docscd frontend
bun install
bun run dev
# → http://localhost:3000| Variable | Default | Description |
|---|---|---|
HOST |
0.0.0.0 |
Bind address |
PORT |
8000 |
Bind port |
ALLOWED_ORIGINS |
http://localhost:3000,... |
Comma-separated CORS origins |
TELEGRAM_BOT_TOKEN |
(empty) | Bot token from @BotFather — leave empty to disable |
TELEGRAM_CHAT_ID |
(empty) | Your chat ID from @userinfobot |
| Variable | Default | Description |
|---|---|---|
VITE_BACKEND_URL |
http://localhost:8000 |
Backend base URL |
| Service | Platform | Config file |
|---|---|---|
| Frontend | Vercel | vercel.json |
| Backend | Render | render.yaml |
Commits that touch only README.md, QUICK_START.md or files inside docs/ will not trigger a rebuild on either platform.
# Backend
uv run black backend/
uv run ruff check --fix backend/
# Frontend
cd frontend && bun run lintOr run the helper script:
.\format.ps1evaluation.py runs all reference configurations and reports results. It mirrors the same SimulationManager / SimulationAgentsConfig defaults used by the backend API.
python evaluation.py # quick summary, no images
python evaluation.py -v # verbose (agent log lines)
python evaluation.py --imgs # generate benchmark charts and snapshots
python evaluation.py --seed 42 # override random seed for all maps
python evaluation.py --maps A B # run only the specified map(s)
python evaluation.py --mode known # run only map_known configs
python evaluation.py --mode unknown # run only unknown configs
python evaluation.py --seed-mine 0-199 # find the best seed in a range
--maps and --mode filters are applied to both normal evaluation and --seed-mine mode. Charts and per-config PNG snapshots are saved to docs/benchmarks/<map>/.
MIT — developed for the Multi-Agent Systems course project.
