Merge remote-tracking branch 'origin/smail' into ahmed

This commit is contained in:
AKallala
2026-04-27 14:32:08 +02:00
15 changed files with 1000482 additions and 17 deletions
Vendored
BIN
View File
Binary file not shown.
+18
View File
@@ -0,0 +1,18 @@
{
"configurations": [
{
"name": "macos-clang-x64",
"includePath": [
"${workspaceFolder}/**"
],
"compilerPath": "/usr/bin/clang",
"cStandard": "${default}",
"cppStandard": "${default}",
"intelliSenseMode": "macos-clang-x64",
"compilerArgs": [
""
]
}
],
"version": 4
}
+13
View File
@@ -0,0 +1,13 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "C/C++ Runner: Debug Session",
"type": "lldb",
"request": "launch",
"args": [],
"cwd": "/Users/smailalijagic/Desktop/Universität/26FS/Advanced Systems Lab/team70",
"program": "/Users/smailalijagic/Desktop/Universität/26FS/Advanced Systems Lab/team70/build/Debug/outDebug"
}
]
}
+59
View File
@@ -0,0 +1,59 @@
{
"C_Cpp_Runner.cCompilerPath": "clang",
"C_Cpp_Runner.cppCompilerPath": "clang++",
"C_Cpp_Runner.debuggerPath": "lldb",
"C_Cpp_Runner.cStandard": "",
"C_Cpp_Runner.cppStandard": "",
"C_Cpp_Runner.msvcBatchPath": "",
"C_Cpp_Runner.useMsvc": false,
"C_Cpp_Runner.warnings": [
"-Wall",
"-Wextra",
"-Wpedantic",
"-Wshadow",
"-Wformat=2",
"-Wcast-align",
"-Wconversion",
"-Wsign-conversion",
"-Wnull-dereference"
],
"C_Cpp_Runner.msvcWarnings": [
"/W4",
"/permissive-",
"/w14242",
"/w14287",
"/w14296",
"/w14311",
"/w14826",
"/w44062",
"/w44242",
"/w14905",
"/w14906",
"/w14263",
"/w44265",
"/w14928"
],
"C_Cpp_Runner.enableWarnings": true,
"C_Cpp_Runner.warningsAsError": false,
"C_Cpp_Runner.compilerArgs": [],
"C_Cpp_Runner.linkerArgs": [],
"C_Cpp_Runner.includePaths": [],
"C_Cpp_Runner.includeSearch": [
"*",
"**/*"
],
"C_Cpp_Runner.excludeSearch": [
"**/build",
"**/build/**",
"**/.*",
"**/.*/**",
"**/.vscode",
"**/.vscode/**"
],
"C_Cpp_Runner.useAddressSanitizer": false,
"C_Cpp_Runner.useUndefinedSanitizer": false,
"C_Cpp_Runner.useLeakSanitizer": false,
"C_Cpp_Runner.showCompilationTime": false,
"C_Cpp_Runner.useLinkTimeOptimization": false,
"C_Cpp_Runner.msvcSecureNoWarnings": false
}
+194
View File
@@ -0,0 +1,194 @@
# Overview — Formulas & Variables
As a reference the paper was used (9805244v1.pdf)
## 1. Variables
### Per pedestrian $\alpha$
| Paper | Code | Type | Meaning | Ref |
|---|---|---|---|---|
| $r_\alpha$ | `curr_pos` | `Vector2d` | position | |
| $v_\alpha$ | `curr_vel` | `Vector2d` | actual velocity (capped) | |
| $w_\alpha$ | `w` | `Vector2d` | preferred velocity (integrates force) | |
| $e_\alpha$ | `e` | `Vector2d` | desired direction, unit vector | |
| $r_\alpha^k$ | `destination` | `Vector2d` | next destination | |
| $v_\alpha^0$ | `desired_v0` | `double` | desired speed | |
| $v_{\max,\alpha}$ | `v_max` | `double` | maximum speed $= 1.3 \cdot v_\alpha^0$ | |
| $F_\alpha$ | `f_i` | `Vector2d` | total force accumulator | |
### Global / scene
| Paper | Code | Meaning | Ref |
|---|---|---|---|
| $n_p$ | `n_p` | number of pedestrians (CLI arg 1) | |
| $n_{\text{iter}}$ | `n_iter` | number of timesteps (CLI arg 2) | |
| — | `BOARD_LENGTH` | walkway length, x-axis (50 m) ||
| — | `BOARD_WIDTH` | walkway width, y-axis (10 m) | |
| $B$ | `Obstacle` | line segment (start, end) | |
### Constants
| Paper | Code | Value | Unit | Ref |
|---|---|---|---|---|
| $\tau_\alpha$ | `tau_alpha` | 0.5 | s | |
| $V_{\alpha\beta}^0$ | `V0_AB` | 2.1 | m²/s² | |
| $\sigma$ | `SIGMA` | 0.3 | m ||
| $U_{\alpha B}^0$ | `U0_AB` | 10.0 | m²/s² | |
| $R$ | `R` | 0.2 | m | |
| $c$ | `c` | 0.5 | — | |
| $\varphi$ | `phi` | 100° | ($2\varphi = 200°$) | |
| $\Delta t$ | `delta_t` | 2 | s (look-ahead, used in $b$) ||
| — | `dt` | 0.01 | s (Euler integration step) | |
## 2. Formulas
### 2.1 Desired direction — Eq. 1 (p. 4)
$$
e_\alpha = \frac{r_\alpha^k - r_\alpha}{\| r_\alpha^k - r_\alpha \|}
$$
### 2.2 Acceleration toward desired velocity — Eq. 2 (p. 4)
$$
F_\alpha^0 = \frac{v_\alpha^0 \cdot e_\alpha - v_\alpha}{\tau_\alpha}
$$
Uses **actual** velocity $v_\alpha$.
### 2.3 Pedestrian–pedestrian potential & force — Eq. 3 (p. 4), Eq. 13 (p. 7)
$$
V_{\alpha\beta}(b) = V_{\alpha\beta}^0 \cdot \exp\!\left(-\frac{b}{\sigma}\right)
$$
$$
f_{\alpha\beta} = -\nabla_{r_{\alpha\beta}} V_{\alpha\beta}(b)
= \frac{V_{\alpha\beta}^0}{\sigma} \cdot \exp\!\left(-\frac{b}{\sigma}\right) \cdot \nabla b
$$
### 2.4 Elliptical $b$ — Eq. 4 (p. 5)
$$
r_{\alpha\beta} = r_\alpha - r_\beta
$$
$$
s_\beta = v_\beta^0 \cdot \Delta t
$$
> **Team convention:** paper writes $s_\beta = v_\beta \Delta t$ (actual speed); we use $v_\beta^0$ (desired speed).
$$
2b = \sqrt{\left(\| r_{\alpha\beta} \| + \| r_{\alpha\beta} - s_\beta \cdot e_\beta \|\right)^2 - s_\beta^2}
$$
Gradient (derived from Eq. 4, not given explicitly in paper):
$$
\nabla b = \frac{\| r_{\alpha\beta} \| + \| r_{\alpha\beta} - s_\beta \, e_\beta \|}{4b}
\left(
\frac{r_{\alpha\beta}}{\| r_{\alpha\beta} \|}
+ \frac{r_{\alpha\beta} - s_\beta \, e_\beta}{\| r_{\alpha\beta} - s_\beta \, e_\beta \|}
\right)
$$
### 2.5 Border potential & force — Eq. 5 (p. 5), Eq. 13 (p. 7)
$$
U_{\alpha B}\!\left(\| r_{\alpha B} \|\right) = U_{\alpha B}^0 \cdot \exp\!\left(-\frac{\| r_{\alpha B} \|}{R}\right)
$$
$$
f_{\alpha B} = \frac{U_{\alpha B}^0}{R} \cdot \exp\!\left(-\frac{\| r_{\alpha B} \|}{R}\right) \cdot \frac{r_{\alpha B}}{\| r_{\alpha B} \|}
$$
where $r_{\alpha B} = r_\alpha - r_B^\alpha$, and $r_B^\alpha$ is the nearest point of border $B$ to $\alpha$.
### 2.6 Perception weight — Eq. 7 (p. 6)
$$
w(e,\, f) =
\begin{cases}
1 & \text{if } e \cdot f \geq \| f \| \cos\varphi \\
c & \text{otherwise}
\end{cases}
$$
### 2.7 Weighted force terms — Eq. 8 (p. 6) + team convention
$$
F_{\alpha\beta} = w(e_\alpha,\; -f_{\alpha\beta}) \cdot f_{\alpha\beta}
$$
$$
F_{\alpha B} = w(e_\alpha,\; -f_{\alpha B}) \cdot f_{\alpha B}
\qquad \text{(team convention; not explicit in paper)}
$$
> **Note:** Paper Eq. 8 only defines $w$ weighting for ped–ped $F_{\alpha\beta}$; applying it to border $F_{\alpha B}$ is our extension. (Reason see page 6, top: "However, the formulas above for attractive and repulsive effects only hold for situations that are perceived in the desired direction e_alpha(t) of motion.")
### 2.8 Total force — Eq. 9 (p. 6), no attractors (Eq. 6) / fluctuations
$$
F_\alpha = F_\alpha^0 + \sum_\beta F_{\alpha\beta} + \sum_B F_{\alpha B}
$$
> Paper Eq. 9 also includes attractor term $\sum_i F_{\alpha i}$ (Eq. 6, p. 5) and Eq. 10 adds fluctuations; both omitted here per team convention.
### 2.9 Speed cap — Eq. 12 (p. 7)
$$
g\!\left(\frac{v_{\max}}{\| w \|}\right) =
\begin{cases}
1 & \text{if } \| w \| \leq v_{\max} \\[4pt]
\dfrac{v_{\max}}{\| w \|} & \text{otherwise}
\end{cases}
$$
### 2.10 Equations of motion — Eq. 10 (p. 6), Eq. 11 (p. 7)
$$
\frac{dw_\alpha}{dt} = F_\alpha
$$
$$
v_\alpha = w_\alpha \cdot g\!\left(\frac{v_{\max}}{\| w_\alpha \|}\right)
$$
$$
\frac{dr_\alpha}{dt} = v_\alpha
$$
## 3. One Euler timestep (per pedestrian)
Discretisation of Eq. 10–11; not given explicitly in paper.
$$
F_\alpha \leftarrow F_\alpha^0(v_\alpha,\, e_\alpha) + \sum_\beta F_{\alpha\beta} + \sum_B F_{\alpha B}
$$
$$
w_\alpha^{\text{new}} \leftarrow w_\alpha + F_\alpha \cdot dt
$$
$$
v_\alpha^{\text{new}} \leftarrow w_\alpha^{\text{new}} \cdot g\!\left(\frac{v_{\max}}{\| w_\alpha^{\text{new}} \|}\right)
$$
$$
r_\alpha^{\text{new}} \leftarrow r_\alpha + v_\alpha^{\text{new}} \cdot dt
$$
$$
e_\alpha^{\text{new}} \leftarrow \frac{r_\alpha^k - r_\alpha^{\text{new}}}{\| r_\alpha^k - r_\alpha^{\text{new}} \|}
$$
> **Convention:** force pass over all $\alpha$ first, integration pass second.
>
+44
View File
@@ -0,0 +1,44 @@
# Advanced Systems Lab - Spring 2026
This is the GitLab repository of group 70.
Project topic: Social Force Model for Pedestrian Dynamics
The goal of this project was to implement a fast version of Helbing's social force model. The final report includes an analysis and results of the work.
This repository contains all C++ and Python code that was used to generate and analyze the data.
## Compilation
Linux
``
Windows
``
Apple
`clang++ -O3 -march=native -o main_test_visualisation main.cpp forces.cpp`
Compile the code with running the bash script 'src/main/run_simulation.sh'. After compilation was succesfull the user has 3 different option:
1. Benchmark
2. Test
3. Visualization
The flags used are:
`gcc -lm -O3 -mavx2 -mfma -ffast-math -g`
## Storing coordinates in a csv
`./main_test_visualisation <number of pedestrians> <number of iterations> <csv file>`
## Visualization
`python3 visualization.py <csv file> <mp4 file>`
## Benchmark
## Test
+10 -1
View File
@@ -3,25 +3,34 @@
#include "pedestrian.hpp" #include "pedestrian.hpp"
#include <cmath> #include <cmath>
// $\tau_{\alpha}$
const double tau_alpha = 0.5; const double tau_alpha = 0.5;
// $V^0_{\alpha \beta}$
const double V0_AB = 2.1; const double V0_AB = 2.1;
// $\sigma$
const double SIGMA = 0.3; const double SIGMA = 0.3;
// $U^0_{\alpha B}$
const double U0_AB = 10.0; const double U0_AB = 10.0;
// $R$
const double R = 0.2; const double R = 0.2;
// $c$
const double c = 0.5; const double c = 0.5;
// $\varphi$
const double phi = 100.0 / 180.0 * M_PI; const double phi = 100.0 / 180.0 * M_PI;
const double cos_phi = cos(phi); const double cos_phi = cos(phi);
// $\varDelta_{t}$
// step size = 0.2 seconds
const double delta_t = 2; const double delta_t = 2;
const double dt = 0.01; const double dt = 0.001;
// # Optional (forces.cpp: compute_repulsive_effects_from_pedestrians) // # Optional (forces.cpp: compute_repulsive_effects_from_pedestrians)
// const double DISTANCE = 2.0; // const double DISTANCE = 2.0;
+77 -13
View File
@@ -4,7 +4,10 @@
#include "pedestrian.hpp" #include "pedestrian.hpp"
#include "tsc_x86.h" #include "tsc_x86.h"
#include "vector2d.hpp" #include "vector2d.hpp"
#include <fstream>
#include <iostream> #include <iostream>
#include <tuple>
#include <vector>
#define BOARD_WIDTH 10.0 #define BOARD_WIDTH 10.0
#define BOARD_LENGTH 50.0 #define BOARD_LENGTH 50.0
@@ -21,23 +24,34 @@ using namespace std;
Pedestrian *init_pedestrians(int n_p) { Pedestrian *init_pedestrians(int n_p) {
Pedestrian *P = new Pedestrian[n_p]; Pedestrian *P = new Pedestrian[n_p];
std::random_device rd; // use for truly random simulation std::random_device rd; // use for truly random simulation
std::mt19937 gen(rd()); // use rd instead of 42 as seed for real randomness // std::mt19937 gen(rd()); // use rd instead of 42 as seed for real randomness
std::mt19937 gen(42); // use fixed seed for reproducibility
std::normal_distribution<double> velocity_gen(1.34, 0.26); // 1.34 and 0.26 are the mean and stdrd deviation used in paper std::normal_distribution<double> velocity_gen(1.34, 0.26); // 1.34 and 0.26 are the mean and stdrd deviation used in paper
std::uniform_real_distribution<double> x_gen(2, BOARD_LENGTH - 2); std::uniform_real_distribution<double> x_gen(2, BOARD_LENGTH - 2);
std::uniform_real_distribution<double> y_gen(2, BOARD_WIDTH - 2); std::uniform_real_distribution<double> y_gen(2, BOARD_WIDTH - 2);
for (int i = 0; i < n_p / 2; i++) { for (int i = 0; i < n_p / 2; i++) {
Vector2d start_pos = Vector2d(1, y_gen(gen)); double y = y_gen(gen);
Vector2d destination = Vector2d(BOARD_LENGTH - 1, y_gen(gen)); Vector2d start_pos = Vector2d(x_gen(gen), y);
double desired_v0 = velocity_gen(gen); Vector2d destination = Vector2d(BOARD_LENGTH + 300, BOARD_WIDTH / 2);
// double desired_v0 = velocity_gen(gen);
double desired_v0;
do {
desired_v0 = velocity_gen(gen);
} while (desired_v0 <= 0.1); // to avoid small values (Way below the social force -> that would make the walk backwards) (we discovered some weird stuff in the simulation)
double v_max = 1.3 * desired_v0; double v_max = 1.3 * desired_v0;
P[i] = Pedestrian(WHITE, (destination - start_pos) / (destination - start_pos).norm() * desired_v0, start_pos, (destination - start_pos) / (destination - start_pos).norm(), v_max, desired_v0, destination, Vector2d()); P[i] = Pedestrian(WHITE, (destination - start_pos) / (destination - start_pos).norm() * desired_v0, start_pos, (destination - start_pos) / (destination - start_pos).norm(), v_max, desired_v0, destination, Vector2d());
} }
for (int i = n_p / 2; i < n_p; i++) { for (int i = n_p / 2; i < n_p; i++) {
Vector2d start_pos = Vector2d(BOARD_LENGTH - 1, y_gen(gen)); double y = y_gen(gen);
Vector2d destination = Vector2d(1, y_gen(gen)); Vector2d start_pos = Vector2d(x_gen(gen), y);
double desired_v0 = velocity_gen(gen); Vector2d destination = Vector2d(-300, BOARD_WIDTH / 2);
// double desired_v0 = velocity_gen(gen);
double desired_v0;
do {
desired_v0 = velocity_gen(gen);
} while (desired_v0 <= 0.1);
double v_max = 1.3 * desired_v0; double v_max = 1.3 * desired_v0;
P[i] = Pedestrian(BLACK, (destination - start_pos) / (destination - start_pos).norm() * desired_v0, start_pos, (destination - start_pos) / (destination - start_pos).norm(), v_max, desired_v0, destination, Vector2d(0, 0)); P[i] = Pedestrian(BLACK, (destination - start_pos) / (destination - start_pos).norm() * desired_v0, start_pos, (destination - start_pos) / (destination - start_pos).norm(), v_max, desired_v0, destination, Vector2d(0, 0));
} }
@@ -51,12 +65,21 @@ int main(int argc, const char *argv[]) {
int n_p = atoi(argv[1]); int n_p = atoi(argv[1]);
int n_iter = atoi(argv[2]); int n_iter = atoi(argv[2]);
// Logic to get/dump the simulation data
const int dump_interval = 50; // dump every 5 iterations -> 20 fps (since dt = 0.01)
const char *dump_path = (argc >= 4) ? argv[3] : nullptr;
std::vector<std::tuple<int, int, double, double, int>> samples; // t, id, x, y, color
if (dump_path)
samples.reserve((size_t)n_iter / dump_interval * n_p);
Pedestrian *pedestrians = init_pedestrians(n_p); Pedestrian *pedestrians = init_pedestrians(n_p);
// # Start here or right after function signature // # Start here or right after function signature
uint64_t start = start_tsc(); uint64_t start = start_tsc();
// # (8 + 55N - 55 + 144 + 4 + 8 + 4 + 10)*n_p*n_iter // # (8 + 55N - 55 + 192 + 4 + 8 + 4 + 10)*n_p*n_iter
for (int t = 0; t < n_iter; t++) { for (int t = 0; t < n_iter; t++) {
// Pass1: conmpute all forces from the current state // Pass1: conmpute all forces from the current state
for (int i = 0; i < n_p; i++) { for (int i = 0; i < n_p; i++) {
@@ -66,31 +89,63 @@ int main(int argc, const char *argv[]) {
p.f_i.reset(); p.f_i.reset();
// # 8 flops // # 8 flops
//
// $\vec{F}_\alpha(\vec{v}_\alpha, v^0_\alpha \vec{e}_\alpha) \vec{e}_\alpha(t) = \frac{1}{\tau_\alpha}(v^0_\alpha \vec{e}_\alpha - \vec{v}_\alpha)$
//
compute_acceleration_term(&p); compute_acceleration_term(&p);
// # 55N - 55 flops // # 55N - 55 flops
//
// $\sum_{\beta} \vec{F}_{\alpha\beta}(\vec{e}_{\alpha}, \vec{r}_{\alpha} - \vec{r}_{\beta})$
//
compute_repulsive_effects_from_pedestrians(pedestrians, &p, n_p); compute_repulsive_effects_from_pedestrians(pedestrians, &p, n_p);
// # 144 flops // # 192 flops
//
// $\sum_{B} \vec{F}_{\alpha B}(\vec{e}_{\alpha}, \vec{r}_{\alpha} - \vec{r}_{B})$
//
compute_repulsive_effects_from_borders(board, &p); compute_repulsive_effects_from_borders(board, &p);
} }
// Pass2: integrate the forces and update the current state // Pass2: integrate the forces and update the current state
for (int i = 0; i < n_p; i++) { for (int i = 0; i < n_p; i++) {
Pedestrian &p = pedestrians[i]; Pedestrian &p = pedestrians[i];
// # 4 flops = 2 ADDs, 2 MULTs // # 4 flops = 2 ADDs, 2 MULTs
Vector2d w_alpha = p.curr_vel + p.f_i * dt; // integrate preferred velocity: dw/dt = F (Eq. 10)
p.w = p.w + p.f_i * dt;
// Vector2d w_alpha = p.curr_vel + p.f_i * dt; // commented since this was using p.curr_vel instead of p.w (different from paper)
// # 8 flops = 2 MULTs, 2 DIVs, 1 SQRT, 2 MULTs, 1 ADD // # 8 flops = 2 MULTs, 2 DIVs, 1 SQRT, 2 MULTs, 1 ADD
p.curr_vel = w_alpha * g(p.v_max, w_alpha.norm()); p.curr_vel = p.w * g(p.v_max, p.w.norm());
// # 4 flops = 2 ADDs, 2 MULTs // # 4 flops = 2 ADDs, 2 MULTs
//
// $\vec{r}_i^{t+1} += \vec{r}^t_i + v^t_idt$
//
p.curr_pos = p.curr_pos + p.curr_vel * dt; p.curr_pos = p.curr_pos + p.curr_vel * dt;
// how to handle if a pedestrian reached the end of our simulation/end of the hallway
// The option we do here is to just "teleport" the person back to the beginning
// the good thing is we will have a constant flow of pedestrians and in the simulation we should see how lines build up
if (p.color == WHITE && p.curr_pos.x > (BOARD_LENGTH - 1.5)) {
// basically just keep the y position and reset the x
p.curr_pos.x = 1.0;
// p.destination.y = p.curr_pos.y;
}
if (p.color == BLACK && p.curr_pos.x < 1.5) {
p.curr_pos.x = BOARD_LENGTH - 1.0;
// p.destination.y = p.curr_pos.y;
}
// # 10 flops = 5 ADDs, 2 DIVs, 1 SQRT, 2 MULTs // # 10 flops = 5 ADDs, 2 DIVs, 1 SQRT, 2 MULTs
p.e = (p.destination - p.curr_pos) / (p.destination - p.curr_pos).norm(); p.e = (p.destination - p.curr_pos) / (p.destination - p.curr_pos).norm();
// if we have a dump path/file we wanna save the data for visualisation
if (dump_path && (t % dump_interval == 0)) {
samples.emplace_back(t, i, p.curr_pos.x, p.curr_pos.y, p.color);
}
} }
} }
int W = (8 + 55 * n_p - 55 + 144 + 4 + 8 + 4 + 10) * n_p * n_iter; long long W = (long long)(8 + 55 * n_p - 55 + 192 + 4 + 8 + 4 + 10) * n_p * n_iter;
std::cout << "W(n): "; std::cout << "W(n): ";
std::cout << W; std::cout << W;
std::cout << " flops\n"; std::cout << " flops\n";
@@ -106,6 +161,15 @@ int main(int argc, const char *argv[]) {
std::cout << P; std::cout << P;
std::cout << " flops/cycle\n"; std::cout << " flops/cycle\n";
// now we wanna save the data to a csv
if (dump_path) {
std::ofstream out(dump_path);
out << "time,id,x,y,color\n";
for (auto &[t, id, x, y, c] : samples) {
out << t << ',' << id << ',' << x << ',' << y << ',' << c << '\n';
}
}
delete[] pedestrians; delete[] pedestrians;
return 0; return 0;
} }
BIN
View File
Binary file not shown.
+14 -3
View File
@@ -7,15 +7,26 @@ enum Color { BLACK, WHITE };
struct Pedestrian { struct Pedestrian {
Color color; Color color;
Vector2d curr_vel; // $\vec{v}_{\alpha}(t)$
Vector2d curr_vel; // v_alpha (actual, ≤ v_max)
// $\vec{w}_{\alpha}$
Vector2d w; // w_alpha (preferred, integrates force)
// $\vec{r}_\alpha(t)$
Vector2d curr_pos; Vector2d curr_pos;
// $\vec{e}_{\alpha}(t)$
Vector2d e; Vector2d e;
// $v_{\alpha}^{max} = 1.3 v^{0}_{\alpha}$
double v_max; double v_max;
// $v_\alpha^0$
double desired_v0; double desired_v0;
// $\vec{r}^0_\alpha$
Vector2d destination; Vector2d destination;
// social force
Vector2d f_i; Vector2d f_i;
Pedestrian() : color(WHITE), curr_vel(0.0, 0.0), curr_pos(0.0, 0.0), e(0.0, 0.0), v_max(0.0), desired_v0(0.0), destination(0.0, 0.0), f_i(0.0, 0.0) {} Pedestrian() : color(WHITE), curr_vel(0.0, 0.0), w(0.0, 0.0), curr_pos(0.0, 0.0), e(0.0, 0.0), v_max(0.0), desired_v0(0.0), destination(0.0, 0.0), f_i(0.0, 0.0) {}
Pedestrian(Color clr, Vector2d c_v, Vector2d c_p, Vector2d e, double v_max, double desired_v0, Vector2d d, Vector2d f) : color(clr), curr_vel(c_v), curr_pos(c_p), e(e), v_max(v_max), desired_v0(desired_v0), destination(d), f_i(f) {} Pedestrian(Color clr, Vector2d c_v, Vector2d c_p, Vector2d e, double v_max, double desired_v0, Vector2d d, Vector2d f)
: color(clr), curr_vel(c_v), w(c_v), // initialize w = v at t=0
curr_pos(c_p), e(e), v_max(v_max), desired_v0(desired_v0), destination(d), f_i(f) {}
}; };
+1000001
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 48 MiB

BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+52
View File
@@ -0,0 +1,52 @@
import sys
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
if len(sys.argv)<2:
sys.exit("Use it like the following: python visualization.py positions.csv (out.gif)")
df = pd.read_csv(sys.argv[1])
frames = sorted(df["time"].unique())
fig, ax = plt.subplots(figsize = (10,2.2))
ax.set_xlim(0, 50); ax.set_ylim(0, 10)
ax.set_aspect("equal"); ax.set_facecolor("white")
ax.set_xticks([]); ax.set_yticks([])
for s in ("top", "right", "left", "bottom"):
ax.spines[s].set_color("gray")
# Lets define the 2 groups
# WHITE = 1 (left -> right, drawn as filled black circles, like paper)
# BLACK = 0 (right -> left, drawn as empty circles)
s_white = ax.scatter([],[], s=30, facecolors = "black", edgecolor = "black", zorder = 2)
s_black = ax.scatter([],[], s=30, facecolors = "white", edgecolor = "black", zorder = 2)
# update our graphic from t to t+1
title = ax.set_title("")
def update(t):
sub = df[df["time"] == t]
w = sub[sub["color"] == 1]
b = sub[sub["color"] == 0]
s_white.set_offsets(w[["x", "y"]].values)
s_black.set_offsets(b[["x", "y"]].values)
title.set_text(f"t = {t}")
return s_white, s_black, title
anim = FuncAnimation(fig,update, frames = frames, interval=50, blit=False)
if len(sys.argv) >= 3:
anim.save(sys.argv[2], writer="ffmpeg", fps=20)
print(f"saved {sys.argv[2]}")
else:
plt.show()