Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions examples/airport model/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Airport Operations Simulation in Mesa: Towards Queueing and Resource Modeling Extensions

## Idea

This project investigates how Mesa can be used to model a real-world operational system where system dynamics are driven not only by agent interactions, but also by queues and constrained resources. The chosen case study is an airport operations simulator, where aircraft compete for limited runway capacity under priority and safety constraints.

The core objective is not only to implement the model, but to evaluate how well Mesa supports this class of systems and to identify missing abstractions that could be generalized for broader use.

---

## Reference to Previous Work

The work builds on an earlier standalone implementation:

[https://github.com/Vadim3377/SWE-project](https://github.com/Vadim3377/SWE-project)

The original project implemented a discrete-time airport simulation with:

* priority-based holding queues for inbound aircraft
* FIFO takeoff queues for outbound aircraft
* runway assignment and service logic
* statistical reporting (queue sizes, wait times, cancellations, etc.)

While functionally complete, this system was not structured within an agent-based modeling framework and lacked extensibility, standardised data collection, and interactive visualization.

---

## Transition to Mesa

The project was reimplemented using Mesa to explore how an operational system can be expressed in an ABM paradigm.

The mapping between the original system and Mesa is as follows:

* aircraft: `AircraftAgent`
* runways: `RunwayAgent`
* simulation engine: `AirportModel`
* queues: separate queue module (`queues.py`)
* statistics: Mesa `DataCollector`

This transition made the architecture more modular and reusable, and enabled integration with Mesa’s visualization tools. At the same time, it exposed limitations in Mesa when modeling systems that are primarily driven by queues and service constraints rather than spatial interactions.

---

## Learning Experience

The implementation was guided by Mesa tutorials and documentation, including:

* the introductory model tutorial for understanding agent and model structure
* time and scheduling concepts for designing the simulation loop
* data collection for tracking system metrics
* visualization using SolaraViz for interactive dashboards

This process provided a deeper understanding of Mesa’s design philosophy and highlighted how its abstractions apply to non-standard ABM use cases.

---

## Implementation and Description

The model simulates airport operations as a discrete-time system.

Aircraft are represented as agents with state variables including type (inbound or outbound), fuel level, emergency status, and waiting time. Inbound aircraft consume fuel over time and may escalate to emergency or be diverted if fuel falls below a threshold. Outbound aircraft may be cancelled if their waiting time exceeds a maximum limit.

Runways are modeled as service resources that process aircraft for landing or takeoff, with configurable service durations. Each runway maintains its own state, including current operation and remaining service time.

The system is driven by two queues. The holding queue is implemented as a priority queue where emergency aircraft are prioritised and FIFO ordering is preserved within priority levels. The takeoff queue is implemented as a FIFO queue.

Each simulation step performs the following sequence:

* update aircraft states (waiting time, fuel consumption)
* update runway service progress
* generate new aircraft arrivals
* update queue priorities and constraints
* assign runways to available aircraft
* collect statistics

Visualization is provided both through static plots and an interactive dashboard using SolaraViz, allowing real-time inspection of queue sizes, throughput, and runway utilisation.

---

## Observations

The implementation demonstrates that Mesa provides a strong structure for organizing models and collecting data, but that key elements of queueing systems must be implemented manually.

In particular:

* there are no built-in abstractions for queues or resource-constrained services
* visualization is primarily oriented toward spatial models rather than operational dashboards
* modeling of service systems requires combining agent logic with external scheduling and queue management

These observations align with the Mesa GSoC direction of evaluating what works well in practice and identifying missing components through implementation experience.

---

## Proposed Improvements

This project suggests a natural extension of Mesa in line with the 2026 project ideas, particularly the **behavioral framework initiative**, which emphasizes implementing models, identifying limitations, and proposing reusable improvements based on practical experience.

Based on this work, the following improvements are proposed:

A queueing and resource module could be introduced, providing reusable abstractions such as priority queues, FIFO queues, and service resources. These components would generalize beyond the airport model and support a wide class of systems including healthcare, logistics, and transportation.

A more flexible policy framework for resource allocation could allow users to define and compare strategies for scheduling and prioritization. In this project, runway assignment policies significantly affect system behaviour, suggesting the need for modular strategy definitions.

Visualization support could be extended to better accommodate non-spatial models, with built-in dashboard components for metrics, queue states, and resource utilisation rather than relying primarily on spatial portrayals.

Finally, example models in Mesa could be expanded to include operational systems such as airport or service-center simulations, complementing existing examples and improving accessibility for users working outside traditional spatial ABM domains.


94 changes: 94 additions & 0 deletions examples/airport model/agents.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# agents.py
from mesa import Agent


class AircraftAgent(Agent):
def __init__(
self,
model,
flight_id: str,
flight_type: str, # "inbound" or "outbound"
fuel_remaining: int | None = None,
emergency: bool = False,
):
super().__init__(model)
self.flight_id = flight_id
self.flight_type = flight_type
self.fuel_remaining = fuel_remaining
self.emergency = emergency

self.status = "scheduled" # scheduled, holding, takeoff_queue, landing, takeoff, landed, departed, diverted, cancelled
self.wait_time = 0
self.assigned_runway = None
self.arrival_order = None

def step(self):
# Aircraft logic is mostly passive in this model.
# The model coordinates queues and runway assignment.
if self.status in {"holding", "takeoff_queue"}:
self.wait_time += self.model.tick_size

if self.flight_type == "inbound" and self.status == "holding":
self.consume_fuel()

def consume_fuel(self):
if self.fuel_remaining is None:
return

self.fuel_remaining -= self.model.tick_size

if self.fuel_remaining <= self.model.minimum_fuel_threshold:
self.status = "diverted"
self.model.divert_aircraft(self)

elif self.fuel_remaining <= self.model.emergency_fuel_threshold:
self.emergency = True


# agents.py
class RunwayAgent(Agent):
def __init__(self, model, runway_id: str, mode: str = "mixed"):
super().__init__(model)
self.runway_id = runway_id
self.mode = mode # "landing", "takeoff", "mixed"
self.blocked = False
self.current_aircraft = None
self.remaining_service_time = 0
self.operation = None # "landing" or "takeoff"

def is_available_for(self, operation: str) -> bool:
if self.blocked:
return False
if self.current_aircraft is not None:
return False
if self.mode == "mixed":
return True
return self.mode == operation

def assign(self, aircraft, operation: str, duration: int):
self.current_aircraft = aircraft
self.operation = operation
self.remaining_service_time = duration
aircraft.assigned_runway = self.runway_id
aircraft.status = operation

def step(self):
if self.current_aircraft is None:
return

self.remaining_service_time -= self.model.tick_size

if self.remaining_service_time <= 0:
aircraft = self.current_aircraft

if self.operation == "landing":
aircraft.status = "landed"
self.model.landed_count += 1
else:
aircraft.status = "departed"
self.model.departed_count += 1

aircraft.assigned_runway = None
self.current_aircraft = None
self.operation = None
self.remaining_service_time = 0
77 changes: 77 additions & 0 deletions examples/airport model/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import solara
from mesa.visualization import SolaraViz, make_plot_component
from model import AirportModel


def runway_status_component(model):
with solara.Column():
solara.Markdown("## Runway Status")
for runway in model.runways:
aircraft = runway.current_aircraft
solara.Markdown(
f"""
**{runway.runway_id}**
- Mode: {runway.mode}
- Operation: {runway.operation or "idle"}
- Occupied: {"yes" if aircraft else "no"}
- Aircraft: {getattr(aircraft, "flight_id", "-")}
- Remaining time: {runway.remaining_service_time}
"""
)


def live_metrics_component(model):
total_waiting = len(model.holding_queue) + len(model.takeoff_queue)

with solara.Columns([1, 1, 1]):
with solara.Card("Queues"):
solara.Markdown(
f"""
**Holding:** {len(model.holding_queue)}
**Takeoff:** {len(model.takeoff_queue)}
**Total waiting:** {total_waiting}
"""
)

with solara.Card("Outcomes"):
solara.Markdown(
f"""
**Landed:** {model.landed_count}
**Departed:** {model.departed_count}
**Diverted:** {model.diverted_count}
**Cancelled:** {model.cancelled_count}
"""
)

with solara.Card("Time"):
solara.Markdown(
f"""
**Tick:** {model.tick_count}
**Sim time:** {model.sim_time} min
"""
)


model = AirportModel(
num_runways=2,
inbound_rate=12,
outbound_rate=12,
tick_size=1,
landing_duration=4,
takeoff_duration=3,
emergency_fuel_threshold=25,
minimum_fuel_threshold=10,
max_takeoff_wait=40,
)

page = SolaraViz(
model,
components=[
live_metrics_component,
runway_status_component,
make_plot_component(["holding_queue_size", "takeoff_queue_size"]),
make_plot_component(["landed", "departed", "diverted", "cancelled"]),
make_plot_component(["avg_wait_time"]),
],
name="Airport Simulation",
)
Loading