In [1]:
import radarsimpy
radarsimpy.__version__
Out[1]:
'10.0.1'

Lidar Point Cloud (Experimental)¶

RadarSimPy is a radar simulation package built with python. Contact me if you are interested in this module.

RadarSimC is the ray tracing engine built with C++. It is capabile of generating the point cloud of a customized scene. This engine is integrated in RadarSimPy.

This ray tracing engine can be used to effective calculation the RCS of a target. It can also be used generate point cloud in a customized scene.

This notebook is available on my GitHub.

Create a Scene¶

A scene can be created from multiple .stl models.

In this example, 5 objects will be loaded:

  • ground: a 60 m x 60 m plane used as the ground
  • car_1: an Audi R8 model at (0, 10, 0) m
  • car_2: an Audi R8 model at (-4, 0, 0) m
  • car_3: an Audi R8 model at (4, -5, 0) m
  • car_4: an Audi R8 model at (0, -5, 0) m
In [2]:
import numpy as np

car3_speed = 2  # m/s
car3_yaw = 30  # deg/s

ground = {
    'model': '../models/surface_60x60.stl',
}

car_1 = {
    'model': '../models/vehicles/ford_raptor.stl',
    'location': [-8, 0, 0],
    'rotation': [0, 0, 0],
}

car_2 = {
    'model': '../models/vehicles/lamborgini_aventador.stl',
    'location': [-12, -4, 0],
    'rotation': [0, 0, 0],
    'rotation_rate': [0, 0, 0],
    'speed': [5, 0, 0]
}

car_3 = {
    'model': '../models/vehicles/tesla_model_s.stl',
    'location': [5, 4, 0],
    'rotation': [0, 0, 0]
}

car_4 = {
    'model': '../models/vehicles/scania_truck.stl',
    'location': [-15, 4, 0],
    'rotation': [0, 0, 0],
    'rotation_rate': [0, 0, 0],
    'speed': [2, 0, 0]
}

targets = [ground, car_1, car_2, car_3, car_4]

Lidar¶

Now, use dict to define a Lidar. It has 3 properties:

  • position: position of the Lidar
  • phi: horzontal scanning angles in degree
  • theta: vertical scanning angles in degree
In [3]:
lidar = {
    'position': [0, 0, 1.5],
    'phi': np.arange(0, 360, 1),
    'theta': np.arange(70, 110, 1)
}

To generate the point cloud, we can simply use lidar_scene. It will create an numpy array of the point cloud.

In [4]:
import time
from radarsimpy.rt import lidar_scene

delta_t = 0.25
time_seq = np.arange(0, 3, delta_t)
points = []

tic = time.time()
for t in time_seq:
    points.append(lidar_scene(lidar, targets, t=t))

    targets[3]['rotation'][0] += car3_yaw*delta_t
    #     targets[3]['rotation'][1] += car3_yaw*delta_t
    targets[3]['location'][0] += car3_speed * \
        np.cos(targets[3]['rotation'][0]/180*np.pi)*delta_t
    targets[3]['location'][1] += car3_speed * \
        np.sin(targets[3]['rotation'][0]/180*np.pi)*delta_t

toc = time.time()
print('Exection time:', toc-tic, 's')
Exection time: 33.35826563835144 s

Plot the Point Cloud¶

In [5]:
import plotly.graph_objs as go
from plotly.offline import iplot

ani_frames = []
frame_list = time_seq

for t_idx in range(0, len(time_seq)):
    ani_frames.append(
        dict(data=[dict(type='scatter3d',
                        x=points[t_idx]['positions'][:, 0],
                        y=points[t_idx]['positions'][:, 1],
                        z=points[t_idx]['positions'][:, 2],
                        mode='markers',
                        marker=dict(
                            size=1,
                            color=points[t_idx]['positions'][:, 2],
                            colorscale='Rainbow',
                            opacity=1,
                        ),)],
             name=str(t_idx))
    )

sliders = [
    {
        "pad": {"b": 10, "t": 40},
        "len": 0.9,
        "x": 0.1,
        "y": 0,
        "steps": [
            {
                "args": [[f['name']], {
                    "frame": {"duration": 0},
                    "mode": "immediate",
                    "fromcurrent": True,
                    "transition": {"duration": 0, "easing": "quadratic-in-out"},
                }],
                "label": str(k),
                "method": "animate",
            }
            for k, f in enumerate(ani_frames)
        ],
    }
]

figure_layout = go.Layout(
    height=600,
    template='plotly_dark',
    scene=dict(
        aspectmode='data',
    ),
    margin=dict(l=0, r=0, b=0, t=20)
)

figure_layout['updatemenus'] = [
    {
        'bgcolor': '#9E9E9E',
        'font': {'size': 10, 'color': '#455A64'},
        "buttons": [
            {
                "args": [None, {
                    "frame": {"duration": 10},
                    "mode": "immediate",
                    "fromcurrent": True,
                    "transition": {"duration": 10, "easing": "quadratic-in-out"},
                }],
                "label": "▶",  # play symbol
                "method": "animate",
            },
            {
                "args": [[None], {
                    "frame": {"duration": 0},
                    "mode": "immediate",
                    "fromcurrent": True,
                    "transition": {"duration": 0, "easing": "quadratic-in-out"},
                }],
                "label": "⏸",  # pause symbol
                "method": "animate",
            },
        ],
        "direction": "left",
        "pad": {"r": 10, "t": 50, "l": 20},
        "type": "buttons",
        "x": 0.1,
        "xanchor": "right",
        "y": 0,
        "yanchor": "top"
    }
]

figure_layout['sliders'] = sliders

iplot(dict(data=[ani_frames[0]['data'][0]],
           frames=ani_frames,
           layout=figure_layout))
In [ ]: