<jupyter_start><jupyter_text>(corridor)= CorridorWe want to qualitatively study the impact of non-standard Social Force potentials.<jupyter_code>def initial_state_corridor(n):
    _ = torch.manual_seed(42)

    # first n people go right, second n people go left
    state = torch.zeros((n * 2, 6))

    # positions
    state[:n, 0:2] = ((torch.rand((n, 2)) - 0.5) * 2.0) * torch.tensor([25.0, 4.5])
    state[n:, 0:2] = ((torch.rand((n, 2)) - 0.5) * 2.0) * torch.tensor([25.0, 4.5])

    # velocity
    state[:n, 2] = torch.normal(torch.full((n,), 1.34), 0.26)
    state[n:, 2] = torch.normal(torch.full((n,), -1.34), 0.26)

    # x destination
    state[:n, 4] = 100.0
    state[n:, 4] = -100.0

    return state

initial_state = initial_state_corridor(60)<jupyter_output><empty_output><jupyter_text>The space is just two walls at $y=5.0m$ and $y=-5.0m$. To avoid boundary effects,the walls extend beyond the periodic boundaries at $x=-25m$ and $x=25m$.<jupyter_code>upper_wall = torch.stack([torch.linspace(-30, 30, 600), torch.full((600,), 5)], -1)
lower_wall = torch.stack([torch.linspace(-30, 30, 600), torch.full((600,), -5)], -1)
ped_space = socialforce.potentials.PedSpacePotential([upper_wall, lower_wall])<jupyter_output><empty_output><jupyter_text>Reference PotentialStandard SF:<jupyter_code>ped_ped = socialforce.potentials.PedPedPotential()
# HIDE CODE
simulator = socialforce.Simulator(ped_ped=ped_ped, ped_space=ped_space,
                                  oversampling=2, delta_t=0.08)
simulator.integrator = socialforce.simulator.PeriodicBoundary(
    simulator.integrator, x_boundary=[-25.0, 25.0])

with torch.no_grad():
    states_sf = simulator.run(initial_state, 250)

with socialforce.show.track_canvas(ncols=2, figsize=(12, 2), tight_layout=False) as (ax1, ax2):
    socialforce.show.states(ax1, states_sf[0:1], monochrome=True)
    socialforce.show.space(ax1, ped_space)
    ax1.text(0.1, 0.1, '$t = 0s$', transform=ax1.transAxes)
    ax1.set_xlim(-25, 25)

    socialforce.show.states(ax2, states_sf[249:250], monochrome=True)
    socialforce.show.space(ax2, ped_space)
    ax2.text(0.1, 0.1, '$t = 20s$', transform=ax2.transAxes)
    ax2.set_xlim(-25, 25)
# HIDE CODE
with socialforce.show.track_canvas(figsize=(6, 2), tight_layout=False, show=False, dpi=130) as ax:
    ax.set_xlim(-25, 25)
    socialforce.show.space(ax, ped_space)
    video = socialforce.show.state_animation(ax, states_sf, delta_t=0.08).to_html5_video()

IPython.display.HTML(video)<jupyter_output><empty_output><jupyter_text>Diamond Potential<jupyter_code>ped_ped = socialforce.potentials.PedPedPotentialDiamond(sigma=0.5)
# HIDE CODE
simulator = socialforce.Simulator(ped_ped=ped_ped, ped_space=ped_space,
                                  oversampling=2, delta_t=0.08)
simulator.integrator = socialforce.simulator.PeriodicBoundary(
    simulator.integrator, x_boundary=[-25.0, 25.0])

with torch.no_grad():
    states_diamond = simulator.run(initial_state, 250)

with socialforce.show.track_canvas(ncols=2, figsize=(12, 2), tight_layout=False) as (ax1, ax2):
    socialforce.show.states(ax1, states_diamond[0:1], monochrome=True)
    socialforce.show.space(ax1, ped_space)
    ax1.text(0.1, 0.1, '$t = 0s$', transform=ax1.transAxes)
    ax1.set_xlim(-25, 25)

    socialforce.show.states(ax2, states_diamond[249:250], monochrome=True)
    socialforce.show.space(ax2, ped_space)
    ax2.text(0.1, 0.1, '$t = 20s$', transform=ax2.transAxes)
    ax2.set_xlim(-25, 25)
# HIDE CODE
with socialforce.show.track_canvas(figsize=(6, 2), tight_layout=False, show=False, dpi=130) as ax:
    ax.set_xlim(-25, 25)
    socialforce.show.space(ax, ped_space)
    video = socialforce.show.state_animation(ax, states_diamond, delta_t=0.08).to_html5_video()

IPython.display.HTML(video)<jupyter_output><empty_output><jupyter_text>Asymmetric Diamond<jupyter_code>ped_ped = socialforce.potentials.PedPedPotentialDiamond(sigma=0.5, asymmetry_angle=-20.0)
# HIDE CODE
simulator = socialforce.Simulator(ped_ped=ped_ped, ped_space=ped_space,
                                  oversampling=2, delta_t=0.08)
simulator.integrator = socialforce.simulator.PeriodicBoundary(
    simulator.integrator, x_boundary=[-25.0, 25.0])

with torch.no_grad():
    states_diamond_sd = simulator.run(initial_state, 500)

with socialforce.show.track_canvas(ncols=2, figsize=(12, 2), tight_layout=False) as (ax1, ax2):
    socialforce.show.states(ax1, states_diamond_sd[0:1], monochrome=True)
    socialforce.show.space(ax1, ped_space)
    ax1.text(0.1, 0.1, '$t = 0s$', transform=ax1.transAxes)
    ax1.set_xlim(-25, 25)

    socialforce.show.states(ax2, states_diamond_sd[499:500], monochrome=True)
    socialforce.show.space(ax2, ped_space)
    ax2.text(0.1, 0.1, '$t = 40s$', transform=ax2.transAxes)
    ax2.set_xlim(-25, 25)
# HIDE CODE
with socialforce.show.track_canvas(figsize=(6, 2), tight_layout=False, show=False, dpi=130) as ax:
    ax.set_xlim(-25, 25)
    socialforce.show.space(ax, ped_space)
    video = socialforce.show.state_animation(ax, states_diamond_sd, delta_t=0.08).to_html5_video()

IPython.display.HTML(video)<jupyter_output><empty_output><jupyter_text>Speed Analysis<jupyter_code># HIDE CODE
def relative_speeds(states):
    speeds = np.linalg.norm(states[:, :, 2:4], axis=-1)
    preferred = states[:, :, 9]
    relative = speeds / preferred

    # ignore the first 50
    relative = relative[50:]
    return relative.reshape(-1)

def median_speed(states):
    speeds = np.linalg.norm(states[:, :, 2:4], axis=-1)

    # ignore the first 50
    speeds = speeds[50:]
    return np.median(speeds)

with socialforce.show.canvas() as ax:
    r_sf = relative_speeds(states_sf)
    r_diamond = relative_speeds(states_diamond)
    r_diamond_sd = relative_speeds(states_diamond_sd)
    ax.hist([r_sf, r_diamond, r_diamond_sd], bins=30, range=(0.8, 1.35), density=True, 
            label=[f'Social Force, $v_{{median}}$ = {median_speed(states_sf):.2f}m/s', 
                   f'diamond, $v_{{median}}$ = {median_speed(states_diamond):.2f}m/s',
                   f'speed-dependent diamond, $v_{{median}}$ = {median_speed(states_diamond_sd):.2f}m/s'])
    ax.legend()
    ax.set_xlabel('$v / v_{preferred}$ [m/s]')<jupyter_output><empty_output><jupyter_text>The simulation with standard social force potential leads to pedestrians thatare above their preferred speed whereas in the simulation with the diamondpotential the median speed as at the preferred speed of $1.34m/s$.This is a consequence of the asymmetric nature of the Social Force: the force experianced by pedestrian $\alpha$ due $\beta$ is different (not just opposite) from the force experience by $\beta$ from $\alpha$.When pedestrian $\alpha$ walks in front of $\beta$, $\beta$ will feel almost noforce to slow down as the potential of $\alpha$ is shifted more towards the front.Pedestrian $\alpha$ however will be in the range of the potential from $\beta$who is behind. That force will be halfed by the field-of-view modulation, butthat is still a stronger force than what $\beta$ experiences. In this corridor example with the Social Force pedestrian-pedestrian potential,pedestrians that are in front tend to get pushed to accelerate more than thepedestrians behind to slow down. There is no such asymmetry in the diamond potential.  Asymmetry Analysis<jupyter_code># HIDE CODE
def x2(states):
    x2_coordinates = np.copy(states[:, :, 1])
    x2_coordinates[states[:, :, 6] < 0.0] *= -1.0

    # only take last ones
    x2_coordinates = x2_coordinates[-1]
    return x2_coordinates.reshape(-1)

def mean_x2(states):
    return np.mean(x2(states))

with socialforce.show.canvas() as ax:
    x2_sf = x2(states_sf)
    x2_diamond = x2(states_diamond)
    x2_diamond_sd = x2(states_diamond_sd)
    ax.hist([x2_sf, x2_diamond, x2_diamond_sd], bins=6, range=(-5.0, 5.0), density=True, 
            label=[f'Social Force, $\\overline{{x}}_2$ = {mean_x2(states_sf):.1f}m', 
                   f'diamond, $\\overline{{x}}_2$ = {mean_x2(states_diamond):.1f}m',
                   f'speed-dependent diamond, $\\overline{{x}}_2$ = {mean_x2(states_diamond_sd):.1f}m'],
            orientation='horizontal')
    ax.legend()
    ax.set_ylabel('$x_2$ [m]')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.141396933560477, 'fraction_numerical': 0.044901435872475054, 'mean_word_length': 4.407236842105263, 'pattern_counts': {'":': 0, '<': 30, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '493853', 'license': 'MIT', 'n_tokens_mistral': 3266, 'n_tokens_neox': 2970, 'n_words': 604, 'path': 'guide/corridor.ipynb', 'repo_name': 'svenkreiss/socialforce', 'size': '8218'}