360° LiDAR Rangefinder Digital Twin
The 360° LiDAR Rangefinder Digital Twin (VectorizedLiDAR) provides high-speed, GPU-accelerated ray-marching simulations for multi-rotor UAV obstacle detection and collision avoidance in 3D urban topographies.
Overview & Sensor Geometry
Autonomous UAV navigation in complex urban canyons requires real-time sensing of building facades and vertical structures. The VectorizedLiDAR digital twin equips each UAV with a horizontal radial array of rangefinding beams spanning a full \(360^\circ\) azimuth.
where \(K\) is the number of azimuth beams (typically 8, 16, or 32).
Ray-Marching Over ITU-R P.1410 3D Heightmaps
Unlike mesh-based ray-tracing which is computationally intensive on CPU, VectorizedLiDAR implements a tensorized ray-marching algorithm directly against VectorizedUrbanMap 2.5D/3D building elevation matrices:
Radial Sample Points: For each beam \(k\) extending from UAV position \((x_i, y_i, z_i)\), sample coordinates are evaluated at \(S\) discrete radial step fractions:
Heightmap Collision Condition: Obstacle intersection occurs whenever the UAV altitude \(z_i\) falls at or below the local building height:
Range Normalization: The normalized distance reading \(d_k \in [0.0, 1.0]\) is determined by the nearest hit distance:
If no building is intersected within maximum range \(d_{\max}\), \(d_k = 1.0\) (unobstructed clearance).
Sensor Configuration Parameters
Parameter |
Description |
Default |
Unit |
|---|---|---|---|
num_beams |
Number of radial azimuth beams |
8 |
integer |
max_range |
Maximum sensor detection range |
60.0 |
meters |
n_steps |
Ray-marching discretization intervals |
15 |
integer |
device |
PyTorch execution device (CPU / CUDA) |
cpu |
device |
Observation Space Integration
In the uav_lidar_navigation scenario and POMDP control architectures, the LiDAR vector \(\mathbf{d}_i \in \mathbb{R}^K\) is directly concatenated into the decentralized observation vector:
This provides reinforcement learning agents with local geometric awareness without requiring centralized global heightmap knowledge.
Python Usage Example
import torch
from urbanmarl.models.urban_map import VectorizedUrbanMap
from urbanmarl.models.lidar import VectorizedLiDAR
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# 1. Create procedural 3D urban terrain
urban_map = VectorizedUrbanMap(
batch_size=32,
volume_size=(500, 500, 50),
device=device,
)
# 2. Initialize 8-beam LiDAR sensor with 60m maximum range
lidar = VectorizedLiDAR(
num_beams=8,
max_range=60.0,
n_steps=15,
device=device,
)
# 3. UAV coordinates: shape (batch_size=32, num_uavs=5, 3)
uav_pos = torch.zeros(32, 5, 3, device=device)
uav_pos[..., 2] = 25.0 # flying at altitude 25m
# 4. Perform parallel ray-marching scans
# Output shape: (32, 5, 8) with values in [0.0, 1.0]
lidar_readings = lidar.scan(uav_pos, urban_map)
print(f"LiDAR scan tensor shape: {lidar_readings.shape}")
print(f"UAV 0 Beam Clearances: {lidar_readings[0, 0].cpu().numpy()}")