Skip to content

Commit 2e990de

Browse files
committed
Add Intrusion and Avoidance section to user guide
Demonstrates compute_intrusion and compute_avoidance using the existing bottleneck demo data. Shows per-agent results and temporal evolution plots of the frame-averaged dimensionless numbers.
1 parent 1b4f219 commit 2e990de

1 file changed

Lines changed: 95 additions & 1 deletion

File tree

notebooks/user_guide.ipynb

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3352,6 +3352,100 @@
33523352
":::"
33533353
]
33543354
},
3355+
{
3356+
"cell_type": "markdown",
3357+
"metadata": {},
3358+
"source": [
3359+
"### Dimensionless Numbers: Intrusion and Avoidance\n",
3360+
"\n",
3361+
"The dimensionless Intrusion number $\\mathcal{I}n$ and Avoidance number $\\mathcal{A}v$\n",
3362+
"classify crowd flow regimes based on personal space intrusions and collision anticipation\n",
3363+
"([Cordes et al., *PNAS Nexus*, 2024](https://doi.org/10.1093/pnasnexus/pgae120)).\n",
3364+
"\n",
3365+
"The **Intrusion number** quantifies encroachment on personal space:\n",
3366+
"\n",
3367+
"$$\n",
3368+
"\\mathcal{I}n_i = \\sum_{j \\in \\mathcal{N}_i}\n",
3369+
"\\left(\\frac{r_{\\text{soc}} - \\ell_{\\text{min}}}{r_{ij} - \\ell_{\\text{min}}}\\right)^2\n",
3370+
"$$\n",
3371+
"\n",
3372+
"The **Avoidance number** quantifies the imminence of collisions via the time-to-collision (TTC):\n",
3373+
"\n",
3374+
"$$\n",
3375+
"\\mathcal{A}v_i = \\max_{j \\in \\mathcal{N}'_i}\n",
3376+
"\\frac{\\tau_0}{\\tau_{ij}}\n",
3377+
"$$\n",
3378+
"\n",
3379+
"where $r_{\\text{soc}} = 0.8\\,$m is the social radius, $\\ell_{\\text{min}} = 0.2\\,$m the pedestrian diameter,\n",
3380+
"and $\\tau_0 = 3\\,$s a reference timescale."
3381+
]
3382+
},
3383+
{
3384+
"cell_type": "code",
3385+
"execution_count": null,
3386+
"metadata": {
3387+
"collapsed": false
3388+
},
3389+
"outputs": [],
3390+
"source": [
3391+
"from pedpy import compute_intrusion, compute_avoidance, IntrusionMethod\n",
3392+
"\n",
3393+
"intrusion = compute_intrusion(traj_data=traj)\n",
3394+
"intrusion.head()"
3395+
]
3396+
},
3397+
{
3398+
"cell_type": "code",
3399+
"execution_count": null,
3400+
"metadata": {
3401+
"collapsed": false
3402+
},
3403+
"outputs": [],
3404+
"source": [
3405+
"avoidance = compute_avoidance(\n",
3406+
" traj_data=traj, frame_step=5, tau_0=3.0, radius=0.2\n",
3407+
")\n",
3408+
"avoidance.head()"
3409+
]
3410+
},
3411+
{
3412+
"cell_type": "markdown",
3413+
"metadata": {},
3414+
"source": [
3415+
"#### Temporal evolution\n",
3416+
"\n",
3417+
"We can visualize how these numbers evolve over time by averaging over all pedestrians per frame:"
3418+
]
3419+
},
3420+
{
3421+
"cell_type": "code",
3422+
"execution_count": null,
3423+
"metadata": {
3424+
"collapsed": false
3425+
},
3426+
"outputs": [],
3427+
"source": [
3428+
"import matplotlib.pyplot as plt\n",
3429+
"\n",
3430+
"mean_in = intrusion.groupby(\"frame\")[\"intrusion\"].mean()\n",
3431+
"mean_av = avoidance.groupby(\"frame\")[\"avoidance\"].mean()\n",
3432+
"\n",
3433+
"fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))\n",
3434+
"\n",
3435+
"ax1.plot(mean_in.index / traj.frame_rate, mean_in.values)\n",
3436+
"ax1.set_xlabel(\"Time / s\")\n",
3437+
"ax1.set_ylabel(r\"$\\langle \\mathcal{I}n \\rangle$\")\n",
3438+
"ax1.set_title(\"Mean Intrusion Number\")\n",
3439+
"\n",
3440+
"ax2.plot(mean_av.index / traj.frame_rate, mean_av.values)\n",
3441+
"ax2.set_xlabel(\"Time / s\")\n",
3442+
"ax2.set_ylabel(r\"$\\langle \\mathcal{A}v \\rangle$\")\n",
3443+
"ax2.set_title(\"Mean Avoidance Number\")\n",
3444+
"\n",
3445+
"fig.tight_layout()\n",
3446+
"plt.show()"
3447+
]
3448+
},
33553449
{
33563450
"cell_type": "markdown",
33573451
"metadata": {},
@@ -5207,4 +5301,4 @@
52075301
},
52085302
"nbformat": 4,
52095303
"nbformat_minor": 4
5210-
}
5304+
}

0 commit comments

Comments
 (0)