Main Content

uavLidarPointCloudGenerator

Generate point clouds from meshes

Since R2020b

Description

The uavLidarPointCloudGenerator System object™ generates detections from a statistical simulated lidar sensor. The system object uses a statistical sensor model to simulate lidar detections with added random noise. All detections are with respect to the coordinate frame of the vehicle-mounted sensor. You can use the uavLidarPointCloudGenerator object in a scenario, created using a uavSensor, containing static meshes, UAV platforms, and sensors.

To generate lidar point clouds:

  1. Create the uavLidarPointCloudGenerator object and set its properties.

  2. Call the object with arguments, as if it were a function.

To learn more about how System objects work, see What Are System Objects?

Creation

Description

lidar = uavLidarPointCloudGenerator creates a statistical sensor model to generate point cloud for a lidar. This sensor model will have default properties.

example

lidar = uavLidarPointCloudGenerator(Name,Value) sets properties using one or more name-value pairs. For example, uavLidarPointCloudGenerator('UpdateRate',100,'HasNoise',0) creates a lidar point cloud generator that reports detections at an update rate of 100 Hz without noise.

Properties

expand all

Unless otherwise indicated, properties are nontunable, which means you cannot change their values after calling the object. Objects lock when you call them, and the release function unlocks them.

If a property is tunable, you can change its value at any time.

For more information on changing property values, see System Design in MATLAB Using System Objects.

Update rate of the lidar sensor, specified as a positive real scalar in Hz. This property sets the frequency at which new detections happen.

Example: 20

Data Types: double

Maximum detection range of the sensor, specified as a positive real scalar. The sensor does not detect objects beyond this range. The units are in meters.

Example: 120

Data Types: double

Accuracy of the range measurements, specified as a positive real scalar in meters. This property sets the one-standard-deviation accuracy of the sensor range measurements.

Example: 0.001

Data Types: single | double

Azimuthal resolution of lidar sensor, specified as a positive real scalar in degrees. The azimuthal resolution defines the minimum separation in azimuth angle at which the lidar sensor can distinguish two targets.

Example: 0.6000

Data Types: single | double

Elevation resolution of lidar sensor, specified as a positive real scalar with units in degrees. The elevation resolution defines the minimum separation in elevation angle at which the lidar can distinguish two targets.

Example: 0.6000

Data Types: single | double

Azimuth limits of the lidar, specified as a two-element vector of the form [min max]. Units are in degrees.

Example: [-60 100]

Data Types: single | double

Elevation limits of the lidar, specified as a two-element vector of the form [min max]. Units are in degrees.

Example: [-60 100]

Data Types: single | double

Add noise to lidar sensor measurements, specified as true or false. Set this property to true to add noise to the sensor measurements. Otherwise, the measurements have no noise.

Example: false

Data Types: logical

Output generated data as organized point cloud, specified as true or false. Set this property to true to output an organized point cloud. Otherwise, the output is unorganized.

Example: false

Data Types: logical

Usage

Description

With UAV Scenario

ptCloud = lidar() generates a lidar point cloud object in a UAV Scenario. Use this syntax after adding lidar sensor to the UAV scenario using uavSensor. The updateSensors method uses this syntax to generate lidar detections based on the latest states of static meshes and UAV platforms in the scenario.

Without UAV Scenario

ptCloud = lidar(tgts,simTime) generates a lidar point cloud object ptCloud from the specified target object, tgts, at the specified simulation time simTime.

[ptCloud,isValidTime] = lidar(tgts,simTime) additionally returns isValidTime which specifies if the specified simTime is a multiple of the sensor's update interval (1/UpdateRate).

Input Arguments

expand all

Target object data, specified as a structure or structure array. Each structure corresponds to a mesh. The table shows the properties that the object uses to generate detections.

Target Object Data

FieldDescription
MeshAn extendedObjectMesh object representing the geometry of the target object in its own coordinate frame.
PositionA three-element vector defining the coordinate position of the target with respect to the sensor frame.
OrientationA quaternion object or a 3-by-3 matrix, containing Euler angles, defining the orientation of the target with respect to the sensor frame.

Current simulation time, specified as a positive real scalar. The lidar object calls the lidar point cloud generator at regular intervals to generate new point clouds at a frequency defined by the updateRate property. The value of the UpdateRate property must be an integer multiple of the simulation time interval. Updates requested from the sensor between update intervals do not generate a point cloud. Units are in seconds.

Output Arguments

expand all

Point cloud data, returned as a pointCloud object.

Valid time to generate point cloud, returned as logical 0 (false) or 1 (false). isValidTime is 0 when the requested update time is not a multiple of the updateRate property value.

Data Types: logical

Object Functions

To use an object function, specify the System object as the first input argument. For example, to release system resources of a System object named obj, use this syntax:

release(obj)

expand all

stepRun System object algorithm
releaseRelease resources and allow changes to System object property values and input characteristics
resetReset internal states of System object

Examples

collapse all

This example shows how to use a statistical lidar sensor model to generate point clouds from a mesh.

Create Sensor Model

Create a statistical sensor model, lidar, using the uavLidarPointCloudGenerator System object.

lidar = uavLidarPointCloudGenerator('HasOrganizedOutput',false);

Create Floor

Use the extendedObjectMesh object to create mesh for the target object.

tgts.Mesh = scale(extendedObjectMesh('cuboid'),[100 100 2]); 

Define the position of the target object with respect to the sensor frame.

tgts.Position = [0 0 -10];

Define the orientation of the target with respect to the sensor frame.

 tgts.Orientation = quaternion([1 0 0 0]);

Generate Point Clouds from Floor

 ptCloud = lidar(tgts,0); 

Visualize

Use the translate function to translate the object mesh to its specified location and use the show function to visualize it. Use the scatter3 function to plot the point clouds stored in ptCloud.

figure
show(translate(tgts.Mesh,tgts.Position));
hold on
scatter3(ptCloud.Location(:,1),ptCloud.Location(:,2), ...
       ptCloud.Location(:,3));

Figure contains an axes object. The axes object contains 2 objects of type patch, scatter.

Create a scenario to simulate unmanned aerial vehicle (UAV) flights between a set of buildings. The example demonstrates updating the UAV pose in open-loop simulations. Use the UAV scenario to visualize the UAV flight and generate simulated point cloud sensor readings.

Introduction

To test autonomous algorithms, a UAV scenario enables you to generate test cases and generate sensor data from the environment. You can specify obstacles in the workspace, provide trajectories of UAVs in global coordinates, and convert data between coordinate frames. The UAV scenario enables you to visualize this information in the reference frame of the environment.

Create Scenario with Polygon Building Meshes

A uavScenario object is a model consisting of a set of static obstacles and movable objects called platforms. Use uavPlatform objects to model fixed-wing UAVs, multirotors, and other objects within the scenario. This example builds a scenario consisting of a ground plane and 11 buildings as by extruded polygons. The polygon data for the buildings is loaded and used to add polygon meshes.

% Create the UAV scenario.
scene = uavScenario(UpdateRate=2,ReferenceLocation=[75 -46 0]);

% Add a ground plane.
color.Gray = 0.651*ones(1,3);
color.Green = [0.3922 0.8314 0.0745];
color.Red = [1 0 0];
addMesh(scene,"polygon",{[-250 -150; 200 -150; 200 180; -250 180],[-4 0]},color.Gray)

% Load building polygons.
load("buildingData.mat");

% Add sets of polygons as extruded meshes with varying heights from 10-30.
addMesh(scene,"polygon",{buildingData{1}(1:4,:),[0 30]},color.Green)
addMesh(scene,"polygon",{buildingData{2}(2:5,:),[0 30]},color.Green)
addMesh(scene,"polygon",{buildingData{3}(2:10,:),[0 30]},color.Green)
addMesh(scene,"polygon",{buildingData{4}(2:9,:),[0 30]},color.Green)
addMesh(scene,"polygon",{buildingData{5}(1:end-1,:),[0 30]},color.Green)
addMesh(scene,"polygon",{buildingData{6}(1:end-1,:),[0 15]},color.Green)
addMesh(scene,"polygon",{buildingData{7}(1:end-1,:),[0 30]},color.Green)
addMesh(scene,"polygon",{buildingData{8}(2:end-1,:),[0 10]},color.Green)
addMesh(scene,"polygon",{buildingData{9}(1:end-1,:),[0 15]},color.Green)
addMesh(scene,"polygon",{buildingData{10}(1:end-1,:),[0 30]},color.Green)
addMesh(scene,"polygon",{buildingData{11}(1:end-2,:),[0 30]},color.Green)

% Show the scenario.
show3D(scene);
xlim([-250 200])
ylim([-150 180])
zlim([0 50])

Figure contains an axes object. The axes object with xlabel East (m), ylabel North (m) contains 12 objects of type patch.

Define UAV Platform and Mount Sensor

You can define a uavPlatform in the scenario as a carrier of your sensor models and drive them through the scenario to collect simulated sensor data. You can associate the platform with various meshes, such as fixedwing, quadrotor, and cuboid meshes. You can define a custom mesh defined ones represented by vertices and faces. Specify the reference frame for describing the motion of your platform.

Load flight data into the workspace and create a quadrotor platform using an NED reference frame. Specify the initial position and orientation based on loaded flight log data. The configuration of the UAV body frame orients the x-axis as forward-positive, the y-axis as right-positive, and the z-axis downward-positive.

load("flightData.mat")

% Set up platform
plat = uavPlatform("UAV",scene,ReferenceFrame="NED", ...
    InitialPosition=position(:,:,1),InitialOrientation=eul2quat(orientation(:,:,1)));

% Set up platform mesh. Add a rotation to orient the mesh to the UAV body frame.
updateMesh(plat,"quadrotor",{10},color.Red,[0 0 0],eul2quat([0 0 pi]))

You can choose to mount different sensors, such as the insSensor, gpsSensor, gnssMeasurementGenerator, or uavLidarPointCloudGenerator System objects to your UAV. Mount a lidar point cloud generator and a uavSensor object that contains the lidar sensor model. Specify a mounting location of the sensor that is relative to the UAV body frame.

lidarmodel = uavLidarPointCloudGenerator(AzimuthResolution=0.3324099,...
    ElevationLimits=[-20 20],ElevationResolution=1.25,...
    MaxRange=90,UpdateRate=2,HasOrganizedOutput=true);

lidar = uavSensor("Lidar",plat,lidarmodel,MountingLocation=[0,0,-1]);

Fly the UAV Platform Along Pre-Defined Trajectory and Collect Point Cloud Sensor Readings

Move the UAV along a pre-defined trajectory, and collect the lidar sensor readings along the way. This data could be used to test lidar-based mapping and localization algorithms.

Preallocate the traj and scatterPlot line plots and then specify the plot-specific data sources. During the simulation of the uavScenario, use the provided plotFrames output from the scene as the parent axes to visualize your sensor data in the correct coordinate frames.

Visualize the scene.

[ax,plotFrames] = show3D(scene);

Update plot view for better visibility.

xlim([-250 200])
ylim([-150 180])
zlim([0 50])
view([-110 30])
axis equal
hold on

Create a line plot for the trajectory. First create the plot with plot3, then manually modify the data source properties of the plot. This improves performance of the plotting.

traj = plot3(nan,nan,nan,Color=[1 1 1],LineWidth=2);
traj.XDataSource = "position(:,2,1:idx+1)";
traj.YDataSource = "position(:,1,1:idx+1)";
traj.ZDataSource = "-position(:,3,1:idx+1)";

Create a scatter plot for the point cloud. Update the data source properties again.

colormap("jet")
pt = pointCloud(nan(1,1,3));
scatterplot = scatter3(nan,nan,nan,1,[0.3020 0.7451 0.9333],...
    Parent=plotFrames.UAV.Lidar);
scatterplot.XDataSource = "reshape(pt.Location(:,:,1),[],1)";
scatterplot.YDataSource = "reshape(pt.Location(:,:,2),[],1)";
scatterplot.ZDataSource = "reshape(pt.Location(:,:,3),[],1)";
scatterplot.CDataSource = "reshape(pt.Location(:,:,3),[],1) - min(reshape(pt.Location(:,:,3),[],1))";

Set up the simulation. Then, iterate through the positions and show the scene each time the lidar sensor updates. Advance the scene, move the UAV platform, and update the sensors.

setup(scene)
for idx = 0:size(position, 3)-1
    [isupdated,lidarSampleTime, pt] = read(lidar);
    if isupdated
        % Use fast update to move platform visualization frames.
        show3D(scene,"Time",lidarSampleTime,FastUpdate=true,Parent=ax);
        % Refresh all plot data and visualize.
        refreshdata
        drawnow limitrate
    end
    % Advance scene simulation time and move platform.
    advance(scene);
    move(plat,[position(:,:,idx+1),zeros(1,6),eul2quat(orientation(:,:,idx+1)),zeros(1,3)])
    % Update all sensors in the scene.
    updateSensors(scene)
end
hold off

Figure contains an axes object. The axes object with xlabel East (m), ylabel North (m) contains 15 objects of type patch, scatter, line.

Version History

Introduced in R2020b

expand all