Flickzlab

Ray casting Algorithm

Over the weekend, I was working on my robotics localization coursework and needed a 2D map of the simulated environment in which the robot would be moving. Localization algorithms require a map of the environment to estimate where the robot might be. So, how do you generate a 2D map showing free and occupied spaces from a 3D environment? The answer: the Ray Casting Algorithm!

It is a collision detection algorithm.

30e0ef6f0a39474899df45b23c7cd9f9

The ray casting algorithm is likely familiar to those in game development or 3D software design. It allows you to map out free and occupied spaces:

Robots navigating on a 2D plane typically rely on free spaces for safe movement.

How Does It Work?

Imagine a square-shaped space containing 3D objects or collision geometries. You divide this space into a grid, with the number of cells determined by a resolution value. After dividing the space, you cast imaginary rays into the environment from specific points within each grid cell.

For a typical 2D map:

The physics engine handles the complex computations:

Constructing the 2D Image

The results of the ray casting algorithm are then used to construct a 2D image. Each grid cell corresponds to a pixel in the image:

Implementation

Initialize a 2D grid of size (rows, columns)
Set grid resolution and ray casting parameters:
    resolution = <cell size>
    ray_max_range = <maximum ray length>
    ray_direction = [0, 0, -1]  # Downward direction in 3D space

For each grid cell (i, j):
    Calculate the ray's origin:
        x = cell_center_x(i)
        y = cell_center_y(j)
        z = ray_starting_height
        origin = [x, y, z]

    Calculate the ray's end point:
        end = origin + (ray_direction * ray_max_range)

    Pass the ray parameters to the physics engine:
        intersection = physics_engine.cast_ray(origin, end)

    If intersection is detected:
        grid[i][j] = 1  # Mark cell as occupied
    Else:
        grid[i][j] = 0  # Mark cell as free

Generate the 2D image:
    For each grid cell:
        If grid[i][j] == 1:
            Set pixel (i, j) to black (RGB: [0, 0, 0])
        Else:
            Set pixel (i, j) to white (RGB: [255, 255, 255])
Save the image

For full code implementation: https://github.com/udacity/pgm_map_creator/blob/master/src/collision_map_creator.cc#L45-L138

#algorithm #robotics