Skip to content

OccupancyGrid ​

SUMMARY

A grid representing occupancy in a 2D environment.

python
import numpy as np
from telekinesis import datatypes
grid = datatypes.OccupancyGrid(np.zeros((1, 1), dtype=np.int8), resolution=1.0)
API Reference
Complete API documentation for OccupancyGrid, including parameters, attributes, and methods.
View Reference →

Parameters ​

ParameterTypeDefaultDescription
datanp.ndarrayRequired(H, W) int8 array of cell values (FREE, OCCUPIED, or UNKNOWN). A contiguous input array is stored by reference, not copied — pass arr.copy() explicitly if the source array may be mutated afterward.
resolutionfloatRequiredMeters per cell.
origin_xfloat0.0World x-coordinate of cell (0, 0)'s lower-left corner.
origin_yfloat0.0World y-coordinate of cell (0, 0)'s lower-left corner.
origin_yawfloat0.0Rotation of the grid relative to world axes, in radians. ROS represents this as a quaternion on info.origin.orientation; here it's stored as a plain yaw float instead.

Raises ​

ExceptionCondition
TypeErrordata is not an np.ndarray
ValueErrordata.dtype is not int8
ValueErrordata is not 2-D
ValueErrordata contains a value outside {UNKNOWN} ∪ [FREE, OCCUPIED] (i.e. outside {-1} ∪ [0, 100])

Constants ​

ConstantValueDescription
FREE0Cell is known to be unoccupied.
OCCUPIED100Cell is known to be occupied.
UNKNOWN-1Cell occupancy is unknown.

These are class-level constants, accessible as OccupancyGrid.FREE (or off any instance) without constructing a grid.

Attributes ​

AttributeTypeDescription
datanp.ndarrayDefensive copy of the underlying (H, W) int8 grid. Mutating the returned array does not affect the OccupancyGrid.
shapetuple[int, int](height, width) cell counts.
heightintGrid height in cells (shape[0]).
widthintGrid width in cells (shape[1]).
resolutionfloatMeters per cell.
origin_xfloatWorld x-coordinate of cell (0, 0)'s lower-left corner.
origin_yfloatWorld y-coordinate of cell (0, 0)'s lower-left corner.
origin_yawfloatGrid's rotation relative to world axes, in radians.

None of these attributes have setters — an OccupancyGrid is immutable after construction (unless you mutate the array you originally passed in, since it's stored by reference rather than copied).

Methods ​

MethodTypeDescription
OccupancyGrid.coerce(value)OccupancyGridConverts a dict of grid fields into an OccupancyGrid. Accepts a dict with data and resolution keys; origin_x, origin_y, and origin_yaw are optional. If value is already an OccupancyGrid, it is returned unchanged.

Operators ​

OperationBehavior
g == otherCompare grid values and metadata with another OccupancyGrid value.
np.asarray(g)Convert grid values to a NumPy array with np.asarray(g).

Visualization ​

python
import rerun as rr

# Your code block
# ....

rr.init("occupancy_grid_example", spawn=True)
datatypes.visualize(grid, entity_path="/grid", label="OccupancyGrid")

Example ​

python
"""Demonstrates the Telekinesis OccupancyGrid datatype."""

import time

import numpy as np
import rerun as rr
from loguru import logger

from telekinesis import datatypes

def occupancy_grid_example():
    """Demonstrate creation, inspection, operations, visualization, and serialization."""

    # ======================= Create ============================================
    height, width = 20, 20

    data = np.full((height, width), datatypes.OccupancyGrid.UNKNOWN, dtype=np.int8)
    data[10, 5] = datatypes.OccupancyGrid.OCCUPIED
    data[10, 6] = datatypes.OccupancyGrid.FREE
    data[10, 7] = datatypes.OccupancyGrid.OCCUPIED

    grid = datatypes.OccupancyGrid(
        data, resolution=0.05, origin_x=-5.0, origin_y=-5.0, origin_yaw=0.0
    )
    logger.info(f"Created OccupancyGrid: {grid}")

    # ======================= Inspect ===========================================
    logger.info(f"data=\n{grid.data}")
    logger.info(f"shape={grid.shape}")
    logger.info(f"height={grid.height}")
    logger.info(f"width={grid.width}")
    logger.info(f"resolution={grid.resolution} m/cell")
    logger.info(f"origin_x={grid.origin_x}")
    logger.info(f"origin_y={grid.origin_y}")
    logger.info(f"origin_yaw={grid.origin_yaw}")
    logger.info(f"FREE={datatypes.OccupancyGrid.FREE}")
    logger.info(f"OCCUPIED={datatypes.OccupancyGrid.OCCUPIED}")
    logger.info(f"UNKNOWN={datatypes.OccupancyGrid.UNKNOWN}")

    # ======================= Operations =========================================
    occupied = int(np.sum(grid.data == datatypes.OccupancyGrid.OCCUPIED))
    free = int(np.sum(grid.data == datatypes.OccupancyGrid.FREE))
    unknown = int(np.sum(grid.data == datatypes.OccupancyGrid.UNKNOWN))
    logger.info(f"occupied={occupied}, free={free}, unknown={unknown}")

    numpy_array = np.asarray(grid)
    logger.info(f"NumPy array via __array__: shape={numpy_array.shape}, dtype={numpy_array.dtype}")

    logger.info(f"grid == grid: {grid == grid}")

    # ======================= Visualize =========================================
    rr.init("occupancy_grid_example", spawn=True)
    datatypes.visualize(grid, entity_path="/occupancy_grid", label="Occupancy Grid")

    # ======================= Serialize / Deserialize ===========================
    start = time.perf_counter()
    serialized = datatypes.serialize(grid)
    serialization_ms = (time.perf_counter() - start) * 1000

    start = time.perf_counter()
    deserialized = datatypes.deserialize(serialized)["param_0"]
    deserialization_ms = (time.perf_counter() - start) * 1000

    logger.info(f"Deserialized OccupancyGrid: {deserialized}")
    logger.info(f"Round-trip successful: {grid == deserialized}")
    logger.info(f"Serialization time: {serialization_ms:.3f} ms")
    logger.info(f"Deserialization time: {deserialization_ms:.3f} ms")


if __name__ == "__main__":
    occupancy_grid_example()