irsim.lib.algorithm.social_force_model#

Social Force Model (SFM) for pedestrian / mobile-agent navigation.

Independent Python implementation of the Social Force Model described in:

Helbing, D. & Molnar, P. (1995), Social force model for pedestrian dynamics. Phys. Rev. E 51:4282.

Moussaid, M., Helbing, D., Garnier, S., Johansson, A., Combe, M., Theraulaz, G. (2009), Experimental study of the behavioural mechanisms underlying self-organization in human crowds. Proc. R. Soc. B 276:2755.

The neighbor interaction is the anisotropic, velocity-aware variant from Moussaid-Helbing (2009); the obstacle term is the Helbing-Molnar (1995) summation form – every nearby line obstacle contributes an exponentially decayed push, which (unlike a nearest-segment-only rule) lets symmetric walls cancel and keeps the agent on the centreline.

Each agent integrates Newton-like dynamics v += dt * a where a is the weighted sum of three forces:

  • desired force – relaxation of velocity toward v0 * e_goal;

  • social force – anisotropic repulsion from each neighbor (Moussaid-Helbing 2009 form);

  • obstacle force – exponential repulsion summed over all line obstacles within 5 * sigma_obstacle (Helbing-Molnar 1995 form).

Acknowledgement:

pedsim_ros (srl-freiburg/pedsim_ros) and its vendored libpedsim by Christian Gloor were consulted as reference implementations while writing this module.

Attributes#

Classes#

social_force_model

Social Force Model controller for a single agent.

Module Contents#

class irsim.lib.algorithm.social_force_model.social_force_model(state: list, neighbor_list: list | None = None, line_obs_list: list | None = None, vmax: float = 1.5, step_time: float = 0.1, relaxation_time: float = 0.5, force_factor_desired: float = 1.0, force_factor_social: float = 2.1, force_factor_obstacle: float = 10.0, sigma_obstacle: float = 0.8, lambda_importance: float = 2.0, gamma: float = 0.35, n_angular: float = 2.0, n_velocity: float = 3.0, neighbor_range: float = 10.0, safety_radius: float = 0.0)[source]#

Social Force Model controller for a single agent.

The interface mirrors reciprocal_vel_obs so the two algorithms are interchangeable from a behavior method.

Parameters:
  • state (list) – Agent state [x, y, vx, vy, radius, vx_des, vy_des, theta].

  • neighbor_list (list) – Other moving/static circular agents [[x, y, vx, vy, radius], ...].

  • line_obs_list (list) – Line obstacles [[x1, y1, x2, y2], ...].

  • vmax (float) – Speed cap applied after the velocity update.

  • step_time (float) – Integration step dt.

  • relaxation_time (float) – tau in the desired-force term.

  • force_factor_desired (float) – Weight alpha_D on the desired force.

  • force_factor_social (float) – Weight alpha_S on the social force.

  • force_factor_obstacle (float) – Weight alpha_O on the obstacle force.

  • sigma_obstacle (float) – Decay length of the obstacle repulsion.

  • lambda_importance (float) – Weight of relative velocity in the interaction direction (lambda in MoussaΓ―d 2009).

  • gamma (float) – Sets the interaction range B = gamma * ||t||.

  • n_angular (float) – Angular sharpness n for the sideways force.

  • n_velocity (float) – Angular sharpness n' for the slowdown force.

  • neighbor_range (float) – Max distance for an agent to count as a social-force neighbor.

  • safety_radius (float) – Personal-space buffer subtracted from the agent-to-agent distance inside the social-force exponential. 0 reproduces the upstream behavior (point agents). > 0 shifts the decay closer-in so the repulsion saturates at 2 * safety_radius of centre-to-centre clearance, effectively giving each agent a body radius for SFM.

state#
neighbor_list#
line_obs_list#
vmax = 1.5#
step_time = 0.1#
relaxation_time = 0.5#
force_factor_desired = 1.0#
force_factor_social = 2.1#
force_factor_obstacle = 10.0#
sigma_obstacle = 0.8#
lambda_importance = 2.0#
gamma = 0.35#
n_angular = 2.0#
n_velocity = 3.0#
neighbor_range = 10.0#
safety_radius = 0.0#
update(state: list, neighbor_list: list, line_obs_list: list | None = None) None[source]#

Refresh the per-step inputs without re-instantiating.

cal_vel() list[source]#

Integrate one SFM step and return the new global velocity.

Returns:

Updated velocity [vx, vy], clipped to vmax.

Return type:

list[float]

desired_force() list[source]#

Relaxation toward the desired velocity v0 * e_goal.

The desired velocity is supplied directly via state[5:7].

social_force() list[source]#

Anisotropic neighbor repulsion (Moussaid-Helbing 2009).

Iterates over all neighbors within neighbor_range and sums their contribution.

obstacle_force() list[source]#

Exponential repulsion summed over all nearby line obstacles.

The upstream reference uses only the single nearest obstacle, which oscillates in symmetric environments (two parallel walls flip which one is β€œnearest” each step). We use the Helbing-Molnar (1995) summation form instead: every segment within 5 * sigma_obstacle contributes an exponentially decayed push, so symmetric walls cancel and the agent walks the centreline. The integration is also clamped against overlap (distance < 0 would otherwise make exp(-distance/sigma) explode).

irsim.lib.algorithm.social_force_model.state_a = [0.0, 0.0, 1.0, 0.0, 0.3, 1.0, 0.0, 0.0]#