# Robust MAPF<sub>R</sub> Execution Experiments

This directory contains scripts to generate MAPF maps, tasks as well as scripts to analyze and visualize data collected during experiments.

Visit the following GitLab directory to access the MAPF<sub>R</sub> simulator used to run the experiments: 

[MAPF<sub>R</sub> simulator GitLab](https://gitlab.mff.cuni.cz/shvaikop/ciirc_warehouse_demo)

My main contributions to the simulator:

```
FleetControl/modules/manager/include/BetterADG.h
FleetControl/modules/manager/src/BetterADGNew.cpp
FleetControl/modules/utils/Comm/include/Agent.h
FleetControl/modules/utils/Comm/include/AgentPlanStep.h
FleetControl/modules/utils/Comm/include/AppConfig.h
FleetControl/modules/utils/Comm/include/Assignments.h
FleetControl/modules/utils/Comm/include/BoostLogger.h
FleetControl/modules/utils/Comm/include/GenericMessage.h
FleetControl/modules/utils/Comm/include/MathUtils.h
FleetControl/modules/utils/Comm/include/Point.h
FleetControl/modules/utils/Comm/src/Agent.cpp
FleetControl/modules/utils/Comm/src/AgentPlanStep.cpp
FleetControl/modules/utils/Comm/src/AppConfig.cpp
FleetControl/modules/utils/Comm/src/BoostLogger.cpp
FleetControl/modules/utils/Comm/src/MathUtils.cpp
FleetControl/modules/utils/Comm/src/SolverOutput.cpp
FleetControl/modules/utils/Comm/tests/test_DangerInterval.cpp
FleetControl/modules/utils/Comm/tests/test_MathUtils.cpp
```

## Table of Contents
- [Robust MAPF_R Execution Experiments](#robust-mapf_r-execution-experiments)
  - [Demos](#demos)
    - [10 agents with no action splitting](#10-agents-with-no-action-splitting)
    - [10 agents with adaptive action splitting](#10-agents-with-adaptive-action-splitting)
    - [20 agents with no action splitting](#20-agents-with-no-action-splitting)
    - [20 agents with adaptive action splitting](#20-agents-with-adaptive-action-splitting)
  - [Directory structure](#directory-structure)
    - [Mapf instance structure](#mapf-instance-structure)
  - [Statistics format](#statistics-format)
    - [1. Run-level (global) section](#1-run-level-global-section)
    - [2. Per-robot block `robot_<id>`](#2-per-robot-block-robot_id)

## Demos

## 10 agents with no action splitting

<video width="960" height="521" controls>
  <source src="demos/10_agents_no_split.mp4" type="video/mp4">
  demos/10_agents_no_split.mp4
</video>

## 10 agents with adaptive action splitting

<video width="960" height="521" controls>
  <source src="demos/10_agents_adaptive_split.mp4" type="video/mp4">
  demos/10_agents_adaptive_split.mp4
</video>

## 20 agents with no action splitting

<video width="960" height="521" controls>
  <source src="demos/20_agents_no_split.mp4" type="video/mp4">
  demos/20_agents_no_split.mp4
</video>

## 20 agents with adaptive action splitting

<video width="960" height="521" controls>
  <source src="demos/20_agents_adaptive_split.mp4" type="video/mp4">
  demos/20_agents_no_split.mp4
</video>


## Directory structure

```
.
├── congested/                # Benchmark map + instance generator
│   ├── {5,10,15,20,25,30}_agents/   # Pre-generated MAPF instances of varying sizes
│   ├── generate_instance.sh              # Generate new instances with cycles allowed
│   └── generate_instance_no_cycles.sh    # …same, but forbids cyclic goals
├── data/                     # Aggregated experiment outputs (JSON)
│   ├── aggregated_stats*.json           # Global statistics across runs
│   ├── cycles_stats_aggregated.json     # Cycle-specific metrics
│   └── number_actions_aggregated.json   # Actions taken by agents per run
├── demos/                    # Short demo videos of solver behaviour
│   ├── {10,20}_agents_{adaptive,no}_split.mp4
│   └── …                     # Side-by-side comparisons of split strategies
├── src/                      # All code lives here (import-safe)
│   ├── map_generator.py                  # Build grid-maps with tuned congestion
│   ├── mapf_task_generator.py            # Produce MAPF tasks in XML/YAML
│   ├── aggregate_stats*.py               # Crunch raw logs into JSON summaries
│   ├── visualize_*.py                    # Matplotlib plots for each paper figure
│   └── solution_xml_to_yaml.py           # Convert AA-SIPP output for analysis
├── requirements.txt          # Python dependencies (≈ Python 3.10)
└── README.md                 # You’re here 📖
```
### Mapf instance structure

There are pre-generated MAPF<sub>R</sub> instances on a 60x40 map and 5, 10, 15, 20, 25, 30 agents. For each number of agents there are multiple tasks. Each task directory has the following structure:

```
.
├── aa_sipp_m_tasks_log.xml               # Solution generated by AA-SIPP-m solver
├── aa_sipp_m_tasks.xml                   # Tasks in AA-SIPP-m format
├── agent_size_split_stats                # Json with statistics generated per experiment run
│   └── stats_0.json                      # Statistics from run with agent-size action splitting
├── fixed_split_stats                     # Statistics from runs with fixed-size action splitting
│   ├── stats_1.json                      # 1-unit long actions
│   ├── stats_2.json                      # ...
│   ├── stats_3.json
│   ├── stats_4.json
│   ├── stats_5.json
│   └── stats_6.json                      # 6-unit long actions
├── intersection_split_stats
│   ├── cycles_stats_out.json             # Statistics from run with adaptive splitting
│   └── stats_add_agent_size_split.json
├── no_split_stats                        # Statistics from runs with no action splitting
│   ├── cycles_stats_out.json
│   ├── stats_0.json
│   └── stats_adaptive_and_agent_size.json
├── robot_definitions.txt                 # Robot definitions for simulator
└── wd_sol.yaml                           # Solution in simulator format
```

## Statistics format

Each experiment run generates data in JSON format with the following information:

### 1. Run-level (global) section

| Key | Type | Description |
| --- | ---- | ----------- |
| `max_execution_time` | `float` | Longest wall-clock time any robot spent on its plan (`max(total_measured_time)`) <span title="seconds">[s]</span> |
| `sum_execution_time` | `float` | Sum of all robots’ pure execution times (`Σ total_execution_time`) [s] |
| `num_agents` | `int` | Number of agents in the instance |
| `replan_time` | `float` | CPU time the planner used for re-planning (0 if none) [s] |
| `replanned` | `int` | `1` ⇢ at least one global replan occurred; `0` ⇢ none |

---

### 2. Per-robot block `robot_<id>`

> All scalar metrics are wrapped in a **one-element list** so the schema is future-proof:  
> outer index = *attempt* (`try_0`, `try_1`, …), inner index = *action in that attempt*.

| Key | Shape | Meaning |
| --- | ----- | ------- |
| `action_ids` | `[[int]]` | Planner-assigned action indices (`0 = move`, `1 = wait`, …). |
| `action_times` | `[[float]]` | Nominal duration of each action (schedule) [s] |
| `delay_times` | `[[float]]` | Extra time spent waiting **before** executing each action [s] |
| `actions_completed` | `[int]` | Count of actions that actually finished in the attempt. |
| `completed_execution` | `[bool]` | `true` ⇢ robot reached final goal, `false` ⇢ run stopped early. |
| `total_execution_time` | `[float]` | Σ of `action_times` in the attempt [s] |
| `total_wait_time` | `[float]` | Σ of `delay_times` [s] |
| `total_measured_time` | `[float]` | `total_execution_time + total_wait_time` [s] |
| `wait+exec_time` | `[float]` | Duplicate of `total_measured_time` (legacy field). |


For aggregating statistics we combine these files into a single large JSON file with statistics from all runs.
