Skip to main content

physics.robotics.perception

physics.robotics.perception

Spatial memory footprints, evidence horizons, and teleoperation data budgets.

Functions

Name Description
calc_3dgs_memory_footprint Count Gaussian-state storage under an explicit packing.
calc_free_space_expiry Compute a free-space claim’s erosion horizon.
calc_linear_invalidation_horizon Find the first passage of a linearly growing error allowance.
calc_octree_depth Count halvings from a map edge to a target voxel edge.
calc_spatial_information_age_displacement Compute displacement during a perception delay.
calc_sphere_scan_cells Estimate voxel reads from a spherical query volume.
calc_target_evidence_horizon Find when constant target drift consumes an error margin.
calc_teleop_ingestion_budget Count uncompressed teleoperation traffic and hourly storage.
calc_tracked_evidence_horizon Find when residual acceleration consumes a tracked error margin.
calc_tsdf_voxel_grid_budget Estimate TSDF payload storage and assumed traversal traffic.
calc_voxel_quantization_error Compute the maximum center-representation error of a cubic voxel.

calc_3dgs_memory_footprint

physics.robotics.perception.calc_3dgs_memory_footprint(
    num_gaussians,
    bytes_per_gaussian=56,
)

Count Gaussian-state storage under an explicit packing.

Parameters

Name Type Description Default
num_gaussians int Positive count of Gaussian state records. required
bytes_per_gaussian int Positive bytes per record; default 56 is an assumed packing, not a universal 3DGS layout. 56

Returns

Name Type Description
Quantity Packed state storage in bytes.

Notes

Equation: memory = num_gaussians * bytes_per_gaussian.

Assumptions: Each record uses the same caller-specified packing.

Excludes: Optimizer state, allocator overhead, renderer workspaces, and additional harmonic coefficients.

Equation: Memory = K_gaussians * bytes_per_gaussian

References

Derivation: Count records and multiply by storage per record; the packing is an input convention.

Examples

>>> from mlsysim.physics.robotics.perception import calc_3dgs_memory_footprint
>>> from mlsysim.core.units import ureg
>>> small = calc_3dgs_memory_footprint(10)
>>> large = calc_3dgs_memory_footprint(20)
>>> assert large == 2 * small

calc_free_space_expiry

physics.robotics.perception.calc_free_space_expiry(
    free_depth,
    loc_bound,
    protective_clearance,
    approach_speed,
)

Compute a free-space claim’s erosion horizon.

Parameters

Name Type Description Default
free_depth Quantity Observed free depth in length units. required
loc_bound Quantity Nonnegative localization allowance in length units. required
protective_clearance Quantity Nonnegative clearance reserved before an approaching object reaches the task region. required
approach_speed Quantity Positive assumed approach speed in length / time; supplied by the caller. required

Returns

Name Type Description
Quantity Expiry time in milliseconds, floored at zero.

Notes

Equation: expiry = max(free_depth - loc_bound - protective_clearance, 0) / approach_speed.

Assumptions: An unseen object enters from the free-space boundary at a bounded constant speed.

Excludes: Occlusion geometry beyond a scalar depth, braking, speed-bound validation, and standards compliance.

Equation: T_inv = max(0, (d_free - delta_loc - delta_margin) / v_h)

The free region erodes from its unobserved boundary at the approach speed v_h; localization error delta_loc and the protective clearance delta_margin are spent up front. It is calc_linear_invalidation_horizon with E_0 = delta_loc, r = v_h, and E_max = d_free - delta_margin.

Source: linear invalidation horizon applied to occluded free space; the walking-speed bound v_h is ISO 13855’s K (1.6 m/s).

References

Derivation: Apply the linear invalidation horizon with initial_error = loc_bound and error_limit = free_depth - protective_clearance.

Examples

>>> from mlsysim.physics.robotics.perception import calc_free_space_expiry
>>> from mlsysim.core.units import ureg
>>> h = calc_free_space_expiry(3 * ureg.meter, 1 * ureg.meter, 1 * ureg.meter, 1 * ureg.meter / ureg.second)
>>> assert h == 1 * ureg.second

calc_linear_invalidation_horizon

physics.robotics.perception.calc_linear_invalidation_horizon(
    initial_error,
    error_growth_rate,
    error_limit,
)

Find the first passage of a linearly growing error allowance.

Parameters

Name Type Description Default
initial_error Quantity Initial error allowance in length units. required
error_growth_rate Quantity Positive error-growth rate in length / time. required
error_limit Quantity Allowed error in length units; a spent limit returns zero. required

Returns

Name Type Description
Quantity Invalidation horizon in milliseconds, floored at zero.

Notes

Equation: horizon = max(error_limit - initial_error, 0) / error_growth_rate.

Assumptions: Monotone constant-rate growth of a scalar error allowance.

Excludes: Acceleration, new evidence, stopping capability, and confidence calibration.

Equation: E(dt) = E_0 + r * dt ; T_inv = max(0, (E_max - E_0) / r)

A zero result means the belief never supported the task: its initial error already consumes the tolerance. Unlike calc_target_evidence_horizon this does not raise when E_0 >= E_max; it floors the deadline at zero.

Source: first-passage time of a linear error bound (definition of the invalidation horizon, T_inv = inf{dt >= 0 : E(dt) >= E_max}); the reachable-set lineage for occluded free space is Orzechowski, Meyer, and Lauer 2018 (IEEE ITSC).

References

Derivation: Set a linear error envelope equal to the limit; clamp past crossings to time zero.

Examples

>>> from mlsysim.physics.robotics.perception import calc_linear_invalidation_horizon
>>> from mlsysim.core.units import ureg
>>> h = calc_linear_invalidation_horizon(2 * ureg.meter, 1 * ureg.meter / ureg.second, 1 * ureg.meter)
>>> assert h.magnitude == 0

calc_octree_depth

physics.robotics.perception.calc_octree_depth(map_edge, pitch)

Count halvings from a map edge to a target voxel edge.

Parameters

Name Type Description Default
map_edge Quantity Positive cubic map edge; the intended hierarchy has map_edge >= pitch. required
pitch Quantity Positive target leaf edge in the same length dimension. required

Returns

Name Type Description
int Ceiling of the base-two edge ratio; can be negative for out-of-regime pitch > map_edge.

Notes

Equation: depth = ceil(log2(map_edge / pitch)).

Assumptions: Each level halves an edge and a query descends the full hierarchy.

Excludes: Allocation sparsity, early termination, memory latency, and automatic clamping of out-of-regime input.

Equation: depth = ceil(log2(L / r))

Each level is one dependent read in a point query.

Source: Hornung et al., “OctoMap,” Autonomous Robots 34(3), 2013, Sec. III.

References

Derivation: After d binary subdivisions the edge is map_edge/2**d; choose the least integer d attaining pitch.

Examples

>>> from mlsysim.physics.robotics.perception import calc_octree_depth
>>> from mlsysim.core.units import ureg
>>> assert calc_octree_depth(8 * ureg.meter, 1 * ureg.meter) == 3

calc_spatial_information_age_displacement

physics.robotics.perception.calc_spatial_information_age_displacement(
    velocity,
    information_age,
)

Compute displacement during a perception delay.

Parameters

Name Type Description Default
velocity Quantity Nonnegative constant translational speed in length / time. required
information_age Quantity Positive sensor-to-use age in time units. required

Returns

Name Type Description
Quantity Displacement in meters.

Notes

Equation: displacement = velocity * information_age.

Assumptions: The supplied speed remains constant over the age interval.

Excludes: Acceleration, object motion not included in velocity, and collision assessment.

Equation: Delta_x = v * tau_age

Source: OpenStax, University Physics Volume 1, Sec. 3.1. Physical AI perception pipeline waterfall (exposure, readout, transport, DMA, ISP, backbone, IPC).

References

Derivation: Integrate constant velocity over the elapsed perception age.

Examples

>>> from mlsysim.physics.robotics.perception import calc_spatial_information_age_displacement
>>> from mlsysim.core.units import ureg
>>> distance = calc_spatial_information_age_displacement(1 * ureg.meter / ureg.second, 1 * ureg.second)
>>> assert distance == 1 * ureg.meter

calc_sphere_scan_cells

physics.robotics.perception.calc_sphere_scan_cells(reach, pitch)

Estimate voxel reads from a spherical query volume.

Parameters

Name Type Description Default
reach Quantity Positive sphere radius including any clearance allowance. required
pitch Quantity Positive cubic voxel edge length. required

Returns

Name Type Description
float Dimensionless continuum estimate of cells, not an integer enumeration.

Notes

Equation: cells = (4*pi/3) * (reach / pitch)**3.

Assumptions: A dense read of every voxel within the spherical volume.

Excludes: Boundary-cell rounding, early exits, spatial indexes, and clearance certification.

Equation: N = (4/3) pi (reach / r)^3

reach is the sphere radius plus the protective clearance; every cell within it must be read, because an occupancy cell answers only whether that one cell is occupied.

Source: volume of a sphere in units of the voxel volume r^3.

References

Derivation: Divide sphere volume by cubic voxel volume.

Examples

>>> from mlsysim.physics.robotics.perception import calc_sphere_scan_cells
>>> from mlsysim.core.units import ureg
>>> small = calc_sphere_scan_cells(1 * ureg.meter, 0.1 * ureg.meter)
>>> large = calc_sphere_scan_cells(2 * ureg.meter, 0.1 * ureg.meter)
>>> assert large == 8 * small

calc_target_evidence_horizon

physics.robotics.perception.calc_target_evidence_horizon(
    tolerance_radius,
    sensor_noise,
    drift_velocity,
)

Find when constant target drift consumes an error margin.

Parameters

Name Type Description Default
tolerance_radius Quantity Positive spatial tolerance in length units. required
sensor_noise Quantity Positive initial error allowance below tolerance_radius; a quantile is not a hard bound. required
drift_velocity Quantity Positive drift-speed allowance in length / time. required

Returns

Name Type Description
Quantity Target-evidence validity horizon in milliseconds.

Notes

Equation: horizon = (tolerance_radius - sensor_noise) / drift_velocity.

Assumptions: An initial scalar error plus constant bounded drift; interpretation follows the supplied allowances.

Excludes: Braking, fallback feasibility, clearance checks, and safety certification.

This is not a stopping-time or stopping-distance bound. Motion admission also needs current clearance, total pre-brake delay, achievable deceleration, and a feasible fallback after this evidence expires.

Equation: tau = (r_tol - e_0) / v_drift

References

Derivation: Solve initial error + drift*time = tolerance for time.

Examples

>>> from mlsysim.physics.robotics.perception import calc_target_evidence_horizon
>>> from mlsysim.core.units import ureg
>>> h = calc_target_evidence_horizon(2 * ureg.meter, 1 * ureg.meter, 1 * ureg.meter / ureg.second)
>>> assert h == 1 * ureg.second

calc_teleop_ingestion_budget

physics.robotics.perception.calc_teleop_ingestion_budget(
    num_cameras,
    rgb_width,
    rgb_height,
    rgb_fps,
    rgb_bytes_per_pixel=3,
    depth_width=0,
    depth_height=0,
    depth_fps=0.0,
    depth_bytes_per_pixel=2,
    kinematics_bytes_per_sec=None,
    tactile_bytes_per_sec=None,
)

Count uncompressed teleoperation traffic and hourly storage.

Parameters

Name Type Description Default
num_cameras int Positive count of identical camera streams. required
rgb_width int Positive RGB image width in pixels. required
rgb_height int Positive RGB image height in pixels. required
rgb_fps float Positive RGB frame frequency in frames per second. required
rgb_bytes_per_pixel int Positive RGB bytes per pixel; default 3. 3
depth_width int Depth width in pixels; default zero disables depth. 0
depth_height int Depth height in pixels; default zero disables depth. 0
depth_fps float Depth frames per second; depth is enabled only when width, height, and frequency are positive. 0.0
depth_bytes_per_pixel int Positive depth bytes per pixel; default 2. 2
kinematics_bytes_per_sec Quantity Nonnegative kinematics bandwidth in bytes / time; None means zero. None
tactile_bytes_per_sec Quantity Nonnegative tactile bandwidth in bytes / time; None means zero. None

Returns

Name Type Description
dict RGB, depth, vision, kinematics, tactile, and total bandwidth in MB/s; storage_per_hour in TB.

Notes

Equation: camera bandwidth = cameras*width*height*bytes_per_pixel*fps; total = RGB + depth + kinematics + tactile; hourly storage = total*3600 seconds.

Assumptions: Identical continuous camera streams and uncompressed fixed-size payloads.

Excludes: Compression, transport headers, indexes, replication, and storage write amplification.

Equation: BW_rgb = num_cameras * (W_rgb * H_rgb * Bpp_rgb) * FPS_rgb BW_depth = num_cameras * (W_depth * H_depth * Bpp_depth) * FPS_depth BW_kinematics = bytes_per_sec_kinematics BW_tactile = bytes_per_sec_tactile BW_total = BW_rgb + BW_depth + BW_kinematics + BW_tactile Storage_1hr = BW_total * 3600 s

References

Derivation: Multiply pixels per frame by bytes per pixel and frames per second, sum independent streams, and integrate over one hour.

Examples

>>> from mlsysim.physics.robotics.perception import calc_teleop_ingestion_budget
>>> from mlsysim.core.units import ureg
>>> budget = calc_teleop_ingestion_budget(1, 10, 10, 1)
>>> assert budget["bw_depth"].magnitude == 0
>>> assert budget["storage_per_hour"] == (budget["bw_total"] * ureg.hour).to("terabyte")

calc_tracked_evidence_horizon

physics.robotics.perception.calc_tracked_evidence_horizon(
    tolerance_radius,
    initial_error,
    slip_acceleration,
)

Find when residual acceleration consumes a tracked error margin.

Parameters

Name Type Description Default
tolerance_radius Quantity Positive spatial tolerance in length units. required
initial_error Quantity Nonnegative initial error below tolerance_radius. required
slip_acceleration Quantity Positive residual relative acceleration in length / time**2. required

Returns

Name Type Description
Quantity Tracked-evidence horizon in milliseconds.

Notes

Equation: horizon = sqrt(2*(tolerance_radius - initial_error)/slip_acceleration).

Assumptions: Tracking removes initial relative velocity; residual acceleration is bounded by the input.

Excludes: Velocity-estimation error, braking, and proof of an acceleration bound.

A tracker that follows a moving target removes its steady velocity, so the remaining error growth comes from a bounded residual acceleration a_slip. A segment executed open-loop for a time T then drifts by a_slip T^2 / 2; setting that drift equal to the error margin r_tol - e_0 gives

Equation: tau_ev = sqrt(2 (r_tol - e_0) / a_slip)

This is the constant-acceleration counterpart of calc_target_evidence_horizon (constant drift velocity, a_slip = 0). Like that function it is not a stopping-time bound.

Source: first-passage time of a constant-acceleration displacement (d = a T^2 / 2, solved for T at d = r_tol - e_0); kinematics, derived here.

References

Derivation: Integrate constant acceleration from zero residual velocity, then solve displacement = remaining margin.

Examples

>>> from mlsysim.physics.robotics.perception import calc_tracked_evidence_horizon
>>> from mlsysim.core.units import ureg
>>> h = calc_tracked_evidence_horizon(2 * ureg.meter, 0 * ureg.meter, 1 * ureg.meter / ureg.second**2)
>>> assert h == 2 * ureg.second

calc_tsdf_voxel_grid_budget

physics.robotics.perception.calc_tsdf_voxel_grid_budget(
    workspace_volume,
    voxel_size,
    bytes_per_voxel=4,
    sparsity_ratio=0.03,
    block_size_voxels=512,
    block_header_bytes=32,
    ray_rate=None,
    dense_voxels_per_ray=300,
    sparse_voxels_per_ray=6,
    free_voxels_per_ray=294,
    bytes_per_ray_voxel=8,
    cache_hit_rate=0.95,
)

Estimate TSDF payload storage and assumed traversal traffic.

Parameters

Name Type Description Default
workspace_volume Quantity Positive workspace bounding volume, convertible to cubic meters. required
voxel_size Quantity Positive isotropic voxel edge length. required
bytes_per_voxel int Positive payload bytes per voxel; default 4 stores distance and fusion weight. 4
sparsity_ratio float Active voxel fraction in [0, 1]; default 0.03 is an assumed scenario. 0.03
block_size_voxels int Positive voxel capacity per allocated leaf block; default 512. 512
block_header_bytes int Nonnegative metadata bytes per block; default 32. 32
ray_rate Quantity or float Nonnegative integration rays per second; None omits bandwidth outputs. None
dense_voxels_per_ray int Nonnegative dense lookups per ray; default 300. 300
sparse_voxels_per_ray int Nonnegative TSDF-band updates per ray; default 6. 6
free_voxels_per_ray int Nonnegative free-space occupancy updates per ray; default 294. 294
bytes_per_ray_voxel int Nonnegative read/write bytes per lookup; default 8. 8
cache_hit_rate float Assumed cache-hit fraction in [0, 1]; default 0.95, not an inherent sparse-map property. 0.95

Returns

Name Type Description
dict Integer voxel/block counts, dense_memory in GB, sparse_memory in MB; optional dense_dram_bandwidth in GB/s and sparse_dram_bandwidth in MB/s.

Notes

Equation: N = round(V / pitch**3); A = round(N*sparsity); blocks = ceil(A / block_size); sparse bytes = blocks*(block_size*voxel_bytes + header); traffic = ray_rate*lookups*lookup_bytes, discounted by sparse cache misses.

Assumptions: Fixed voxel packing, rounded voxel counts, full leaf allocation, and caller-specified traversal/cache behavior.

Excludes: Complete occupancy-state storage, evidence epochs, allocator/index metadata, cache capacity analysis, and measured traffic prediction.

The four-byte voxel stores distance and fusion weight only. The sparse result includes the stipulated leaf header, but neither result includes a separate occupancy layer, per-cell evidence epochs, lookup/allocator metadata, or other full-map state. The hit rate is an assumed workload input, not a property of sparse allocation.

Equation: N_dense = V_workspace / (Delta_v)^3 M_dense = N_dense * B_voxel N_active = N_dense * S_sparsity N_blocks = ceil(N_active / B_block) M_sparse = N_blocks * (B_block * B_voxel + B_header) BW_dense_dram = R_rays * N_dense_lookups * B_lookup BW_sparse_dram = R_rays * (N_free_occupancy + N_TSDF_band) * B_lookup * (1 - Hit_cache)

References

Derivation: Count a regular grid, round active occupancy, allocate whole blocks, and sum per-ray memory transactions; this is explicit byte accounting, not a claim about a particular mapper.

Examples

>>> from mlsysim.physics.robotics.perception import calc_tsdf_voxel_grid_budget
>>> from mlsysim.core.units import ureg
>>> budget = calc_tsdf_voxel_grid_budget(1 * ureg.meter**3, 0.1 * ureg.meter)
>>> assert budget["dense_voxel_count"] == 1000
>>> assert budget["sparse_block_count"] == 1

calc_voxel_quantization_error

physics.robotics.perception.calc_voxel_quantization_error(pitch)

Compute the maximum center-representation error of a cubic voxel.

Parameters

Name Type Description Default
pitch Quantity Positive cubic voxel edge length. required

Returns

Name Type Description
Quantity Half the voxel diagonal in millimeters.

Notes

Equation: error = sqrt(3) * pitch / 2.

Assumptions: A point anywhere in a cubic voxel is represented by its center.

Excludes: Sensor error, map registration error, and noncubic cells.

Equation: e_q = (sqrt(3) / 2) r

Source: geometry of a cube of edge r.

References

Derivation: Apply the three-dimensional Pythagorean theorem to a corner-to-center offset.

Examples

>>> from mlsysim.physics.robotics.perception import calc_voxel_quantization_error
>>> from mlsysim.core.units import ureg
>>> a = calc_voxel_quantization_error(1 * ureg.millimeter)
>>> b = calc_voxel_quantization_error(2 * ureg.millimeter)
>>> assert b == 2 * a
Back to top