2D

Parametric

V = socialforce.potentials.PedPedPotential2D(asymmetry=-1.0)
with socialforce.show.canvas(figsize=(12, 6), ncols=2) as (ax1, ax2):
    socialforce.show.potential_2d(V, ax1)
    socialforce.show.potential_2d_grad(V, ax2)
_images/pedped_2d_2_0.png

Asymmetry

We use a multiplicative function to make a symmetric potential asymmetric. Qualitativly, we would like an exponential function, but one that does not grow exponentially at large distances. We use a softplus function normalized such that it is one at the origin:

(9)\[\begin{align} f_\textrm{asymmetry}(x_{\perp}) &= \frac{1}{\ln 2} \ln(1 + \exp(\textrm{asymmetry} \cdot x_{\perp})) \end{align}\]
# HIDE CODE
asymmetry_factor = socialforce.potentials.PedPedPotential2D.asymmetry_factor

x = torch.linspace(-5, 5, 300)
with socialforce.show.canvas() as ax:
    ax.plot(x, asymmetry_factor(0.0, x), label='no asymmetry')
    ax.plot(x, asymmetry_factor(1.0, x), label='asymmetry = 1.0')
    ax.plot(x, asymmetry_factor(0.5, x), label='asymmetry = 0.5')
    ax.plot(x, asymmetry_factor(-1.0, x), label='asymmetry = -1.0')
    ax.legend()
    ax.set_xlabel('$x_{\\perp}$')
    ax.set_ylabel('asymmetry factor')
_images/pedped_2d_4_0.png

Fitting to Circle and ParallelOvertake Scenarios

The preferred speed needs to be varied. Otherwise the symmetry of the problem creates unrealistic scenarios where the two pedestrians get stuck.

circle = socialforce.scenarios.Circle(ped_ped=V)
parallel = socialforce.scenarios.ParallelOvertake(ped_ped=V)
scenarios = circle.generate(5) + parallel.generate(5)
true_experience = socialforce.Trainer.scenes_to_experience(scenarios)
V = socialforce.potentials.PedPedPotentialMLP2D()

with socialforce.show.canvas(figsize=(12, 6), ncols=2) as (ax1, ax2):
    socialforce.show.potential_2d(V, ax1)
    socialforce.show.potential_2d_grad(V, ax2)
/home/runner/work/socialforce/socialforce/socialforce/show.py:253: UserWarning: No contour levels were found within the data range.
  ax.contour(x1, x2, values.T,
_images/pedped_2d_7_1.png
simulator = socialforce.Simulator(ped_ped=V)
opt = torch.optim.SGD(V.parameters(), lr=1.0)
socialforce.Trainer(simulator, opt).loop(20, true_experience, log_interval=5)
epoch 5: 0.00540996069548192
epoch 10: 0.0009795692840979628
epoch 15: 0.0010826763397047913
epoch 20: 0.0009852333103764694
with socialforce.show.canvas(figsize=(12, 6), ncols=2) as (ax1, ax2):
    socialforce.show.potential_2d(V, ax1)
    socialforce.show.potential_2d_grad(V, ax2)
_images/pedped_2d_9_0.png