Skip to content

Commit 221a4c3

Browse files
committed
Add avoidance computation
1 parent a500e8a commit 221a4c3

File tree

3 files changed

+112
-4
lines changed

3 files changed

+112
-4
lines changed

pedpy/__init__.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@
2929
compute_voronoi_density,
3030
)
3131
from .methods.flow_calculator import compute_flow, compute_n_t
32+
from .methods.foo_calculator import (
33+
IntrusionMethod,
34+
compute_avoidance,
35+
compute_intrusion,
36+
)
3237
from .methods.method_utils import (
3338
Cutoff,
3439
compute_frame_range_in_area,
@@ -55,7 +60,6 @@
5560
compute_passing_speed,
5661
compute_voronoi_speed,
5762
)
58-
from .methods.foo_calculator import compute_intrusion, IntrusionMethod
5963
from .plotting.plotting import (
6064
PEDPY_BLUE,
6165
PEDPY_GREEN,
@@ -119,6 +123,7 @@
119123
"compute_voronoi_speed",
120124
"compute_intrusion",
121125
"IntrusionMethod",
126+
"compute_avoidance",
122127
"PEDPY_BLUE",
123128
"PEDPY_GREEN",
124129
"PEDPY_GREY",

pedpy/column_identifier.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,4 @@
3131
WINDOW_SIZE_COL: Final = "window_size"
3232

3333
INTRUSION_COL: Final = "intrusion"
34+
AVOIDANCE_COL: Final = "avoidance"

pedpy/methods/foo_calculator.py

Lines changed: 105 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,22 @@
33

44
from enum import Enum
55

6-
from pedpy.data.trajectory_data import TrajectoryData
7-
from .method_utils import _compute_individual_distances
8-
from pedpy.column_identifier import FRAME_COL, ID_COL, INTRUSION_COL
6+
import numpy as np
97
import pandas
8+
import shapely
9+
10+
from pedpy.column_identifier import (
11+
AVOIDANCE_COL,
12+
FRAME_COL,
13+
ID_COL,
14+
INTRUSION_COL,
15+
)
16+
from pedpy.data.trajectory_data import TrajectoryData
17+
from pedpy.methods.method_utils import (
18+
SpeedCalculation,
19+
_compute_individual_distances,
20+
)
21+
from pedpy.methods.speed_calculator import compute_individual_speed
1022

1123

1224
class IntrusionMethod(Enum): # pylint: disable=too-few-public-methods
@@ -50,3 +62,93 @@ def compute_intrusion(
5062
)
5163

5264
return intrusion
65+
66+
67+
def compute_avoidance(
68+
*,
69+
traj_data: TrajectoryData,
70+
frame_step: int,
71+
radius: float = 0.2,
72+
tau_0: float,
73+
) -> pandas.DataFrame:
74+
"""_summary_.
75+
76+
TODO add documentation here
77+
78+
Args:
79+
traj_data (TrajectoryData): _description_
80+
frame_step (int): _description_
81+
radius (float): _description_
82+
tau_0 (float): _description_
83+
84+
Returns:
85+
pandas.DataFrame: _description_
86+
"""
87+
velocity = compute_individual_speed(
88+
traj_data=traj_data,
89+
frame_step=frame_step,
90+
compute_velocity=True,
91+
speed_calculation=SpeedCalculation.BORDER_SINGLE_SIDED,
92+
)
93+
94+
data = pandas.merge(traj_data.data, velocity, on=[ID_COL, FRAME_COL])
95+
data["velocity"] = shapely.points(data.v_x, data.v_y)
96+
97+
matrix = pandas.merge(
98+
data, data, how="outer", on=FRAME_COL, suffixes=("", "_neighbor")
99+
)
100+
matrix = matrix[matrix.id != matrix.id_neighbor]
101+
102+
distance = np.linalg.norm(
103+
shapely.get_coordinates(matrix.point)
104+
- shapely.get_coordinates(matrix.point_neighbor),
105+
axis=1,
106+
)
107+
108+
e_v = (
109+
shapely.get_coordinates(matrix.point)
110+
- shapely.get_coordinates(matrix.point_neighbor)
111+
) / distance[:, np.newaxis]
112+
113+
v_rel = shapely.get_coordinates(matrix.velocity) - shapely.get_coordinates(
114+
matrix.velocity_neighbor
115+
) / np.linalg.norm(
116+
shapely.get_coordinates(matrix.velocity)
117+
- shapely.get_coordinates(matrix.velocity_neighbor)
118+
)
119+
120+
v_rel_norm = np.linalg.norm(v_rel, axis=1)
121+
122+
dot_product = np.sum(
123+
np.array(np.array(e_v.tolist())) * np.array(np.array(v_rel.tolist())),
124+
axis=1,
125+
)
126+
127+
cos_alpha = dot_product / (distance * v_rel_norm)
128+
129+
ttc = np.full(matrix.shape[0], np.inf)
130+
131+
capital_a = (cos_alpha**2 - 1) * distance**2 + radius**2
132+
133+
# (0.5 * l_a + 0.5 * l_b)**2 in paper
134+
sqrt_a_safe = np.where(
135+
capital_a >= 0, np.sqrt(np.where(capital_a >= 0, capital_a, 0)), np.nan
136+
)
137+
138+
valid_conditions = (
139+
(capital_a >= 0)
140+
& (-cos_alpha * distance - sqrt_a_safe >= 0)
141+
& (v_rel_norm != 0)
142+
)
143+
144+
ttc[valid_conditions] = (
145+
-cos_alpha[valid_conditions] * distance[valid_conditions]
146+
- np.sqrt(capital_a[valid_conditions])
147+
) / v_rel_norm[valid_conditions]
148+
149+
matrix[AVOIDANCE_COL] = tau_0 / ttc
150+
151+
avoidance = matrix.groupby(by=[ID_COL, FRAME_COL], as_index=False).agg(
152+
avoidance=(AVOIDANCE_COL, "max")
153+
)
154+
return avoidance

0 commit comments

Comments
 (0)