robometric_frame.safety.collision_rate
Collision Rate metric for robotics policy safety evaluation.
Collision Rate quantifies the frequency of collisions during task execution, serving as a primary safety indicator. This metric is particularly critical for mobile robots and humanoids operating in human environments where safety is paramount.
- Reference:
M. Hoy, A. S. Matveev, and A. V. Savkin, “Algorithms for collision-free navigation of mobile robots in complex cluttered environments: a survey,” Robotica, vol. 33, pp. 463–497, Mar. 2015.
Classes
|
Compute Collision Rate for robotics policy safety evaluation. |
- class robometric_frame.safety.collision_rate.CollisionRate(distance_fn, collision_threshold=0.0, **kwargs)[source]
Compute Collision Rate for robotics policy safety evaluation.
Collision Rate is calculated as:
\[\text{CR} = \frac{N_{\text{collisions}}}{T_{\text{steps}}}\]where \(N_{\text{collisions}}\) is the total number of collision occurrences and \(T_{\text{steps}}\) is the total number of trajectory steps.
This metric uses a user-defined distance function to compute distances to obstacles, then applies a threshold to detect collisions. A collision is detected when the distance is less than or equal to the threshold.
- Parameters:
distance_fn (
Callable[[Tensor,Any],Tensor]) –User-defined function that computes distances to obstacles. Signature: distance_fn(trajectory: Tensor, environment: Any) -> Tensor - trajectory: Shape (…, L, D) where L is trajectory length, D is spatial dims - environment: User-defined environment representation (optional) - Returns: Tensor of shape (…, L) with distances to nearest obstacle
at each trajectory point (positive values)
collision_threshold (
float) – Distance threshold for collision detection. Distances less than or equal to this value are considered collisions. Default: 0.0**kwargs (
Any) – Additional keyword arguments passed to the base Metric class.
Example
>>> from robometric_frame.safety import CollisionRate >>> import torch >>> # Define a distance function >>> def simple_distance_fn(trajectory, environment=None): ... # Distance to walls at ±5 ... x_coords = trajectory[..., 0] ... dist_to_walls = torch.minimum( ... torch.abs(x_coords - 5), ... torch.abs(x_coords + 5) ... ) ... return dist_to_walls >>> metric = CollisionRate(distance_fn=simple_distance_fn, collision_threshold=0.5) >>> # Trajectory with some points close to walls >>> trajectory = torch.tensor([[0.0, 0.0], [3.0, 0.0], [4.8, 0.0], [1.0, 0.0]]) >>> metric.update(trajectory) >>> result = metric.compute() >>> result['collision_rate'].item() # One point at distance 0.2 <= 0.5 0.25
- Example (with environment):
>>> # Define distance function with environment obstacles >>> def obstacle_distance_fn(trajectory, environment): ... # environment is a dict with obstacle positions and radii ... min_distances = torch.full(trajectory.shape[:-1], float('inf')) ... for obs_pos, obs_radius in zip(environment['positions'], environment['radii']): ... # Compute distance to obstacle surface ... distances = torch.norm(trajectory - obs_pos, dim=-1) - obs_radius ... min_distances = torch.minimum(min_distances, distances) ... return torch.clamp(min_distances, min=0.0) # Ensure non-negative >>> environment = { ... 'positions': [torch.tensor([2.0, 2.0]), torch.tensor([5.0, 5.0])], ... 'radii': [0.5, 0.5] ... } >>> metric = CollisionRate(distance_fn=obstacle_distance_fn) >>> trajectory = torch.tensor([[0.0, 0.0], [2.0, 2.0], [3.0, 3.0], [4.0, 4.0]]) >>> metric.update(trajectory, environment=environment) >>> result = metric.compute()
- Example (batched):
>>> # Batch of trajectories >>> metric = CollisionRate(distance_fn=simple_distance_fn, collision_threshold=0.5) >>> trajectories = torch.tensor([ ... [[0.0, 0.0], [1.0, 0.0], [2.0, 0.0]], ... [[4.7, 0.0], [4.9, 0.0], [5.0, 0.0]] ... ]) >>> metric.update(trajectories) >>> result = metric.compute()
- __init__(distance_fn, collision_threshold=0.0, **kwargs)[source]
Initialize the CollisionRate metric.
- update(trajectory, environment=None)[source]
Update metric state with trajectory and collision information.
- Parameters:
trajectory (
Tensor) –Trajectory tensor of shape (…, L, D) where: - … represents any number of batch dimensions (can be empty) - L is the number of trajectory points - D is the spatial dimensionality (typically 2 or 3)
Examples of valid shapes: - (L, D): Single trajectory - (B, L, D): Batch of B trajectories - (B, T, L, D): Batch with time/episode dimension
environment (
Optional[Any]) – Optional environment representation passed to distance_fn. Can be any type (dict, object, tensor, etc.) that the user’s distance function expects.
- Raises:
ValueError – If trajectory has invalid shape or distances are negative.
RuntimeError – If distance_fn returns invalid shape or type.
- Return type:
Example
>>> metric = CollisionRate(distance_fn=my_distance_fn) >>> trajectory = torch.randn(10, 2) # 10 points in 2D >>> metric.update(trajectory) >>> # With environment >>> metric.update(trajectory, environment={'obstacles': [...]})
- compute()[source]
Compute collision rate statistics.
- Returns:
‘collision_rate’: Ratio of collision steps to total steps
’total_collisions’: Total number of collision occurrences
’total_steps’: Total number of trajectory steps
’collision_percentage’: Collision rate as percentage (0-100)
- Return type:
Dictionary containing
- Raises:
RuntimeError – If no trajectories have been recorded.
Example
>>> metric = CollisionRate(distance_fn=my_distance_fn) >>> metric.update(trajectory) >>> result = metric.compute() >>> print(f"Collision rate: {result['collision_rate'].item():.2%}") >>> print(f"Total collisions: {result['total_collisions'].item()}")
- training: bool