Source code for jupedsim.models.social_force

# SPDX-License-Identifier: LGPL-3.0-or-later

import warnings
from dataclasses import dataclass

try:
    from warnings import deprecated
except ImportError:
    from deprecated import deprecated

import jupedsim.native as py_jps


[docs] @dataclass(kw_only=True) class SocialForceModel: r"""Parameters for Social Force Model All attributes are initialized with reasonably good defaults. See the scientific publication for more details about this model https://doi.org/10.1038/35035023 Attributes: body_force: describes the strength with which an agent is influenced by pushing forces from obstacles and neighbors in its direct proximity. [in kg s^-2] (is called k) friction: describes the strength with which an agent is influenced by frictional forces from obstacles and neighbors in its direct proximity. [in kg m^-1 s^-1] (is called :math:`\kappa`) """ body_force: float = 120000 # [kg s^-2] is called k friction: float = 240000 # [kg m^-1 s^-1] is called kappa def __init__( self, *, body_force: float = 120000, friction: float = 240000, bodyForce=None, ): """ Init dataclass SocialForceMode to handle deprecated arguments. """ self.body_force = body_force if bodyForce is not None: warnings.warn( "'bodyForce' is deprecated, use 'body_force' instead.", DeprecationWarning, stacklevel=2, ) self.body_force = bodyForce self.friction = friction @property @deprecated("deprecated, use 'body_force' instead.") def bodyForce(self) -> float: return self.body_force @bodyForce.setter @deprecated("deprecated, use 'body_force' instead.") def bodyForce(self, bodyForce): self.body_force = bodyForce
[docs] @dataclass(kw_only=True) class SocialForceModelAgentParameters: """ Parameters required to create an Agent in the Social Force Model. See the scientific publication for more details about this model https://doi.org/10.1038/35035023 Attributes: position: Position of the agent. orientation: Orientation of the agent. journey_id: Id of the journey the agent follows. stage_id: Id of the stage the agent targets. velocity: current velocity of the agent. mass: mass of the agent. [in kg] (is called m) desired_speed: desired Speed of the agent. [in m/s] (is called v0) reaction_time: reaction Time of the agent. [in s] (is called :math:`\\tau`) agent_scale: indicates how strong an agent is influenced by pushing forces from neighbors. [in N] (is called A) obstacle_scale: indicates how strong an agent is influenced by pushing forces from obstacles. [in N] (is called A) force_distance: indicates how much the distance between an agent and obstacles or neighbors influences social forces. [in m] (is called B) radius: radius of the space an agent occupies. [in m] (is called r) """ # todo write force equation from paper position: tuple[float, float] = (0.0, 0.0) orientation: tuple[float, float] = (0.0, 0.0) journey_id: int = -1 stage_id: int = -1 velocity: tuple[float, float] = (0.0, 0.0) # the values are from paper. doi is in class description mass: float = 80.0 # [kg] is called m desired_speed: float = ( 0.8 # [m / s] is called v0 can be set higher depending on situation ) reaction_time: float = 0.5 # [s] is called tau agent_scale: float = 2000 # [N] is called A obstacle_scale: float = 2000 # [N] is called A force_distance: float = 0.08 # [m] is called B radius: float = ( 0.3 # [m] in paper 2r is uniformy distibuted in interval [0.5 m, 0.7 m] ) def __init__( self, position: tuple[float, float] = (0.0, 0.0), orientation: tuple[float, float] = (0.0, 0.0), journey_id: int = -1, stage_id: int = -1, velocity: tuple[float, float] = (0.0, 0.0), mass: float = 80.0, desired_speed: float = 0.8, reaction_time: float = 0.5, agent_scale: float = 2000, obstacle_scale: float = 2000, force_distance: float = 0.08, radius: float = 0.3, desiredSpeed=None, reactionTime=None, agentScale=None, obstacleScale=None, forceDistance=None, ): """Init dataclass to handle deprecated arguments.""" self.position = position self.orientation = orientation self.journey_id = journey_id self.stage_id = stage_id self.velocity = velocity self.mass = mass self.radius = radius deprecated_map = { "desiredSpeed": "desired_speed", "reactionTime": "reaction_time", "agentScale": "agent_scale", "obstacleScale": "obstacle_scale", "forceDistance": "force_distance", } for old_name, new_name in deprecated_map.items(): if locals()[old_name]: warnings.warn( f"'{old_name}' is deprecated, use '{new_name}' instead.", DeprecationWarning, stacklevel=2, ) setattr(self, new_name, locals()[old_name]) else: setattr(self, new_name, locals()[new_name]) print(self) @property @deprecated("deprecated, use 'desired_speed' instead.") def desiredSpeed(self) -> float: return self.desired_speed @desiredSpeed.setter @deprecated("deprecated, use 'desired_speed' instead.") def desiredSpeed(self, desiredSpeed): self.desired_speed = desiredSpeed @property @deprecated("deprecated, use 'reaction_time' instead.") def reactionTime(self) -> float: return self.reaction_time @reactionTime.setter @deprecated("deprecated, use 'reaction_time' instead.") def reactionTime(self, reactionTime): self.reaction_time = reactionTime @property @deprecated("deprecated, use 'agent_scale' instead.") def agentScale(self) -> float: return self.agent_scale @agentScale.setter @deprecated("deprecated, use 'agent_scale' instead.") def agentScale(self, agentScale): self.agent_scale = agentScale @property @deprecated("deprecated, use 'obstacle_scale' instead.") def obstacleScale(self) -> float: return self.obstacle_scale @obstacleScale.setter @deprecated("deprecated, use 'obstacle_scale' instead.") def obstacleScale(self, obstacleScale): self.obstacle_scale = obstacleScale @property @deprecated("deprecated, use 'force_distance' instead.") def forceDistance(self) -> float: return self.force_distance @forceDistance.setter @deprecated("deprecated, use 'force_distance' instead.") def forceDistance(self, forceDistance): self.force_distance = forceDistance def as_native( self, ) -> py_jps.SocialForceModelAgentParameters: return py_jps.SocialForceModelAgentParameters( position=self.position, orientation=self.orientation, journey_id=self.journey_id, stage_id=self.stage_id, velocity=self.velocity, mass=self.mass, desired_speed=self.desired_speed, reaction_time=self.reaction_time, agent_scale=self.agent_scale, obstacle_scale=self.obstacle_scale, force_distance=self.force_distance, radius=self.radius, )
[docs] class SocialForceModelState: def __init__(self, backing) -> None: self._obj = backing @property def velocity(self) -> tuple[float, float]: """velocity of this agent.""" return self._obj.velocity @velocity.setter def velocity(self, velocity): self._obj.velocity = velocity @property def mass(self) -> float: """mass of this agent.""" return self._obj.mass @mass.setter def mass(self, mass): self._obj.mass = mass @property def desiredSpeed(self) -> float: """desired Speed of this agent.""" warnings.warn( "'desiredSpeed' is deprecated, use 'desired_speed' instead.", DeprecationWarning, stacklevel=2, ) return self._obj.desired_speed @desiredSpeed.setter def desiredSpeed(self, desiredSpeed): warnings.warn( "'desiredSpeed' is deprecated, use 'desired_speed' instead.", DeprecationWarning, stacklevel=2, ) self._obj.desired_speed = desiredSpeed @property def desired_speed(self) -> float: """desired Speed of this agent.""" return self._obj.desired_speed @desired_speed.setter def desired_speed(self, desired_speed): self._obj.desired_speed = desired_speed @property @deprecated("deprecated, use 'reaction_time' instead.") def reactionTime(self) -> float: """reaction Time of this agent.""" return self._obj.reaction_time @reactionTime.setter @deprecated("deprecated, use 'reaction_time' instead.") def reactionTime(self, reactionTime): self._obj.reaction_time = reactionTime @property def reaction_time(self) -> float: return self._obj.reaction_time @reaction_time.setter def reaction_time(self, reaction_time): self._obj.reaction_time = reaction_time @property @deprecated("deprecated, use 'agent_scale' instead.") def agentScale(self) -> float: return self._obj.agent_scale @agentScale.setter @deprecated("deprecated, use 'agent_scale' instead.") def agentScale(self, agentScale): self._obj.agent_scale = agentScale @property def agent_scale(self) -> float: return self._obj.agent_scale @agent_scale.setter def agent_scale(self, agent_scale): self._obj.agent_scale = agent_scale @property @deprecated("deprecated, use 'obstacle_scale' instead.") def obstacleScale(self) -> float: return self._obj.obstacle_scale @obstacleScale.setter @deprecated("deprecated, use 'obstacle_scale' instead.") def obstacleScale(self, obstacleScale): self._obj.obstacle_scale = obstacleScale @property def obstacle_scale(self) -> float: return self._obj.obstacle_scale @obstacle_scale.setter def obstacle_scale(self, obstacle_scale): self._obj.obstacle_scale = obstacle_scale @property @deprecated("deprecated, use 'force_distance' instead.") def forceDistance(self) -> float: return self._obj.force_distance @forceDistance.setter @deprecated("deprecated, use 'force_distance' instead.") def forceDistance(self, forceDistance): self._obj.force_distance = forceDistance @property def force_distance(self) -> float: return self._obj.force_distance @force_distance.setter def force_distance(self, force_distance): self._obj.force_distance = force_distance @property def radius(self) -> float: """radius of this agent.""" return self._obj.radius @radius.setter def radius(self, radius): self._obj.radius = radius