irsim.lib.algorithm#
Core algorithms for IR-SIM simulation.
This package contains: - kinematics: Robot kinematics functions - rvo: Reciprocal Velocity Obstacle algorithm - social_force_model: Anisotropic Social Force Model (Moussaïd 2009), per-agent and batched with Moussaïd 2010 social groups - generation: Polygon generation utilities - ray_casting_2d: Vectorized 2D ray casting for lidar sensors
Submodules#
Classes#
A class to implement the Reciprocal Velocity Obstacle (RVO) algorithm for multi-robot collision avoidance. |
|
Vectorized Social Force Model for a crowd of agents. |
|
Social Force Model controller for a single agent. |
Functions#
|
Generate a random polygon around a center point. |
reference: https://stackoverflow.com/questions/8997099/algorithm-to-generate-random-2d-polygon |
|
|
Calculate the next state for an Ackermann steering vehicle. |
|
Calculate the next state for a differential wheel robot. |
|
Calculate the next state for an omnidirectional robot with angular velocity. |
|
Calculate the next position for an omnidirectional robot. |
|
Cast a 2D lidar geometry against already-detected objects. |
Package Contents#
- irsim.lib.algorithm.generate_polygon(center: list[float], avg_radius: float, irregularity: float, spikeyness: float, num_vertices: int) numpy.ndarray[源代码]#
Generate a random polygon around a center point.
- 参数:
center (Tuple[float, float]) -- Center of the polygon.
avg_radius (float) -- Average radius from the center to vertices.
irregularity (float) -- Variance of angle spacing between vertices. Range [0, 1]
spikeyness (float) -- Variance of radius from the center. Range [0, 1]
num_vertices (int) -- Number of vertices for the polygon.
- 返回:
Vertices of the polygon in CCW order.
- 返回类型:
numpy.ndarray
- irsim.lib.algorithm.random_generate_polygon(number: int = 1, center_range: list[float] | None = None, avg_radius_range: list[float] | None = None, irregularity_range: list[float] | None = None, spikeyness_range: list[float] | None = None, num_vertices_range: list[int] | None = None, **kwargs: Any) numpy.ndarray | list[numpy.ndarray][源代码]#
reference: https://stackoverflow.com/questions/8997099/algorithm-to-generate-random-2d-polygon
Generate random polygons with specified properties.
- 参数:
number (int) -- Number of polygons to generate (default 1).
center_range (List[float]) -- Range for the polygon center [min_x, min_y, max_x, max_y].
avg_radius_range (List[float]) -- Range for the average radius of the polygons.
irregularity_range (List[float]) -- Range for the irregularity of the polygons.
spikeyness_range (List[float]) -- Range for the spikeyness of the polygons.
num_vertices_range (List[int]) -- Range for the number of vertices of the polygons.
- 返回:
List of vertices for each polygon or a single polygon's vertices if number=1.
- irsim.lib.algorithm.ackermann_kinematics(state: numpy.ndarray, velocity: numpy.ndarray, step_time: float, noise: bool = False, alpha: list[float] | None = None, mode: str = 'steer', wheelbase: float = 1) numpy.ndarray[源代码]#
Calculate the next state for an Ackermann steering vehicle.
- 参数:
state -- A 4x1 vector [x, y, theta, steer_angle] representing the current state.
velocity -- A 2x1 vector representing the current velocities, format depends on mode. For "steer" mode, [linear, steer_angle] is expected. For "angular" mode, [linear, angular] is expected.
step_time -- The time step for the simulation.
noise -- Boolean indicating whether to add noise to the velocity (default False).
alpha -- List of noise parameters for the velocity model (default [0.03, 0, 0, 0.03]). alpha[0] and alpha[1] are for linear velocity, alpha[2] and alpha[3] are for angular velocity.
mode -- The kinematic mode, either "steer" or "angular" (default "steer").
wheelbase -- The distance between the front and rear axles (default 1).
- 返回:
A 4x1 vector representing the next state.
- 返回类型:
new_state
- irsim.lib.algorithm.differential_kinematics(state: numpy.ndarray, velocity: numpy.ndarray, step_time: float, noise: bool = False, alpha: list[float] | None = None) numpy.ndarray[源代码]#
Calculate the next state for a differential wheel robot.
- 参数:
state -- A 3x1 vector [x, y, theta] representing the current position and orientation.
velocity -- A 2x1 vector [linear, angular] representing the current velocities.
step_time -- The time step for the simulation.
noise -- Boolean indicating whether to add noise to the velocity (default False).
alpha -- List of noise parameters for the velocity model (default [0.03, 0, 0, 0.03]). alpha[0] and alpha[1] are for linear velocity, alpha[2] and alpha[3] are for angular velocity.
- 返回:
A 3x1 vector [x, y, theta] representing the next state.
- 返回类型:
next_state
- irsim.lib.algorithm.omni_angular_kinematics(state: numpy.ndarray, velocity: numpy.ndarray, step_time: float, noise: bool = False, alpha: list[float] | None = None) numpy.ndarray[源代码]#
Calculate the next state for an omnidirectional robot with angular velocity.
Uses body-frame velocity: the first two components are forward and lateral speeds relative to the robot heading, and the third is yaw rate.
- 参数:
state -- A 3x1 vector [x, y, theta] representing the current position and orientation.
velocity -- A 3x1 vector [forward, lateral, yaw_rate] in body frame.
step_time -- The time step for the simulation.
noise -- Boolean indicating whether to add noise to the velocity (default False).
alpha -- List of noise parameters [alpha_fwd, alpha_lat, alpha_yaw] (default [0.03, 0.03, 0.03]). Each value scales the standard deviation for the corresponding velocity channel.
- 返回:
A 3x1 vector [x, y, theta] representing the next state.
- 返回类型:
next_state
- irsim.lib.algorithm.omni_kinematics(state: numpy.ndarray, velocity: numpy.ndarray, step_time: float, noise: bool = False, alpha: list[float] | None = None) numpy.ndarray[源代码]#
Calculate the next position for an omnidirectional robot.
Uses body-frame velocity: the two components are forward and lateral speeds relative to the robot heading (theta). Since omni robots have no yaw control, theta remains unchanged.
- 参数:
state -- A 3x1 vector [x, y, theta] representing the current state.
velocity -- A 2x1 vector [forward, lateral] in body frame.
step_time -- The time step for the simulation.
noise -- Boolean indicating whether to add noise to the velocity (default False).
alpha -- List of noise parameters for the velocity model (default [0.03, 0.03]).
- 返回:
- A 3x1 vector [x, y, theta] representing the next state.
Theta is preserved unchanged.
- 返回类型:
next_state
- irsim.lib.algorithm.cast_rays(lidar_geometry, detected_objects, max_range: float) tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray][源代码]#
Cast a 2D lidar geometry against already-detected objects.
This geometry-only operation derives ray parameters, gathers boundary segments from the supplied objects, runs the numerical kernel, and maps segment hits back to indices in
detected_objects. Scene lookup remains the sensor's responsibility.- 参数:
lidar_geometry -- Max-range beams in world coordinates as a Shapely multiline geometry.
detected_objects -- Objects selected by the sensor's scene query.
max_range -- Maximum ray length; misses return this value.
- 返回:
Ranges, indices into
detected_objects, origin, and directions.- 返回类型:
tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]
- class irsim.lib.algorithm.reciprocal_vel_obs(state: list, obs_state_list=None, vxmax=1.5, vymax=1.5, acce=0.5, factor=1.0, line_obs_list=None)[源代码]#
A class to implement the Reciprocal Velocity Obstacle (RVO) algorithm for multi-robot collision avoidance.
- 参数:
state (list) -- The rvo state of the agent [x, y, vx, vy, radius, vx_des, vy_des].
obs_state_list (list) -- List of states of static obstacles [[x, y, vx, vy, radius]].
vxmax (float) -- Maximum velocity in the x direction.
vymax (float) -- Maximum velocity in the y direction.
acce (float) -- Acceleration limit.
factor (float) -- Penalty weighting factor for velocity selection.
line_obs_list (list) -- List of line segments [[x1, y1, x2, y2], ...].
- state#
- obs_state_list = None#
- line_obs_list = None#
- vxmax = 1.5#
- vymax = 1.5#
- acce = 0.5#
- factor = 1.0#
- update(state, obs_state_list, line_obs_list=None)[源代码]#
Update the agent, circular-obstacle, and line-obstacle states.
- cal_vel(mode='rvo')[源代码]#
Calculate the velocity of the agent based on the Reciprocal Velocity Obstacle (RVO) algorithm.
- 参数:
mode (str) -- The vo configure to calculate the velocity. It can be "rvo", "hrvo", or "vo". - rvo: Reciprocal Velocity Obstacle (RVO) algorithm, for multi-robot collision avoidance. - hrvo: Hybrid Reciprocal Velocity Obstacle (HRVO) algorithm, for multi-robot collision avoidance. - vo: Velocity Obstacle (VO) algorithm, for obstacle-robot collision avoidance.
- 返回:
Selected velocity [vx, vy].
- 返回类型:
list[float]
- config_rvo_mode(obstacle)[源代码]#
Build one RVO cone for a circular obstacle.
- 参数:
obstacle -- Neighbour state
[x, y, vx, vy, radius], or the static form[x, y, radius](zero velocity).- 返回:
[apex, left_vector, right_vector]cone description.- 返回类型:
list
- config_hrvo_mode(obstacle)[源代码]#
Build one HRVO cone for a circular obstacle.
- 参数:
obstacle -- Neighbour state
[x, y, vx, vy, radius], or the static form[x, y, radius](zero velocity).- 返回:
[apex, left_vector, right_vector]cone description.- 返回类型:
list
- config_vo_mode(obstacle)[源代码]#
Build one VO cone for a circular obstacle.
- 参数:
obstacle -- Neighbour state
[x, y, vx, vy, radius], or the static form[x, y, radius](zero velocity).- 返回:
[apex, left_vector, right_vector]cone description.- 返回类型:
list
- config_vo_lines()[源代码]#
Compute VO cones for line segment obstacles.
For each segment, compute the angular span as seen from the agent, expanded by asin(r / dist) on each side to account for the agent radius. The apex is [0, 0] since line obstacles are static.
- vel_candidate(rvo_list)[源代码]#
Sample reachable velocities and split them by VO feasibility.
- 参数:
rvo_list -- Velocity-obstacle cone descriptions
[apex, left, right].- 返回:
Feasible velocities outside all cones and infeasible velocities inside at least one cone.
- 返回类型:
tuple[list, list]
- vel_select(vo_outside, vo_inside)[源代码]#
Select the best velocity from feasible candidates or penalized fallback.
Both arguments may be lists of
[vx, vy]or(N, 2)arrays; the first minimum is returned, asminwould.
- penalties(vels, vel_des, factor)[源代码]#
Vectorized
penalty()for an(N, 2)array of velocities.Same formulas and branches as the scalar version, evaluated for all candidates at once; the crowded-scene fallback otherwise calls
penaltyhundreds of times per robot per step.
- penalty(vel, vel_des, factor)[源代码]#
Scalar
penalties()for one velocity, kept for compatibility.
- class irsim.lib.algorithm.SocialForceModelBatch(states, neighbor_states=None, line_obs_list=None, social_groups: list[list[int]] | 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, force_factor_coherence: float = 2.0, force_factor_group_repulsion: float = 1.0, group_repulsion_threshold: float | None = None, force_factor_gaze: float = 3.0, gaze_vision_angle: float = 90.0)[源代码]#
Vectorized Social Force Model for a crowd of agents.
Evaluates the same desired, social and obstacle forces as
social_force_modelforNagents at once from one state snapshot. Every agent therefore reacts to the same instant, so the result does not depend on the order in which agents are stepped, and the pairwise social term is array math over allN x (N + M)pairs instead of a Python loop.Agents can optionally be partitioned into social groups (people walking together). Members of a group receive the three extra forces of Moussaid et al. (2010), in the formulation used by pedsim_ros:
coherence -- pull toward the group's centre of mass, ramping in smoothly (
tanh) once a member is further than(size - 1) / 2metres from it;repulsion -- push apart members whose centres come closer than
group_repulsion_threshold;gaze -- brake along the velocity,
f = -alpha * v, when the other members' centre of mass lies outside agaze_vision_anglecone around the walking direction;alphais the missing head rotation in radians, so an agent slows down until it can see its group again.
引用
Moussaid, M., Perozo, N., Garnier, S., Helbing, D., Theraulaz, G. (2010), The walking behaviour of pedestrian social groups and its impact on crowd dynamics. PLoS ONE 5(4): e10047.
PySocialForce, yuxiang-gao/PySocialForce -- NumPy implementation of the extended social force model whose batched force evaluation and group forces this class follows.
- 参数:
states (array-like) --
(N, 8)agent states[x, y, vx, vy, radius, vx_des, vy_des, theta];thetais carried for the caller and not used by the forces.neighbor_states (array-like) --
(M, 5)circular neighbours that are not part of the batch,[[x, y, vx, vy, radius], ...](robots driven by other behaviors, circular obstacles). They push batch agents but are not moved.line_obs_list (array-like) --
(K, 4)line obstacles[[x1, y1, x2, y2], ...].social_groups (list[list[int]] | None) -- Index lists into
states; each agent may appear in at most one group.Noneor[]disables the group forces.vmax (float) -- Speed cap applied after the velocity update.
step_time (float) -- Integration step
dt.relaxation_time (float) --
tauin the desired-force term.force_factor_desired (float) -- Weight on the desired force.
force_factor_social (float) -- Weight on the social force.
force_factor_obstacle (float) -- Weight on the obstacle force.
sigma_obstacle (float) -- Decay length of the obstacle repulsion.
lambda_importance (float) -- Weight of relative velocity in the interaction direction.
gamma (float) -- Sets the interaction range
B = gamma * ||t||.n_angular (float) -- Angular sharpness
nfor the sideways force.n_velocity (float) -- Angular sharpness
n'for the slowdown force.neighbor_range (float) -- Agents further apart than this ignore each other in the social force.
safety_radius (float) -- Personal-space buffer subtracted from the agent-to-agent distance inside the social-force exponential.
force_factor_coherence (float) -- Weight on the group coherence force.
force_factor_group_repulsion (float) -- Weight on the intra-group repulsion force.
group_repulsion_threshold (float | None) -- Centre-to-centre distance below which two group members repel each other.
Noneuses the sum of their radii (states[:, 4]), i.e. members push apart as soon as their discs touch.force_factor_gaze (float) -- Weight on the group gaze force.
gaze_vision_angle (float) -- Half-angle, in degrees, of the cone around the walking direction inside which the group's centre of mass is considered visible.
- 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#
- force_factor_coherence = 2.0#
- force_factor_group_repulsion = 1.0#
- group_repulsion_threshold = None#
- force_factor_gaze = 3.0#
- gaze_vision_angle = 90.0#
- social_groups: list[numpy.ndarray] = []#
- update(states, neighbor_states=None, line_obs_list=None, social_groups: list[list[int]] | None = None) None[源代码]#
Refresh the per-step inputs without re-instantiating.
- 参数:
states --
(N, 8)agent states.neighbor_states --
(M, 5)external circular neighbours.line_obs_list --
(K, 4)line obstacles.social_groups -- New group partition, or
Noneto keep the current one. Pass[]to switch the group forces off.
- property n: int#
Number of agents in the batch.
- cal_vel() numpy.ndarray[源代码]#
Integrate one SFM step for every agent.
- 返回:
(N, 2)updated world-frame velocities, each clipped tovmax.- 返回类型:
np.ndarray
- social_force() numpy.ndarray[源代码]#
Anisotropic neighbour repulsion (Moussaid-Helbing 2009).
Each agent sums the contribution of every other batch agent and every external neighbour closer than
neighbor_range. Matchessocial_force_model.social_force()term by term.
- obstacle_force() numpy.ndarray[源代码]#
Exponential repulsion summed over all nearby line obstacles.
Same rule as
social_force_model.obstacle_force(): every segment within5 * sigma_obstacle + radiusof an agent's centre contributes, the decay is clamped at the body surface, and a segment passing exactly through the centre pushes along+x.
- coherence_force() numpy.ndarray[源代码]#
Pull each member toward its group's centre of mass.
The pull is
(com - p) * (tanh(d - d_max) + 1) / 2withd_max = (size - 1) / 2metres, the smooth variant of the paper's step rule used by pedsim_ros.
- group_repulsive_force() numpy.ndarray[源代码]#
Push apart group members that come too close.
Each pair closer than
group_repulsion_threshold(or the sum of the two radii when that isNone) contributes the raw offsetp_self - p_other.
- gaze_force() numpy.ndarray[源代码]#
Brake when the rest of the group falls out of view.
With
phithe angle between the walking directionvand the other members' centre of mass, the force is-(phi - phi_vis) * vwhenphiexceedsgaze_vision_angleand zero otherwise. A stationary member has no walking direction and gets no gaze force.
- class irsim.lib.algorithm.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)[源代码]#
Social Force Model controller for a single agent.
The interface mirrors
reciprocal_vel_obsso the two algorithms are interchangeable from a behavior method.- 参数:
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) --
tauin the desired-force term.force_factor_desired (float) -- Weight
alpha_Don the desired force.force_factor_social (float) -- Weight
alpha_Son the social force.force_factor_obstacle (float) -- Weight
alpha_Oon the obstacle force.sigma_obstacle (float) -- Decay length of the obstacle repulsion.
lambda_importance (float) -- Weight of relative velocity in the interaction direction (
lambdain Moussaïd 2009).gamma (float) -- Sets the interaction range
B = gamma * ||t||.n_angular (float) -- Angular sharpness
nfor 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.
0reproduces the upstream behavior (point agents).> 0shifts the decay closer-in so the repulsion saturates at2 * safety_radiusof 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[源代码]#
Refresh the per-step inputs without re-instantiating.
- cal_vel() list[源代码]#
Integrate one SFM step and return the new global velocity.
- 返回:
Updated velocity
[vx, vy], clipped tovmax.- 返回类型:
list[float]
- desired_force() list[源代码]#
Relaxation toward the desired velocity
v0 * e_goal.The desired velocity is supplied directly via
state[5:7].
- social_force() list[源代码]#
Anisotropic neighbor repulsion (Moussaid-Helbing 2009).
Iterates over all neighbors within
neighbor_rangeand sums their contribution.
- obstacle_force() list[源代码]#
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_obstaclecontributes an exponentially decayed push, so symmetric walls cancel and the agent walks the centreline. The integration is also clamped against overlap (distance < 0would otherwise makeexp(-distance/sigma)explode).