- R 72.7%
- Makefile 10.6%
- Dockerfile 6.3%
- HTML 6.3%
- Shell 4.1%
| .forgejo/workflows | ||
| cache | ||
| doc | ||
| graphics/6 | ||
| lib | ||
| out | ||
| src | ||
| .1_session-info.txt | ||
| .2_session-info.txt | ||
| .3_session-info.txt | ||
| .4_session-info.txt | ||
| .5_session-info.txt | ||
| .6_session-info.txt | ||
| .gitattributes | ||
| .gitignore | ||
| .gitmodules | ||
| .lfsconfig | ||
| 1-AoI_Raster.html | ||
| 1-AoI_Raster.Rmd | ||
| 2-Per-Cell_AoI.html | ||
| 2-Per-Cell_AoI.Rmd | ||
| 3-Parameter_Study.Rmd | ||
| 4-Required_Penetration.html | ||
| 4-Required_Penetration.Rmd | ||
| 5-Cell_Reachability.html | ||
| 5-Cell_Reachability.Rmd | ||
| 6-No_AoI.html | ||
| 6-No_AoI.Rmd | ||
| AGENTS.md | ||
| Containerfile | ||
| envmon.sif | ||
| envmon.sumocfg | ||
| Makefile | ||
| parallel.sbatch | ||
| README.md | ||
| VERSIONS | ||
envmon
R-based geospatial analysis of Age of Information (AoI) in vehicular sensor networks. Uses SUMO traffic simulation traces from the Luxembourg LuST scenario to study how well moving vehicles can keep grid cells up-to-date with sensor readings (e.g. CO2 pollution). The core question: what penetration rate of sensor-equipped vehicles is needed to maintain fresh information across a city grid?
Prerequisites
| Dependency | Notes |
|---|---|
| R 4.x | The Containerfile pins ghcr.io/rocker-org/geospatial:4.5.1 for local container builds; local installs need the packages listed there |
| Podman (or Docker) | For containerised builds; skip if using LOCAL_R=1 |
| Git LFS | Default hydration is about 8 GiB after excluding envmon.sif; notebooks use the full LuST trace and precomputed result Parquet files |
| csv2parquet | From domoritz/arrow-tools — used in the data pipeline |
| SUMO 1.8.0 | Only needed to regenerate the raw trace; lib/sumo is a source submodule and must be built before lib/sumo/bin/sumo exists |
Getting Started
Committed *.html files are the fastest review path. Rendering notebooks is the reproducibility check.
# Clone the public repository
git clone https://code.fabimi.net/luna/envmon.git
cd envmon
# Pull LFS objects
git lfs install
git lfs pull
# Optional: retrieve the Singularity image for SLURM/HPC use
git lfs pull -I envmon.sif
Optional submodules
Only needed for the Data Pipeline; not needed to render notebooks from committed LFS data.
git submodule update --init lib/LuSTScenario lib/sumo
Container (recommended)
make container.exists # build the Podman image
make PODMAN=docker container.exists # build with Docker
make 1-AoI_Raster.html # render a notebook inside the container
Local R
Install the R packages listed in the Containerfile, then prefix commands with LOCAL_R=1:
LOCAL_R=1 make 6-No_AoI.html
Data Pipeline
Optional: cache/envmon.parquet is committed via LFS, so reviewers do not need to run SUMO before rendering notebooks.
The trace data is produced in three sequential steps (each target depends on the previous):
SUMO simulation ──► FCD XML ──► CSV ──► Parquet
make out/envmon.fcd.xml # 1. Run SUMO → Floating Car Data XML
make out/envmon.csv # 2. xml2csv.py → semicolon-delimited CSV
make cache/envmon.parquet # 3. csv2parquet → Parquet (used by notebooks)
make out/envmon.fcd.xml requires a built SUMO binary at lib/sumo/bin/sumo; make out/envmon.csv uses SUMO's tools/xml/xml2csv.py; make cache/envmon.parquet requires csv2parquet.
Analysis Notebooks
| # | File | Purpose | Key Parameters |
|---|---|---|---|
| 1 | 1-AoI_Raster.Rmd |
Single-vehicle AoI visualisation on a raster grid | frame_duration |
| 2 | 2-Per-Cell_AoI.Rmd |
Per-cell AoI for sampled vehicle subsets | penetration_rate |
| 3 | 3-Parameter_Study.Rmd |
Compute-heavy sweep under default params (seq_len(10) × c(0.1,0.3,0.7,0.9) × 10 workers) |
repetitions, penetration_rates, no_workers |
| 4 | 4-Required_Penetration.Rmd |
Determine the required penetration rate | (loads pre-computed results) |
| 5 | 5-Cell_Reachability.Rmd |
Grid cell reachability analysis | sample_size, time windows |
| 6 | 6-No_AoI.Rmd |
Visit-based metric without AoI calculation | slot_width, penetration_rate |
3-Parameter_Study.html is intentionally not committed because the full default render is a parameter sweep; CI and smoke runs use reduced parameters.
Rendering
make 3-Parameter_Study.html # full default sweep in the container
LOCAL_R=1 make 3-Parameter_Study.html # full default sweep with local R
# Recommended smoke render for notebook 3
R --vanilla -e 'rmarkdown::render("3-Parameter_Study.Rmd", params=list(repetitions=seq(1), penetration_rates=c(0.001)))'
# Custom parameters
R --vanilla -e 'rmarkdown::render("2-Per-Cell_AoI.Rmd", params=list(penetration_rate=0.001))'
Extracting a standalone R script
make 3-Parameter_Study.R # runs knitr::purl() to extract R code
Batch Processing (SLURM)
src/run-aoi.R is a standalone CLI for computing AoI on an HPC cluster:
Rscript src/run-aoi.R \
--penetration_rate 0.01 \
--repetition 1 \
--cell_size 200 \
--crs 32632 \
--busy_start 28800 --busy_end 32400 \
--calm_start 57600 --calm_end 61200
Only --penetration_rate is required; the rest have sensible defaults. Output goes to out/{SLURM_ARRAY_JOB_ID}/{SLURM_ARRAY_TASK_ID}/ on a cluster, or out/local/{UUID}/ for local runs. Each run produces aoi.parquet, grid.shp, and session-info.txt.
See parallel.sbatch for the SLURM array job template.
Project Structure
.
├── 1-AoI_Raster.Rmd … 6-No_AoI.Rmd # analysis notebooks
├── Makefile # build automation
├── Containerfile # Podman/Docker image definition
├── VERSIONS # pinned tool versions
├── envmon.sumocfg # SUMO simulation config
├── parallel.sbatch # SLURM batch script
├── src/
│ ├── helpers.R # shared functions (load, grid, AoI pipeline)
│ └── run-aoi.R # standalone CLI for batch AoI computation
├── cache/ # cached data (Parquet, RData, shapefiles)
├── out/ # pipeline outputs and batch results
├── lib/
│ ├── sumo/ # SUMO v1_8_0 (git submodule)
│ └── LuSTScenario/ # Luxembourg traffic scenario (git submodule)
├── graphics/ # generated figures plus tracked graphics/6/aoi-problem.png input illustration
└── doc/ # presentations
CI
Forgejo Actions renders all six notebooks with reduced parameters on every pull request and uploads the HTML output as artifacts.