handoverlab 2.4.1__tar.gz → 2.4.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {handoverlab-2.4.1 → handoverlab-2.4.2}/CHANGELOG.md +42 -1
- {handoverlab-2.4.1 → handoverlab-2.4.2}/CITATION.cff +5 -2
- {handoverlab-2.4.1 → handoverlab-2.4.2}/PKG-INFO +66 -18
- {handoverlab-2.4.1 → handoverlab-2.4.2}/README.md +65 -17
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/calibration-3gpp.md +3 -2
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/comparison.md +2 -2
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/guides/beams-layers.md +9 -8
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/guides/buffers.md +15 -9
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/guides/daps-ltm.md +4 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/guides/dual-connectivity.md +4 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/guides/fading.md +11 -3
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/guides/indoor-rural.md +17 -15
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/guides/learning-rule.md +4 -3
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/guides/mro.md +15 -9
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/guides/scheduler.md +12 -6
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/guides/ue-beams.md +4 -0
- handoverlab-2.4.2/docs/images/buffers.png +0 -0
- handoverlab-2.4.2/docs/images/dashboard-charts.png +0 -0
- handoverlab-2.4.2/docs/images/dashboard-compare.png +0 -0
- handoverlab-2.4.2/docs/images/dashboard-where.png +0 -0
- handoverlab-2.4.2/docs/images/dashboard.png +0 -0
- handoverlab-2.4.2/docs/images/dual-connectivity.png +0 -0
- handoverlab-2.4.2/docs/images/fading.png +0 -0
- handoverlab-2.4.2/docs/images/mro.png +0 -0
- handoverlab-2.4.2/docs/images/procedures.png +0 -0
- handoverlab-2.4.2/docs/images/scheduler.png +0 -0
- handoverlab-2.4.2/docs/images/traffic.png +0 -0
- handoverlab-2.4.2/docs/images/ue-beams.png +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/index.md +8 -4
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/performance.md +19 -5
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/indoor-office-4ghz.md +1 -1
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/rural-700mhz.md +1 -1
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/suburban-sma-7ghz.md +1 -1
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/stability.md +1 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/standard-compliance.md +1 -1
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/tutorials/own-rule.md +10 -9
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/tutorials/tuning-study.md +1 -1
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/user_guide.md +27 -14
- {handoverlab-2.4.1 → handoverlab-2.4.2}/pyproject.toml +1 -1
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/__init__.py +1 -1
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/scenarios/cards/indoor-office-4ghz.yaml +1 -1
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/scenarios/cards/rural-700mhz.yaml +1 -1
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/scenarios/cards/suburban-sma-7ghz.yaml +1 -1
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab.egg-info/PKG-INFO +66 -18
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab.egg-info/SOURCES.txt +17 -0
- handoverlab-2.4.2/tools/make_buffers_figure.py +107 -0
- handoverlab-2.4.2/tools/make_dashboard_screenshots.py +219 -0
- handoverlab-2.4.2/tools/make_dc_figure.py +127 -0
- handoverlab-2.4.2/tools/make_fading_figure.py +127 -0
- handoverlab-2.4.2/tools/make_mro_figure.py +135 -0
- handoverlab-2.4.2/tools/make_procedures_figure.py +107 -0
- handoverlab-2.4.2/tools/make_scheduler_figure.py +138 -0
- handoverlab-2.4.2/tools/make_traffic_figure.py +84 -0
- handoverlab-2.4.2/tools/make_ue_beams_figure.py +123 -0
- handoverlab-2.4.1/docs/images/dashboard-charts.png +0 -0
- handoverlab-2.4.1/docs/images/dashboard-compare.png +0 -0
- handoverlab-2.4.1/docs/images/dashboard-where.png +0 -0
- handoverlab-2.4.1/docs/images/dashboard.png +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/.zenodo.json +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/CODE_OF_CONDUCT.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/CONTRIBUTING.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/LICENSE +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/MANIFEST.in +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/SECURITY.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/RELEASING.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/calibration.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/guides/add-scenario.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/guides/ai-mobility.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/guides/dashboard.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/guides/export-event-logs.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/guides/high-speed-train.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/guides/highway.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/guides/many-cores.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/guides/ntn.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/guides/radio-maps.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/guides/reproduce.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/guides/suburban-o2i.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/guides/upper-mid-band.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/images/ai-mobility.png +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/images/calibration_38901.png +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/images/calibration_7ghz.png +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/images/new-scenarios.png +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/images/ntn-beams.png +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/images/radio-map.png +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/images/report-comparison.png +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/images/report-tuning.png +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/images/ssb-beams.png +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/migration-2.0.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/reference/api/config.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/reference/api/engine.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/reference/api/eventlog.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/reference/api/gui.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/reference/api/index.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/reference/api/mapfile.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/reference/api/ntn.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/reference/api/rules.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/reference/api/scenarios.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/reference/api/simulate.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/reference/api/stability.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/reference/api/stats.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/reference/api/studies.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/reference/api/testing.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/reference/api/verify.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/reference/cli.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/reference/metrics.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/reference-study.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/dense-urban-2layer.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/dense-urban-2layer.svg +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/fr3-urban-15ghz.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/fr3-urban-15ghz.svg +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/highway-tr37885-30ghz.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/highway-tr37885-30ghz.svg +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/highway-tr37885-4ghz.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/highway-tr37885-4ghz.svg +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/hst-fr2-28ghz.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/hst-fr2-28ghz.svg +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/indoor-office-4ghz.svg +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/ns3-urban-3.5ghz.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/ns3-urban-3.5ghz.svg +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/ntn-leo600-2ghz.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/ntn-leo600-2ghz.svg +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/open-area-10ghz.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/open-area-10ghz.svg +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/rural-700mhz.svg +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/smoke.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/smoke.svg +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/suburban-sma-7ghz.svg +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/urban-grid-10ghz.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/urban-grid-10ghz.svg +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/urban-grid-28ghz-beams.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/urban-grid-28ghz-beams.svg +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/urban-macro-tr37885-4ghz.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/scenarios/urban-macro-tr37885-4ghz.svg +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/time-step.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/tutorials/first-run.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/tutorials/reading-the-report.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/docs/verification.md +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/examples/compare_a3_cho.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/examples/open_area.toml +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/examples/radio_map.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/examples/smoke.yaml +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/examples/speed_rule.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/examples/street_grid.yaml +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/examples/study_reference.yaml +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/examples/study_reference_explore.yaml +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/examples/study_smoke.yaml +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/examples/traffic_models.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/mkdocs.yml +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/setup.cfg +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/__main__.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/channel/__init__.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/channel/antenna.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/channel/extended.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/channel/fading.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/channel/l2s.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/channel/ntn.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/channel/pathloss.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/channel/radiomap.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/channel/source.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/cli.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/config.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/engine/__init__.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/engine/_kernels.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/engine/batch.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/engine/buffers.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/engine/core.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/engine/dual.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/engine/extended.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/engine/invariants.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/engine/metrics.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/engine/procedures.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/engine/scheduler.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/eventlog.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/gui/__init__.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/gui/app.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/gui/logic.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/io.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/layout.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/linklevel.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/mapfile.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/measurement.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/mobility.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/py.typed +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/requirements.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/rules/__init__.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/rules/base.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/rules/builtin.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/rules/dqn.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/rules/mro.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/rules/predict.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/scenarios/__init__.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/scenarios/cards/dense-urban-2layer.yaml +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/scenarios/cards/fr3-urban-15ghz.yaml +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/scenarios/cards/highway-tr37885-30ghz.yaml +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/scenarios/cards/highway-tr37885-4ghz.yaml +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/scenarios/cards/hst-fr2-28ghz.yaml +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/scenarios/cards/ns3-urban-3.5ghz.yaml +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/scenarios/cards/ntn-leo600-2ghz.yaml +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/scenarios/cards/open-area-10ghz.yaml +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/scenarios/cards/smoke.yaml +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/scenarios/cards/urban-grid-10ghz.yaml +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/scenarios/cards/urban-grid-28ghz-beams.yaml +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/scenarios/cards/urban-macro-tr37885-4ghz.yaml +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/seeds.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/simulate.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/stability.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/standard.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/stats.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/studies/__init__.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/studies/config.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/studies/report.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/studies/runner.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/studies/status.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/studies/store.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/studies/study.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/studies/tuning.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/testing.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/traffic.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/verify/__init__.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/verify/aimobility.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/verify/calibration.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/verify/data/golden.json +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/verify/data/golden_1x.json +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/verify/data/ns3_urban_a3.json +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/verify/data/r1_165974.csv +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/verify/data/r1_2506406.csv +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/verify/engine_checks.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/verify/extended.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/verify/fading.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/verify/golden.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/verify/highway.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/verify/learning.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/verify/ns3.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/verify/ntn.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/verify/radio.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/verify/report.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/verify/scenarios.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/verify/stored.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/verify/values.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab/world.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab.egg-info/dependency_links.txt +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab.egg-info/entry_points.txt +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab.egg-info/requires.txt +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/src/handoverlab.egg-info/top_level.txt +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/conftest.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/data/bh6_reference.json +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/data/bh6_wide.json +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/data/make_bh6_reference.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/data/make_bh6_wide.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/data/public_api.json +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/helpers.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_ai_mobility.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_batch.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_beams_layers.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_buffers.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_calibration.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_channel_detail.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_cltm.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_config_cli.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_contract.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_determinism.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_dqn.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_engine_triggers.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_eventlog.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_fading.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_gui.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_highway.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_highway_tr37885.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_hst_dc.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_indoor_rural.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_invariants.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_levels_status_extend.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_lm_model.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_mapfile.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_measurement.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_mro.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_ntn.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_pathloss.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_protocol_3gpp.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_readme_boundaries.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_regression_bh6.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_regression_bh6_wide.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_rrc_detail.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_rules_rc2.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_scenarios.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_scenarios_230.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_sched_kernel.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_scheduler.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_signalling_energy.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_stability.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_stats.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_study.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_tools.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_traffic.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_tuning.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_ue_beams.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_v111.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tests/test_verify.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tools/compare_fingerprints.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tools/make_ai_mobility_figure.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tools/make_beam_figure.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tools/make_calibration_7ghz_figure.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tools/make_calibration_figure.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tools/make_ntn_figure.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tools/make_radiomap_figure.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tools/make_readme_images.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tools/make_scenarios_figure.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tools/mkdocs_hooks.py +0 -0
- {handoverlab-2.4.1 → handoverlab-2.4.2}/tools/release_check.py +0 -0
|
@@ -7,6 +7,46 @@ All notable changes to this project are documented in this file. The format foll
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.4.2] - 2026-10-23
|
|
11
|
+
|
|
12
|
+
No change of results.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- A picture for every option, each drawn from a real run by its own script in `tools/`: the handover
|
|
17
|
+
procedures side by side (`procedures.png`), mobility robustness optimisation (`mro.png`), fast fading
|
|
18
|
+
(`fading.png`), the slot scheduler with the Numba timings (`scheduler.png`), buffers at handover
|
|
19
|
+
(`buffers.png`), dual connectivity (`dual-connectivity.png`), UE receive beams (`ue-beams.png`) and the
|
|
20
|
+
traffic models (`traffic.png`); shown in the README and in each guide.
|
|
21
|
+
- `tools/make_dashboard_screenshots.py`: the dashboard screenshots taken with Edge through the DevTools
|
|
22
|
+
protocol; all four dashboard pictures redone with this version.
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- The speed-ups stated for 2.4.0 ("8 to 60" times, "50-80" times the rate model) were not all supported by the
|
|
27
|
+
measurements: `docs/performance.md` gives 23 to 59 times for the Numba scheduler and, measured again for 2.4.2
|
|
28
|
+
on the configuration of the scheduler picture, 42 (round robin) and 93 times (proportional fair), with the
|
|
29
|
+
NumPy scheduler about 91 times the rate model. The README, `docs/comparison.md`, the scheduler and fading guides
|
|
30
|
+
and `docs/performance.md` now give these measured numbers.
|
|
31
|
+
|
|
32
|
+
### Documentation
|
|
33
|
+
|
|
34
|
+
- 7 GHz calibration: README, `docs/comparison.md`, `docs/calibration-3gpp.md` and
|
|
35
|
+
`docs/standard-compliance.md` say which cases they count (at 7 GHz 228 percentiles, largest distance
|
|
36
|
+
1.69-2.43 dB; with the two 6 GHz reruns 342 percentiles, 1.65-2.88 dB).
|
|
37
|
+
- README model boundaries: the slot scheduler (2.2.0) and the user-plane buffers (2.3.0) listed as options,
|
|
38
|
+
with what is still not modelled.
|
|
39
|
+
- Scenario cards `suburban-sma-7ghz`, `rural-700mhz` and `indoor-office-4ghz`: the 7 GHz calibration of 2.4.0
|
|
40
|
+
and the hard-LOS results of `docs/guides/indoor-rural.md`; scenario pages regenerated.
|
|
41
|
+
- Examples rerun with this version and their numbers, and where needed their conclusions, updated: the guides
|
|
42
|
+
on buffers, MRO (the faster MRO setting is no better), beams and layers, indoor and rural scenarios, the
|
|
43
|
+
learning rule and fast fading; tutorial 2; the README traffic table; the `status` example in the user guide.
|
|
44
|
+
- User guide: all 15 cards, the `a3_pred` rule, `ttt_d2_s`, the layout kinds `indoor` and `ntn`, `run.backend`
|
|
45
|
+
under `run`, `ntn.hpbw_deg` (tabled widths at 2 GHz only), `ntn.los_model` and `radio.vegetation`; the study
|
|
46
|
+
example with a main guard. `docs/index.md`: the current layouts and cards. `docs/stability.md`: the missing
|
|
47
|
+
import. Tutorial 3: the cap of four extensions dates from 2.4.1.
|
|
48
|
+
- Citation with the DOI of 2.4.1.
|
|
49
|
+
|
|
10
50
|
## [2.4.1] - 2026-10-22
|
|
11
51
|
|
|
12
52
|
No change of results.
|
|
@@ -1080,7 +1120,8 @@ First alpha release (stage 1: the core simulator).
|
|
|
1080
1120
|
- Documentation: README, user guide, contribution guide, citation file; CI on Linux, Windows and
|
|
1081
1121
|
macOS with Python 3.9-3.12.
|
|
1082
1122
|
|
|
1083
|
-
[Unreleased]: https://github.com/mjs19971997/handoverlab/compare/v2.4.
|
|
1123
|
+
[Unreleased]: https://github.com/mjs19971997/handoverlab/compare/v2.4.2...HEAD
|
|
1124
|
+
[2.4.2]: https://github.com/mjs19971997/handoverlab/compare/v2.4.1...v2.4.2
|
|
1084
1125
|
[2.4.1]: https://github.com/mjs19971997/handoverlab/compare/v2.4.0...v2.4.1
|
|
1085
1126
|
[2.4.0]: https://github.com/mjs19971997/handoverlab/compare/v2.3.0...v2.4.0
|
|
1086
1127
|
[2.3.0]: https://github.com/mjs19971997/handoverlab/compare/v2.2.0...v2.3.0
|
|
@@ -14,7 +14,7 @@ abstract: >-
|
|
|
14
14
|
handover rules (including a measurement-prediction rule after TR 38.744), equal-budget tuning
|
|
15
15
|
studies with paired statistics, and verification against hand-computed values, golden event-log
|
|
16
16
|
fingerprints, the 3GPP large-scale calibration and ns-3 / 5G-LENA.
|
|
17
|
-
version: "2.4.
|
|
17
|
+
version: "2.4.2"
|
|
18
18
|
doi: 10.5281/zenodo.23409131
|
|
19
19
|
identifiers:
|
|
20
20
|
- type: doi
|
|
@@ -29,7 +29,10 @@ identifiers:
|
|
|
29
29
|
- type: doi
|
|
30
30
|
value: 10.5281/zenodo.23582521
|
|
31
31
|
description: "Version 2.4.0 on Zenodo"
|
|
32
|
-
|
|
32
|
+
- type: doi
|
|
33
|
+
value: 10.5281/zenodo.23585308
|
|
34
|
+
description: "Version 2.4.1 on Zenodo"
|
|
35
|
+
date-released: 2026-10-23
|
|
33
36
|
license: MIT
|
|
34
37
|
repository-code: "https://github.com/mjs19971997/handoverlab"
|
|
35
38
|
url: "https://mjs19971997.github.io/handoverlab/"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: handoverlab
|
|
3
|
-
Version: 2.4.
|
|
3
|
+
Version: 2.4.2
|
|
4
4
|
Summary: System-level handover simulator for 5G-Advanced and beyond-5G research
|
|
5
5
|
Author: Mostafa Jalili Sanjarani, Yasser Elmi Sola
|
|
6
6
|
License-Expression: MIT
|
|
@@ -70,7 +70,7 @@ received-power-level radio model from TR 38.901 (TR 38.811 for the satellite) (o
|
|
|
70
70
|
and several carriers), an L3-filtered measurement chain, a radio-link failure model, and an
|
|
71
71
|
outcome label for every handover attempt.
|
|
72
72
|
|
|
73
|
-
> **Status: 2.4.
|
|
73
|
+
> **Status: 2.4.2** (`python -m pip install handoverlab`). The public surface (configuration and
|
|
74
74
|
> result formats with a schema version, the rule interface, metric names, commands and the
|
|
75
75
|
> documented Python names) follows the [stability policy](https://github.com/mjs19971997/handoverlab/blob/main/docs/stability.md): within 2.x it only grows,
|
|
76
76
|
> and anything removed is deprecated first. 2.0.0 makes the 3GPP values the defaults (the protocol profile,
|
|
@@ -150,6 +150,47 @@ accurate than sample and hold 400 ms ahead (1.84 / 2.66 / 3.14 dB against 2.38 /
|
|
|
150
150
|
|
|
151
151
|

|
|
152
152
|
|
|
153
|
+
**Handover procedures side by side.** On one card failures fall from 0.6 (A3) to 0.2 (LTM and CLTM) per
|
|
154
|
+
UE-minute; DAPS has no execution interruption; LTM pays with 192 RRC messages per UE-minute against 45 for A3:
|
|
155
|
+
|
|
156
|
+

|
|
157
|
+
|
|
158
|
+
**Mobility robustness optimisation.** `a3_mro` moves the offset of every cell pair from its own failures;
|
|
159
|
+
here 17 pairs move and failures fall from 0.22 to 0.14 per UE-minute when starting from 3 dB:
|
|
160
|
+
|
|
161
|
+

|
|
162
|
+
|
|
163
|
+
**Fast fading.** With TDL-A or TDL-C the 5th percentile of the link-monitoring SINR on the ns-3 card falls
|
|
164
|
+
from 8.3 dB to 3.8 and 3.4 dB:
|
|
165
|
+
|
|
166
|
+

|
|
167
|
+
|
|
168
|
+
**Slot scheduler.** Round robin and proportional fair with the MCS, TBS and HARQ of TS 38.214; with
|
|
169
|
+
`run.backend: numba` the same runs take 2.2 s and 1.0 s instead of 92.7 s and 93.3 s with NumPy, with identical
|
|
170
|
+
fingerprints (the default rate model takes about 1.0 s for the same run):
|
|
171
|
+
|
|
172
|
+

|
|
173
|
+
|
|
174
|
+
**Buffers at handover.** Without data forwarding A3 loses 2.17 % of the data and DAPS 0.34 %; with
|
|
175
|
+
forwarding nothing is lost, and the forwarded data wait 85-349 ms:
|
|
176
|
+
|
|
177
|
+

|
|
178
|
+
|
|
179
|
+
**Dual connectivity.** A 4 GHz master cell and a 30 GHz secondary cell: the secondary cell group carries data
|
|
180
|
+
96 % of the time and 183 Mbit/s per user, against 10.1 Mbit/s on the master cell group:
|
|
181
|
+
|
|
182
|
+

|
|
183
|
+
|
|
184
|
+
**UE receive beams.** Two panels with DFT beams (peak gain 13.7 dBi) raise the mean SINR from 10.9 to 19.2 dB
|
|
185
|
+
and cut failures from 3.60 to 1.44 per UE-minute; a beam sweep keeps them at 3.36:
|
|
186
|
+
|
|
187
|
+

|
|
188
|
+
|
|
189
|
+
**Traffic models.** The same handovers (11.3 per UE-minute) under fixed rates, full buffer, periodic packets and FTP model 3,
|
|
190
|
+
with very different rate, cell load and energy per bit:
|
|
191
|
+
|
|
192
|
+

|
|
193
|
+
|
|
153
194
|
## What it models
|
|
154
195
|
|
|
155
196
|
- **Scenarios**: the TR 37.885 urban street grid (configurable number of blocks; 433 m x 250 m
|
|
@@ -213,7 +254,7 @@ the clause-by-clause detail is in [standard compliance](https://github.com/mjs19
|
|
|
213
254
|
| Channel | TR 38.901 path loss and LOS (UMi, UMa, RMa, SMa, InH), LOS from buildings, spatially consistent LOS and shadowing, car and O2I building penetration loss, radio maps from a file (clause 8), TR 38.811 for the satellite | received power per site and step with a slow time-varying component; indoor users keep the LOS state and shadowing of their position; optional TDL fast fading with effective SINRs (clause 7.7.2, since 2.2.0) | CDL and the full fast-fading model of clause 7.5, MIMO |
|
|
214
255
|
| Beams and carriers | SSB beams per sector, cell quality from beams, beam failure detection and recovery, several carriers with gaps and Event A5; dual connectivity (NR-DC: SN addition, PSCell change, SN release, SCG failure; option since 2.3.0) | the TR 38.901 antenna element and DFT beams; isotropic UE unless UE receive panels are set (option since 2.4.0); the SCG as one PSCell with a full-buffer share | UE transmit beams and polarisation, conditional PSCell change, fast MCG recovery |
|
|
215
256
|
| Mobility | street-following vehicles (60 km/h, two lanes), highway lanes at 70/140 km/h, a train at 350 km/h (TR 38.854), random waypoints, pedestrians | constant speed per user | handheld rotation and body blockage |
|
|
216
|
-
| Traffic and load | constant rates per 5QI, full buffer, periodic, FTP model 3; cell load drives interference | rate from SINR (Shannon-type mapping), no
|
|
257
|
+
| Traffic and load | constant rates per 5QI, full buffer, periodic, FTP model 3; cell load drives interference; options: a slot scheduler (`protocol.scheduler`: round robin or proportional fair) with the MCS, TBS and HARQ of TS 38.214 (since 2.2.0), and user-plane buffers at handover (`protocol.buffers`: simplified PDCP / RLC in AM or UM with Xn data forwarding, since 2.3.0) | by default the rate from the SINR (Shannon-type mapping) without a scheduler; with the scheduler the channel is held for the 10 ms step and the MCS is chosen from the SINR of one measurement interval earlier (no CSI reports); buffers: downlink only, one bearer per user, the interruption quantised to the measurement interval; both options need the base engine (no beams, layers, NTN or TS 38.133 periods) | uplink data, CSI-based link adaptation, PDCP reordering and status reports at the UE, TCP and applications |
|
|
217
258
|
| Measurements | L1 samples with error, TS 38.331 L3 filter, TS 38.133 measurement periods and gaps (option) | wideband RSRP; SS-RSRP per resource element with beams/carriers | RSRQ, CSI reporting |
|
|
218
259
|
| Procedures | baseline (A3), CHO, DAPS, LTM, conditional LTM, CHO with D1/D2 for satellites, A3/A5 between carriers; rules `a3`, `a3a5`, `a3_mro`, `a3_bandit`, `dqn`, `a3_pred`, `cho`, `cho_d2`, `daps`, `ltm`, `cltm` | fixed preparation, command and execution delays; re-establishment always succeeds after a fixed outage | condEventT1, RACH-less NTN handover, Xn signalling in detail |
|
|
219
260
|
| Failure model | Qout/Qin with windows, N310/N311/T310, T304, command received during T310, re-establishment, link-monitoring restart | Qout/Qin as SINR thresholds (TR 36.839 values) instead of the BLER of a hypothetical PDCCH | BLER-based link monitoring; absolute failure rates are not calibrated: compare rules with each other |
|
|
@@ -254,8 +295,10 @@ Ericsson, Nokia, Samsung, Qualcomm and others), for UMa, UMi and the indoor offi
|
|
|
254
295
|
30 GHz. 325 of 342 compared percentiles are inside the range, none is more than about 1 dB from
|
|
255
296
|
the industry mean, and `handoverlab verify` repeats the check
|
|
256
297
|
([details](https://github.com/mjs19971997/handoverlab/blob/main/docs/calibration-3gpp.md)). Since 2.4.0 the
|
|
257
|
-
same check runs
|
|
258
|
-
|
|
298
|
+
same check runs for Table 7.8-1A against the companies of R1-2506406. At 7 GHz (UMa, UMi and SMa with ISD
|
|
299
|
+
1299 m and 1732 m) all 228 percentiles lie inside their range, but the largest distance from their mean is
|
|
300
|
+
1.69-2.43 dB, which misses the 1.5 dB criterion set before the run; the two 6 GHz reruns of UMa and UMi with
|
|
301
|
+
the updated model add 114 percentiles, also all inside, at 1.65 and 2.88 dB.
|
|
259
302
|
|
|
260
303
|

|
|
261
304
|
|
|
@@ -304,8 +347,8 @@ L1/L2-triggered mobility.
|
|
|
304
347
|
|
|
305
348
|
- **2.4.0**: UE receive beams (panels of TR 38.802, best beam or a sweep); a measurement-prediction rule after
|
|
306
349
|
TR 38.744 (`a3_pred`: predicted Event A3 or measurement skipping, sample and hold or a trained ridge
|
|
307
|
-
predictor); the slot scheduler as a compiled kernel (`run.backend: numba`, bit-identical
|
|
308
|
-
faster); the 7 GHz large-scale calibration against the companies of R1-2506406 (every percentile inside the
|
|
350
|
+
predictor); the slot scheduler as a compiled kernel (`run.backend: numba`, bit-identical; on the ns-3 card
|
|
351
|
+
42 times (`rr`) and 93 times (`pf`) faster than the NumPy loop); the 7 GHz large-scale calibration against the companies of R1-2506406 (every percentile inside the
|
|
309
352
|
range, the distance to the mean criterion missed); a [comparison with other simulators](https://github.com/mjs19971997/handoverlab/blob/main/docs/comparison.md).
|
|
310
353
|
- **2.3.0**: user-plane buffers at handover (PDCP / RLC, Xn data forwarding for baseline, conditional, DAPS and
|
|
311
354
|
L1/L2-triggered handover); the TR 37.885 urban macro grid, suburban macro (SMa) and O2I penetration of indoor
|
|
@@ -436,13 +479,13 @@ traffic models (one seed, 30 users, 60 s on the urban grid at 10 GHz):
|
|
|
436
479
|
|
|
437
480
|
```text
|
|
438
481
|
model cell load rate [Mbit/s] delivered SINR [dB] failures/UE-min
|
|
439
|
-
fixed 0.28 14.
|
|
440
|
-
full_buffer 0.52
|
|
441
|
-
periodic 0.28 0.04 0.
|
|
442
|
-
ftp3 0.28 3.93 0.
|
|
482
|
+
fixed 0.28 14.10 0.97 23.6 0.08
|
|
483
|
+
full_buffer 0.52 717.77 0.48 21.2 0.08
|
|
484
|
+
periodic 0.28 0.04 0.86 23.7 0.08
|
|
485
|
+
ftp3 0.28 3.93 0.87 23.7 0.08
|
|
443
486
|
```
|
|
444
487
|
|
|
445
|
-
Busier cells interfere more: under full buffer the SINR drops by about 2.
|
|
488
|
+
Busier cells interfere more: under full buffer the SINR drops by about 2.4 dB. With one seed each
|
|
446
489
|
failure rate counts only a few failures; compare them over several seeds.
|
|
447
490
|
|
|
448
491
|
The full script is [examples/compare_a3_cho.py](https://github.com/mjs19971997/handoverlab/blob/main/examples/compare_a3_cho.py). Writing your own
|
|
@@ -524,9 +567,11 @@ the pages are plain Markdown in [docs/](https://github.com/mjs19971997/handoverl
|
|
|
524
567
|
25. 2.3.0: buffers at handover, urban macro, SMa and O2I, the high-speed train, dual connectivity.
|
|
525
568
|
26. 2.4.0: UE receive beams, the TR 38.744 prediction rule, the compiled
|
|
526
569
|
scheduler, the 7 GHz calibration and the comparison with other simulators.
|
|
527
|
-
27.
|
|
570
|
+
27. 2.4.1: pictures, citation and tutorials brought up to date; the example study
|
|
528
571
|
completes again; no change of results.
|
|
529
|
-
28.
|
|
572
|
+
28. **2.4.2 (this release)**: every option has a picture; the dashboard pictures show the current version;
|
|
573
|
+
guide and tutorial examples rerun; facts made consistent; no change of results.
|
|
574
|
+
29. Later (planned, not done), staying a handover simulator: the effect of a handover on what the user
|
|
530
575
|
sees (simple TCP and application models on top of the buffers), MIMO as an SINR gain, hundreds of
|
|
531
576
|
users per run, and one scenario definition that also runs in ns-3; condEventT1 and earth-fixed beams.
|
|
532
577
|
|
|
@@ -535,8 +580,11 @@ the pages are plain Markdown in [docs/](https://github.com/mjs19971997/handoverl
|
|
|
535
580
|
If you use HandoverLab, please cite it as described in [CITATION.cff](https://github.com/mjs19971997/handoverlab/blob/main/CITATION.cff) (GitHub shows
|
|
536
581
|
it under *Cite this repository*). Every release is archived on Zenodo:
|
|
537
582
|
[doi:10.5281/zenodo.23409131](https://doi.org/10.5281/zenodo.23409131) cites all versions (it resolves to
|
|
538
|
-
the latest). To cite the exact version you used, take its DOI from the version list on that page
|
|
539
|
-
2.4.
|
|
583
|
+
the latest). To cite the exact version you used, take its DOI from the version list on that page, where
|
|
584
|
+
the DOI of the latest version is listed; for example, version 2.4.1 is
|
|
585
|
+
[doi:10.5281/zenodo.23585308](https://doi.org/10.5281/zenodo.23585308) and version 2.4.0
|
|
586
|
+
[doi:10.5281/zenodo.23582521](https://doi.org/10.5281/zenodo.23582521). The BibTeX entry below cites 2.4.1;
|
|
587
|
+
replace version and DOI with those of the version you used.
|
|
540
588
|
|
|
541
589
|
```bibtex
|
|
542
590
|
@software{handoverlab,
|
|
@@ -544,8 +592,8 @@ the latest). To cite the exact version you used, take its DOI from the version l
|
|
|
544
592
|
title = {{HandoverLab}: system-level handover simulator for 5G-Advanced and beyond-5G research},
|
|
545
593
|
year = {2026},
|
|
546
594
|
publisher = {Zenodo},
|
|
547
|
-
version = {2.4.
|
|
548
|
-
doi = {10.5281/zenodo.
|
|
595
|
+
version = {2.4.1},
|
|
596
|
+
doi = {10.5281/zenodo.23585308},
|
|
549
597
|
url = {https://github.com/mjs19971997/handoverlab}
|
|
550
598
|
}
|
|
551
599
|
```
|
|
@@ -12,7 +12,7 @@ received-power-level radio model from TR 38.901 (TR 38.811 for the satellite) (o
|
|
|
12
12
|
and several carriers), an L3-filtered measurement chain, a radio-link failure model, and an
|
|
13
13
|
outcome label for every handover attempt.
|
|
14
14
|
|
|
15
|
-
> **Status: 2.4.
|
|
15
|
+
> **Status: 2.4.2** (`python -m pip install handoverlab`). The public surface (configuration and
|
|
16
16
|
> result formats with a schema version, the rule interface, metric names, commands and the
|
|
17
17
|
> documented Python names) follows the [stability policy](https://github.com/mjs19971997/handoverlab/blob/main/docs/stability.md): within 2.x it only grows,
|
|
18
18
|
> and anything removed is deprecated first. 2.0.0 makes the 3GPP values the defaults (the protocol profile,
|
|
@@ -92,6 +92,47 @@ accurate than sample and hold 400 ms ahead (1.84 / 2.66 / 3.14 dB against 2.38 /
|
|
|
92
92
|
|
|
93
93
|

|
|
94
94
|
|
|
95
|
+
**Handover procedures side by side.** On one card failures fall from 0.6 (A3) to 0.2 (LTM and CLTM) per
|
|
96
|
+
UE-minute; DAPS has no execution interruption; LTM pays with 192 RRC messages per UE-minute against 45 for A3:
|
|
97
|
+
|
|
98
|
+

|
|
99
|
+
|
|
100
|
+
**Mobility robustness optimisation.** `a3_mro` moves the offset of every cell pair from its own failures;
|
|
101
|
+
here 17 pairs move and failures fall from 0.22 to 0.14 per UE-minute when starting from 3 dB:
|
|
102
|
+
|
|
103
|
+

|
|
104
|
+
|
|
105
|
+
**Fast fading.** With TDL-A or TDL-C the 5th percentile of the link-monitoring SINR on the ns-3 card falls
|
|
106
|
+
from 8.3 dB to 3.8 and 3.4 dB:
|
|
107
|
+
|
|
108
|
+

|
|
109
|
+
|
|
110
|
+
**Slot scheduler.** Round robin and proportional fair with the MCS, TBS and HARQ of TS 38.214; with
|
|
111
|
+
`run.backend: numba` the same runs take 2.2 s and 1.0 s instead of 92.7 s and 93.3 s with NumPy, with identical
|
|
112
|
+
fingerprints (the default rate model takes about 1.0 s for the same run):
|
|
113
|
+
|
|
114
|
+

|
|
115
|
+
|
|
116
|
+
**Buffers at handover.** Without data forwarding A3 loses 2.17 % of the data and DAPS 0.34 %; with
|
|
117
|
+
forwarding nothing is lost, and the forwarded data wait 85-349 ms:
|
|
118
|
+
|
|
119
|
+

|
|
120
|
+
|
|
121
|
+
**Dual connectivity.** A 4 GHz master cell and a 30 GHz secondary cell: the secondary cell group carries data
|
|
122
|
+
96 % of the time and 183 Mbit/s per user, against 10.1 Mbit/s on the master cell group:
|
|
123
|
+
|
|
124
|
+

|
|
125
|
+
|
|
126
|
+
**UE receive beams.** Two panels with DFT beams (peak gain 13.7 dBi) raise the mean SINR from 10.9 to 19.2 dB
|
|
127
|
+
and cut failures from 3.60 to 1.44 per UE-minute; a beam sweep keeps them at 3.36:
|
|
128
|
+
|
|
129
|
+

|
|
130
|
+
|
|
131
|
+
**Traffic models.** The same handovers (11.3 per UE-minute) under fixed rates, full buffer, periodic packets and FTP model 3,
|
|
132
|
+
with very different rate, cell load and energy per bit:
|
|
133
|
+
|
|
134
|
+

|
|
135
|
+
|
|
95
136
|
## What it models
|
|
96
137
|
|
|
97
138
|
- **Scenarios**: the TR 37.885 urban street grid (configurable number of blocks; 433 m x 250 m
|
|
@@ -155,7 +196,7 @@ the clause-by-clause detail is in [standard compliance](https://github.com/mjs19
|
|
|
155
196
|
| Channel | TR 38.901 path loss and LOS (UMi, UMa, RMa, SMa, InH), LOS from buildings, spatially consistent LOS and shadowing, car and O2I building penetration loss, radio maps from a file (clause 8), TR 38.811 for the satellite | received power per site and step with a slow time-varying component; indoor users keep the LOS state and shadowing of their position; optional TDL fast fading with effective SINRs (clause 7.7.2, since 2.2.0) | CDL and the full fast-fading model of clause 7.5, MIMO |
|
|
156
197
|
| Beams and carriers | SSB beams per sector, cell quality from beams, beam failure detection and recovery, several carriers with gaps and Event A5; dual connectivity (NR-DC: SN addition, PSCell change, SN release, SCG failure; option since 2.3.0) | the TR 38.901 antenna element and DFT beams; isotropic UE unless UE receive panels are set (option since 2.4.0); the SCG as one PSCell with a full-buffer share | UE transmit beams and polarisation, conditional PSCell change, fast MCG recovery |
|
|
157
198
|
| Mobility | street-following vehicles (60 km/h, two lanes), highway lanes at 70/140 km/h, a train at 350 km/h (TR 38.854), random waypoints, pedestrians | constant speed per user | handheld rotation and body blockage |
|
|
158
|
-
| Traffic and load | constant rates per 5QI, full buffer, periodic, FTP model 3; cell load drives interference | rate from SINR (Shannon-type mapping), no
|
|
199
|
+
| Traffic and load | constant rates per 5QI, full buffer, periodic, FTP model 3; cell load drives interference; options: a slot scheduler (`protocol.scheduler`: round robin or proportional fair) with the MCS, TBS and HARQ of TS 38.214 (since 2.2.0), and user-plane buffers at handover (`protocol.buffers`: simplified PDCP / RLC in AM or UM with Xn data forwarding, since 2.3.0) | by default the rate from the SINR (Shannon-type mapping) without a scheduler; with the scheduler the channel is held for the 10 ms step and the MCS is chosen from the SINR of one measurement interval earlier (no CSI reports); buffers: downlink only, one bearer per user, the interruption quantised to the measurement interval; both options need the base engine (no beams, layers, NTN or TS 38.133 periods) | uplink data, CSI-based link adaptation, PDCP reordering and status reports at the UE, TCP and applications |
|
|
159
200
|
| Measurements | L1 samples with error, TS 38.331 L3 filter, TS 38.133 measurement periods and gaps (option) | wideband RSRP; SS-RSRP per resource element with beams/carriers | RSRQ, CSI reporting |
|
|
160
201
|
| Procedures | baseline (A3), CHO, DAPS, LTM, conditional LTM, CHO with D1/D2 for satellites, A3/A5 between carriers; rules `a3`, `a3a5`, `a3_mro`, `a3_bandit`, `dqn`, `a3_pred`, `cho`, `cho_d2`, `daps`, `ltm`, `cltm` | fixed preparation, command and execution delays; re-establishment always succeeds after a fixed outage | condEventT1, RACH-less NTN handover, Xn signalling in detail |
|
|
161
202
|
| Failure model | Qout/Qin with windows, N310/N311/T310, T304, command received during T310, re-establishment, link-monitoring restart | Qout/Qin as SINR thresholds (TR 36.839 values) instead of the BLER of a hypothetical PDCCH | BLER-based link monitoring; absolute failure rates are not calibrated: compare rules with each other |
|
|
@@ -196,8 +237,10 @@ Ericsson, Nokia, Samsung, Qualcomm and others), for UMa, UMi and the indoor offi
|
|
|
196
237
|
30 GHz. 325 of 342 compared percentiles are inside the range, none is more than about 1 dB from
|
|
197
238
|
the industry mean, and `handoverlab verify` repeats the check
|
|
198
239
|
([details](https://github.com/mjs19971997/handoverlab/blob/main/docs/calibration-3gpp.md)). Since 2.4.0 the
|
|
199
|
-
same check runs
|
|
200
|
-
|
|
240
|
+
same check runs for Table 7.8-1A against the companies of R1-2506406. At 7 GHz (UMa, UMi and SMa with ISD
|
|
241
|
+
1299 m and 1732 m) all 228 percentiles lie inside their range, but the largest distance from their mean is
|
|
242
|
+
1.69-2.43 dB, which misses the 1.5 dB criterion set before the run; the two 6 GHz reruns of UMa and UMi with
|
|
243
|
+
the updated model add 114 percentiles, also all inside, at 1.65 and 2.88 dB.
|
|
201
244
|
|
|
202
245
|

|
|
203
246
|
|
|
@@ -246,8 +289,8 @@ L1/L2-triggered mobility.
|
|
|
246
289
|
|
|
247
290
|
- **2.4.0**: UE receive beams (panels of TR 38.802, best beam or a sweep); a measurement-prediction rule after
|
|
248
291
|
TR 38.744 (`a3_pred`: predicted Event A3 or measurement skipping, sample and hold or a trained ridge
|
|
249
|
-
predictor); the slot scheduler as a compiled kernel (`run.backend: numba`, bit-identical
|
|
250
|
-
faster); the 7 GHz large-scale calibration against the companies of R1-2506406 (every percentile inside the
|
|
292
|
+
predictor); the slot scheduler as a compiled kernel (`run.backend: numba`, bit-identical; on the ns-3 card
|
|
293
|
+
42 times (`rr`) and 93 times (`pf`) faster than the NumPy loop); the 7 GHz large-scale calibration against the companies of R1-2506406 (every percentile inside the
|
|
251
294
|
range, the distance to the mean criterion missed); a [comparison with other simulators](https://github.com/mjs19971997/handoverlab/blob/main/docs/comparison.md).
|
|
252
295
|
- **2.3.0**: user-plane buffers at handover (PDCP / RLC, Xn data forwarding for baseline, conditional, DAPS and
|
|
253
296
|
L1/L2-triggered handover); the TR 37.885 urban macro grid, suburban macro (SMa) and O2I penetration of indoor
|
|
@@ -378,13 +421,13 @@ traffic models (one seed, 30 users, 60 s on the urban grid at 10 GHz):
|
|
|
378
421
|
|
|
379
422
|
```text
|
|
380
423
|
model cell load rate [Mbit/s] delivered SINR [dB] failures/UE-min
|
|
381
|
-
fixed 0.28 14.
|
|
382
|
-
full_buffer 0.52
|
|
383
|
-
periodic 0.28 0.04 0.
|
|
384
|
-
ftp3 0.28 3.93 0.
|
|
424
|
+
fixed 0.28 14.10 0.97 23.6 0.08
|
|
425
|
+
full_buffer 0.52 717.77 0.48 21.2 0.08
|
|
426
|
+
periodic 0.28 0.04 0.86 23.7 0.08
|
|
427
|
+
ftp3 0.28 3.93 0.87 23.7 0.08
|
|
385
428
|
```
|
|
386
429
|
|
|
387
|
-
Busier cells interfere more: under full buffer the SINR drops by about 2.
|
|
430
|
+
Busier cells interfere more: under full buffer the SINR drops by about 2.4 dB. With one seed each
|
|
388
431
|
failure rate counts only a few failures; compare them over several seeds.
|
|
389
432
|
|
|
390
433
|
The full script is [examples/compare_a3_cho.py](https://github.com/mjs19971997/handoverlab/blob/main/examples/compare_a3_cho.py). Writing your own
|
|
@@ -466,9 +509,11 @@ the pages are plain Markdown in [docs/](https://github.com/mjs19971997/handoverl
|
|
|
466
509
|
25. 2.3.0: buffers at handover, urban macro, SMa and O2I, the high-speed train, dual connectivity.
|
|
467
510
|
26. 2.4.0: UE receive beams, the TR 38.744 prediction rule, the compiled
|
|
468
511
|
scheduler, the 7 GHz calibration and the comparison with other simulators.
|
|
469
|
-
27.
|
|
512
|
+
27. 2.4.1: pictures, citation and tutorials brought up to date; the example study
|
|
470
513
|
completes again; no change of results.
|
|
471
|
-
28.
|
|
514
|
+
28. **2.4.2 (this release)**: every option has a picture; the dashboard pictures show the current version;
|
|
515
|
+
guide and tutorial examples rerun; facts made consistent; no change of results.
|
|
516
|
+
29. Later (planned, not done), staying a handover simulator: the effect of a handover on what the user
|
|
472
517
|
sees (simple TCP and application models on top of the buffers), MIMO as an SINR gain, hundreds of
|
|
473
518
|
users per run, and one scenario definition that also runs in ns-3; condEventT1 and earth-fixed beams.
|
|
474
519
|
|
|
@@ -477,8 +522,11 @@ the pages are plain Markdown in [docs/](https://github.com/mjs19971997/handoverl
|
|
|
477
522
|
If you use HandoverLab, please cite it as described in [CITATION.cff](https://github.com/mjs19971997/handoverlab/blob/main/CITATION.cff) (GitHub shows
|
|
478
523
|
it under *Cite this repository*). Every release is archived on Zenodo:
|
|
479
524
|
[doi:10.5281/zenodo.23409131](https://doi.org/10.5281/zenodo.23409131) cites all versions (it resolves to
|
|
480
|
-
the latest). To cite the exact version you used, take its DOI from the version list on that page
|
|
481
|
-
2.4.
|
|
525
|
+
the latest). To cite the exact version you used, take its DOI from the version list on that page, where
|
|
526
|
+
the DOI of the latest version is listed; for example, version 2.4.1 is
|
|
527
|
+
[doi:10.5281/zenodo.23585308](https://doi.org/10.5281/zenodo.23585308) and version 2.4.0
|
|
528
|
+
[doi:10.5281/zenodo.23582521](https://doi.org/10.5281/zenodo.23582521). The BibTeX entry below cites 2.4.1;
|
|
529
|
+
replace version and DOI with those of the version you used.
|
|
482
530
|
|
|
483
531
|
```bibtex
|
|
484
532
|
@software{handoverlab,
|
|
@@ -486,8 +534,8 @@ the latest). To cite the exact version you used, take its DOI from the version l
|
|
|
486
534
|
title = {{HandoverLab}: system-level handover simulator for 5G-Advanced and beyond-5G research},
|
|
487
535
|
year = {2026},
|
|
488
536
|
publisher = {Zenodo},
|
|
489
|
-
version = {2.4.
|
|
490
|
-
doi = {10.5281/zenodo.
|
|
537
|
+
version = {2.4.1},
|
|
538
|
+
doi = {10.5281/zenodo.23585308},
|
|
491
539
|
url = {https://github.com/mjs19971997/handoverlab}
|
|
492
540
|
}
|
|
493
541
|
```
|
|
@@ -91,8 +91,9 @@ InterDigital and ZTE, "Calibration Results for 7 - 24 GHz SI";
|
|
|
91
91
|
`Calibration_LS_v35`, based on TR 38.901 V19.0.0). The criteria were fixed before the first run: every
|
|
92
92
|
percentile 5-95 % inside the company range widened by 0.5 dB (C1, the rule of the cases above), and the
|
|
93
93
|
largest distance from the company mean at most 1.5 dB per case (C2). Result, 30 000 users per case, seed 1:
|
|
94
|
-
**C1 passes for all 18 case-metric pairs (342 of 342 percentiles strictly inside the range
|
|
95
|
-
six cases (largest distance 1.65-2.88 dB
|
|
94
|
+
**C1 passes for all 18 case-metric pairs of the six cases (342 of 342 percentiles strictly inside the range;
|
|
95
|
+
228 of 228 for the four 7 GHz cases); C2 fails for all six cases (largest distance 1.65-2.88 dB; 1.69-2.43 dB
|
|
96
|
+
for the four 7 GHz cases, 1.65 and 2.88 dB for the two 6 GHz reruns).** `handoverlab verify` runs C1 as checks and C2 as notes in the
|
|
96
97
|
group `calibration`.
|
|
97
98
|
|
|
98
99
|
**The reference.** `src/handoverlab/verify/data/r1_2506406.csv` keeps, in the format of `r1_165974.csv`, the
|
|
@@ -41,7 +41,7 @@ Tools compared (latest release found on 2026-10-22):
|
|
|
41
41
|
|
|
42
42
|
| Tool | NTN | Beams | Fast fading and link-to-system mapping | Scheduler |
|
|
43
43
|
|---|---|---|---|---|
|
|
44
|
-
| HandoverLab 2.4.0 | one LEO satellite with earth-moving beams (TR 38.811, TR 38.821), CHO with D2; no several satellites, Doppler or earth-fixed beams ([NTN guide](guides/ntn.md)) | SSB beams per sector from the TR 38.901 element and DFT beams, cell quality from beams, beam failure detection and recovery; UE receive beams optional (1, 2 or 4 panels, [UE beams](guides/ue-beams.md)), isotropic UE by default; no MIMO ([beams](guides/beams-layers.md)) | off by default (large-scale channel with a slow time-varying part); option: TDL-A to TDL-E with MIESM for link monitoring and a capacity-equivalent SINR for the rate; no CDL ([fading](guides/fading.md)) | by default a rate model without a scheduler; option: slot scheduler RR or PF with MCS, TBS and HARQ (base engine only; with `run.backend: numba`
|
|
44
|
+
| HandoverLab 2.4.0 | one LEO satellite with earth-moving beams (TR 38.811, TR 38.821), CHO with D2; no several satellites, Doppler or earth-fixed beams ([NTN guide](guides/ntn.md)) | SSB beams per sector from the TR 38.901 element and DFT beams, cell quality from beams, beam failure detection and recovery; UE receive beams optional (1, 2 or 4 panels, [UE beams](guides/ue-beams.md)), isotropic UE by default; no MIMO ([beams](guides/beams-layers.md)) | off by default (large-scale channel with a slow time-varying part); option: TDL-A to TDL-E with MIESM for link monitoring and a capacity-equivalent SINR for the rate; no CDL ([fading](guides/fading.md)) | by default a rate model without a scheduler; option: slot scheduler RR or PF with MCS, TBS and HARQ (base engine only; with `run.backend: numba` bit-identical and, on the ns-3 card, 42 (`rr`) and 93 (`pf`) times faster than its NumPy loop) ([scheduler](guides/scheduler.md)) |
|
|
45
45
|
| ns-3 5G-LENA v5.1 | NTN channel (TR 38.811, from ns-3 mainline [L9]) and a LEO mobility example [L1, L2] | ideal and SRS-based realistic beamforming; beam management "Simplified model; no SSB blocks" [L1]; quasi-omni beams in the RRC / handover context [L3] | TR 38.901 with fast fading; EESM-based PHY abstraction with SINR-BLER tables [L1, L8] | PF, RR, MR, QoS-aware, RL-based; OFDMA and TDMA [L1] |
|
|
46
46
|
| ns-3 mmWave v8.0 | TR 38.811 channel inherited from ns-3.42; no NTN protocol features stated [M2] | SVD- and DFT-based beamforming; NR beam tracking listed as future work [M1, M3] | TR 38.901 channel, ray-tracing and measured traces; EESM error model from 5G-LENA [M1, M3] | flexible-TTI RR, PF, max-rate, max-weight [M1] |
|
|
47
47
|
| Simu5G 1.8.0 | not in the official release; separate third-party work exists [S10] | not stated; antenna-gain link budget only [S1] | path loss, LOS and shadowing of TR 36.814 / 36.873 / 38.901 with Jakes or Rayleigh fading; reception from SINR and BLER curves [S5, S6] | MAX C/I, PF, DRR, QoS-aware PF [S1] |
|
|
@@ -54,7 +54,7 @@ Tools compared (latest release found on 2026-10-22):
|
|
|
54
54
|
|
|
55
55
|
| Tool | Speed and scale | Validation against 3GPP |
|
|
56
56
|
|---|---|---|
|
|
57
|
-
| HandoverLab 2.4.0 | one process: 2 rules, 40 users, 76 cells, 60 s simulated in 10-15 s on a modest virtual machine (1.11.0 timings, [performance](performance.md)); many rules share one world; no published figures for thousands of nodes | large-scale calibration of TR 38.901 clause 7.8.1 against the 21 companies of R1-165974 (325 of 342 percentiles inside the range) and
|
|
57
|
+
| HandoverLab 2.4.0 | one process: 2 rules, 40 users, 76 cells, 60 s simulated in 10-15 s on a modest virtual machine (1.11.0 timings, [performance](performance.md)); many rules share one world; no published figures for thousands of nodes | large-scale calibration of TR 38.901 clause 7.8.1 against the 21 companies of R1-165974 (325 of 342 percentiles inside the range) and against R1-2506406 (at 7 GHz all 228 percentiles of UMa, UMi and SMa inside the company range, largest distance from the company mean 1.69-2.43 dB; with the two 6 GHz reruns 342 percentiles, 1.65-2.88 dB, [details](calibration-3gpp.md)); handover counts against ns-3 / 5G-LENA; failure levels differ from ns-3 ([calibration](calibration.md)); clause-by-clause [standard compliance](standard-compliance.md) |
|
|
58
58
|
| ns-3 5G-LENA v5.1 | runtime numbers: not stated for the module; a MIMO channel speed-up of up to 16 times is reported in a WNS3 paper [L11]; the calibration scenario has 12 gNBs and 120 UEs [L10] | calibrated in 3GPP outdoor reference scenarios (SIMPAT 2022) [L7]; calibration examples for RP-180524 [L2]; mobility checked against TR 36.839 (v5.1) [L5] |
|
|
59
59
|
| ns-3 mmWave v8.0 | not stated | not stated (examples "verify its correct functioning" [M6]) |
|
|
60
60
|
| Simu5G 1.8.0 | background cells and UEs for large scenarios; real-time emulation of "hundreds of simulated users and tens of cells" on one desktop [S1, S9] | PHY abstraction validated in 3GPP-based scenarios [S8]; fingerprint regression tests [S1] |
|
|
@@ -50,15 +50,16 @@ UE-minute):
|
|
|
50
50
|
|
|
51
51
|
| Rule | Handovers | Failures | Beam switches | Beam failures | recovered | ended in RLF | Interruption [s] | SINR [dB] |
|
|
52
52
|
|---|---|---|---|---|---|---|---|---|
|
|
53
|
-
| A3 |
|
|
54
|
-
| CHO |
|
|
55
|
-
| LTM |
|
|
56
|
-
| CLTM |
|
|
53
|
+
| A3 | 20.4 | 5.50 | 42.9 | 11.43 | 4.83 | 5.42 | 6.36 | 9.8 |
|
|
54
|
+
| CHO | 22.0 | 3.88 | 46.6 | 8.73 | 4.12 | 3.83 | 3.67 | 11.6 |
|
|
55
|
+
| LTM | 30.6 | 2.80 | 50.0 | 7.33 | 3.30 | 2.75 | 2.60 | 13.1 |
|
|
56
|
+
| CLTM | 30.6 | 2.72 | 49.6 | 7.40 | 3.60 | 2.67 | 2.55 | 13.5 |
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
(the user needed a handover),
|
|
61
|
-
beam failures to recover
|
|
58
|
+
A little less than half (42-49 %) of the detected beam failures are recovered on another beam of the
|
|
59
|
+
same cell; 36-47 % end in a radio-link failure because no beam of the serving cell is good enough any
|
|
60
|
+
more (the user needed a handover), and these make up 98-99 % of the failures; the rest (9-17 %) are
|
|
61
|
+
ended by a handover. Faster cell changes (LTM, conditional LTM) leave fewer beam failures to recover
|
|
62
|
+
(7.3-7.4 per UE-minute against 11.4 with A3).
|
|
62
63
|
|
|
63
64
|
## 2. Two carriers: a macro layer and a small-cell layer
|
|
64
65
|
|
|
@@ -8,6 +8,10 @@ delayed by the interruption. It works with every procedure (baseline handover su
|
|
|
8
8
|
DAPS, LTM and conditional LTM). It is off by default; with it off every result of 2.2.0 is
|
|
9
9
|
unchanged bit for bit (the new metrics are 0).
|
|
10
10
|
|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
*Without forwarding A3 loses 2.17 % of the data, CHO 1.16 %, DAPS 0.34 % and LTM 0.41 %; with forwarding nothing is lost, and the forwarded data wait 85-349 ms.*
|
|
14
|
+
|
|
11
15
|
```yaml
|
|
12
16
|
scenario:
|
|
13
17
|
base: smoke
|
|
@@ -97,15 +101,17 @@ forwarding and links below Qout (no data in the rate model) add.
|
|
|
97
101
|
|
|
98
102
|
| Rule | forwarded kbyte/UE-min | lost share without forwarding | mean PDCP delay | delay of forwarded data |
|
|
99
103
|
|---|---|---|---|---|
|
|
100
|
-
| A3 |
|
|
101
|
-
| CHO (late / early forwarding) |
|
|
102
|
-
| DAPS | 6.
|
|
103
|
-
| LTM | 1.
|
|
104
|
-
|
|
105
|
-
With forwarding nothing is lost.
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
104
|
+
| A3 | 7.4 | 2.2 % | 8.3 ms | 313 ms |
|
|
105
|
+
| CHO (late / early forwarding) | 3.5 | 1.2 % | 1.1 / 0.9 ms | 85 / 75 ms |
|
|
106
|
+
| DAPS | 6.7 (copies) | 0.3 % (all at failures) | 6.4 ms | 349 ms |
|
|
107
|
+
| LTM | 1.2 | 0.4 % | 0.4 ms | 94 ms |
|
|
108
|
+
|
|
109
|
+
With forwarding nothing is lost. Without it DAPS loses no data at its executions; its 0.3 % are
|
|
110
|
+
lost at failures and re-establishments. Late forwarding adds the 2 x 5 ms wait for CHO; for LTM the
|
|
111
|
+
wait ends before the next measurement instant and does not show (94 ms either way). DAPS gains
|
|
112
|
+
little here: most of its executions start with the source SINR already below Qout, where the rate
|
|
113
|
+
model sends nothing, so the data left for the target are the oldest ones, and its forwarded data
|
|
114
|
+
wait longest (349 ms).
|
|
109
115
|
|
|
110
116
|
## 7. Checks
|
|
111
117
|
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Since 1.0.0rc2 HandoverLab has two procedures next to baseline and conditional handover:
|
|
4
4
|
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
*On one card failures fall from 0.6 (A3) to 0.2 (LTM and CLTM) per UE-minute; DAPS has no execution interruption; LTM sends 192 RRC messages per UE-minute against 45 for A3.*
|
|
8
|
+
|
|
5
9
|
| Rule | Procedure | Specification | What changes compared with `a3` |
|
|
6
10
|
|---|---|---|---|
|
|
7
11
|
| `daps` | DAPS handover (Rel-16) | TS 38.300 clause 9.2.3.2, TS 38.331 clause 5.3.5.8.3 | the source keeps serving during the execution; a failed execution falls back to the source |
|
|
@@ -4,6 +4,10 @@ Since 2.3.0 a user can hold a secondary cell group (SCG) next to its master cell
|
|
|
4
4
|
NR-DC case of TS 37.340 V19.3.0 clause 4.1.3.3, one gNB as master node (MN) and another as secondary
|
|
5
5
|
node (SN). The option `protocol.dc` is off by default; with it off every result stays as it was.
|
|
6
6
|
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
*The SCG carries data 96 % of the time; per UE-minute there are 21.1 PSCell changes and 16.3 MCG handovers, and per user the SCG carries 183 Mbit/s against 10.1 Mbit/s on the MCG.*
|
|
10
|
+
|
|
7
11
|
The model is the simplest consistent subset that a system-level simulator needs: when an SCG is
|
|
8
12
|
added, changed or lost, what that costs in signalling and interruption, and how much time the
|
|
9
13
|
user spends with a second link. The MCG behaves exactly as without dual connectivity: its handover
|
|
@@ -6,6 +6,10 @@ slow time-varying component, with radio-link monitoring on the wideband SINR. Si
|
|
|
6
6
|
the SINR at several frequencies to one effective SINR. It is off by default; with it off every
|
|
7
7
|
result of 2.1.0 is unchanged bit for bit.
|
|
8
8
|
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
*On the ns-3 card (10 vehicles, 20 s) the 5th percentile of the link-monitoring SINR falls from 8.3 dB without fading to 3.8 dB (TDL-A) and 3.4 dB (TDL-C); the MIESM value of QPSK saturates at 18.5 dB.*
|
|
12
|
+
|
|
9
13
|
```yaml
|
|
10
14
|
scenario:
|
|
11
15
|
base: ns3-urban-3.5ghz
|
|
@@ -45,9 +49,13 @@ another simulator is used; a BLER per MCS (TS 38.214 tables) follows with the sl
|
|
|
45
49
|
|
|
46
50
|
## 3. Cost and limits
|
|
47
51
|
|
|
48
|
-
-
|
|
49
|
-
|
|
50
|
-
|
|
52
|
+
- The engine takes about 10 times as long (32 sinusoids per tap, every step; 10 users on the
|
|
53
|
+
ns-3 card, 20 s simulated, without building the world, median of seven runs: 7.7 s with `tdl-a`
|
|
54
|
+
and 7.8 s with `tdl-c` instead of 0.74 s, with the default traffic of the card; the 1.02 s of the
|
|
55
|
+
[scheduler measurement](../performance.md) is another session with full-buffer traffic, and machine load
|
|
56
|
+
changes such times by up to a factor of two); many
|
|
57
|
+
rules on one world the same (24 rules: 53 s instead of 5.4 s), as the batched and compiled loops
|
|
58
|
+
are not used with fading.
|
|
51
59
|
- This version needs the base engine: no beams, layers, NTN or TS 38.133 periods
|
|
52
60
|
(`meas_periods: sample`, `rlm_eval: fixed`); such a configuration is refused.
|
|
53
61
|
- The step stays 10 ms. At 30 m/s and 3.5 GHz the coherence time is about 1 ms, so successive
|
|
@@ -69,27 +69,29 @@ Means over three seeds per user-minute, with the cards as they are and with the
|
|
|
69
69
|
|
|
70
70
|
| Scenario | Rule | LOS state | Handovers | Failures | Unnecessary | Ping-pong | Interruption [s] |
|
|
71
71
|
|---|---|---|---|---|---|---|---|
|
|
72
|
-
| indoor | A3 3 dB 160 ms | soft |
|
|
73
|
-
| indoor | A3 3 dB 160 ms | hard |
|
|
74
|
-
| indoor | A3 5 dB 320 ms | soft |
|
|
75
|
-
| indoor | `a3_mro` | soft |
|
|
76
|
-
| rural | A3 3 dB 160 ms | soft |
|
|
77
|
-
| rural | A3 3 dB 160 ms | hard |
|
|
78
|
-
| rural | A3 5 dB 320 ms | soft |
|
|
79
|
-
| rural | `a3_mro` | soft | 10.
|
|
80
|
-
|
|
81
|
-
- **Indoors**,
|
|
82
|
-
neighbour is close. This is the point of the
|
|
83
|
-
nearly equal cells. A larger offset and
|
|
84
|
-
price of
|
|
72
|
+
| indoor | A3 3 dB 160 ms | soft | 3.81 | 0.00 | 0.86 | 0.02 | 0.15 |
|
|
73
|
+
| indoor | A3 3 dB 160 ms | hard | 3.95 | 0.00 | 0.96 | 0.05 | 0.16 |
|
|
74
|
+
| indoor | A3 5 dB 320 ms | soft | 2.91 | 0.02 | 0.23 | 0.00 | 0.14 |
|
|
75
|
+
| indoor | `a3_mro` | soft | 3.77 | 0.00 | 0.84 | 0.02 | 0.15 |
|
|
76
|
+
| rural | A3 3 dB 160 ms | soft | 13.07 | 0.07 | 7.58 | 1.82 | 0.67 |
|
|
77
|
+
| rural | A3 3 dB 160 ms | hard | 15.62 | 0.18 | 9.24 | 2.57 | 1.06 |
|
|
78
|
+
| rural | A3 5 dB 320 ms | soft | 8.86 | 0.21 | 4.09 | 0.45 | 0.63 |
|
|
79
|
+
| rural | `a3_mro` | soft | 10.56 | 0.08 | 5.51 | 0.97 | 0.56 |
|
|
80
|
+
|
|
81
|
+
- **Indoors**, about a quarter of the handovers are unnecessary even at walking speed (0.86 of 3.81
|
|
82
|
+
per user-minute), because every neighbour is close; ping-pong is rare. This is the point of the
|
|
83
|
+
scenario: a rule has to avoid switching between nearly equal cells. A larger offset and
|
|
84
|
+
time-to-trigger cut the unnecessary handovers by about three quarters at the price of a few late
|
|
85
|
+
ones (0.02 failures per user-minute, all too late, against none).
|
|
85
86
|
- **In rural cells**, the handover rate is far above what the cell size alone would give, and most
|
|
86
87
|
handovers are unnecessary: the 8 dB shadowing with 120 m decorrelation, uncorrelated between
|
|
87
88
|
sites (TR 38.901 clause 7.5 step 4; half correlated until 2.0.0), moves the best cell often at
|
|
88
89
|
120 km/h. Compare rules with each other here, and do
|
|
89
90
|
not read the absolute handover rate as that of a real rural network.
|
|
90
91
|
- **Hard against soft LOS**: with the hard switch, a link jumps by about 20 dB (RMa at 1-2 km) or
|
|
91
|
-
about 15 dB (InH at 20 m) when its state changes
|
|
92
|
-
|
|
92
|
+
about 15 dB (InH at 20 m) when its state changes. In rural cells these jumps raise the failures from
|
|
93
|
+
0.07 to 0.18 per user-minute and the handovers by about a fifth (13.07 to 15.62); indoors there are
|
|
94
|
+
no failures with either state, and the hard switch adds only a few handovers (3.81 to 3.95).
|
|
93
95
|
- The failure model is not calibrated in absolute terms in any scenario; read failure rates
|
|
94
96
|
relative to each other.
|
|
95
97
|
|