lidar_scan.h

Class

class LidarScan

Data structure for efficient operations on aggregated lidar data.

Stores each field (range, intensity, etc.) contiguously as a H x W block of 4-byte unsigned integers, where H is the number of beams and W is the horizontal resolution (e.g. 512, 1024, 2048).

Note: this is the “staggered” representation where each column corresponds to a single measurement in time. Use the destagger() function to create an image where columns correspond to a single azimuth angle.

Public Types

template<typename T>
using Header = Eigen::Array<T, Eigen::Dynamic, 1>

Header typedef.

using Points = Eigen::Array<double, Eigen::Dynamic, 3>

XYZ coordinates with dimensions arranged contiguously in columns.

Public Functions

LidarScan()

The default constructor creates an invalid 0 x 0 scan.

LidarScan(size_t w, size_t h)

Initialize a scan with fields configured for the LEGACY udp profile.

Note, the number of columns per packet is set to the default (DEFAULT_COLUMNS_PER_PACKET).

Parameters:
  • w[in] horizontal resolution, i.e. the number of measurements per scan.

  • h[in] vertical resolution, i.e. the number of channels.

LidarScan(const sensor::sensor_info &sensor_info)

Initialize a scan with fields configured as default for the provided SensorInfo’s configuration

Parameters:

sensor_info[in] description of sensor to create scan for

LidarScan(std::shared_ptr<sensor::sensor_info> sensor_info)

Initialize a scan configured as default for the provided SensorInfo’s configuration

Parameters:

sensor_info[in] a shared_ptr to the sensor_info object

LidarScan(std::shared_ptr<sensor::sensor_info> sensor_info, const std::vector<FieldType> &field_types)

Initialize a scan for the given sensor info with either the default for the provided configuration or provided fields.

Parameters:
  • sensor_info[in] a shared_ptr to the sensor_info object

  • field_types[in] fields to use in the lidar scan

LidarScan(size_t w, size_t h, sensor::UDPProfileLidar profile, size_t columns_per_packet = DEFAULT_COLUMNS_PER_PACKET)

Initialize a scan with the default fields for a particular udp profile.

Parameters:
  • w[in] horizontal resolution, i.e. the number of measurements per scan.

  • h[in] vertical resolution, i.e. the number of channels.

  • profile[in] udp profile.

  • columns_per_packet[in] The number of columns per packet, this argument is optional.

template<typename Iterator>
inline LidarScan(size_t w, size_t h, Iterator begin, Iterator end, size_t columns_per_packet = DEFAULT_COLUMNS_PER_PACKET)

Initialize a scan with a custom set of fields.

Template Parameters:

Iterator – A standard template iterator for the custom fields.

Parameters:
  • w[in] horizontal resoulution, i.e. the number of measurements per scan.

  • h[in] vertical resolution, i.e. the number of channels.

  • begin[in] begin iterator of pairs of channel fields and types.

  • end[in] end iterator of pairs of channel fields and types.

  • columns_per_packet[in] The number of columns per packet, this argument is optional.

LidarScan(const LidarScan &other)

Initialize a lidar scan from another lidar scan.

Parameters:

other[in] The other lidar scan to initialize from.

LidarScan(const LidarScan &other, const LidarScanFieldTypes &fields)

Initialize a lidar scan from another with only the indicated fields. Casts, zero pads or removes fields from the original scan if necessary.

Throws:

std::invalid_argument – if field dimensions are incompatible

Parameters:
  • other[in] The other lidar scan to initialize from.

  • fields[in] Fields to have in new lidar scan.

LidarScan(LidarScan &&other)

Initialize a lidar scan from another lidar scan.

Parameters:

other[in] The other lidar scan to initialize from.

LidarScan &operator=(const LidarScan &other)

Copy.

Parameters:

other[in] The lidar scan to copy from.

LidarScan &operator=(LidarScan &&other)

Copy via Move semantic.

Parameters:

other[in] The lidar scan to copy from.

~LidarScan()

Lidar scan destructor.

sensor::ShotLimitingStatus shot_limiting() const

Get frame shot limiting status

Returns:

true if sensor is shot limiting

sensor::ThermalShutdownStatus thermal_shutdown() const

Get frame thermal shutdown status

Returns:

true if sensor is in thermal shutdown state.

template<typename T>
Eigen::Ref<img_t<T>> field(const std::string &f)

Access a lidar data field.

Throws:

std::invalid_argument – if T does not match the runtime field type.

Template Parameters:

T – The type parameter T must match the dynamic type of the field. See the constructor documentation for expected field types or query dynamically for generic operations.

Parameters:

f[in] the field to view.

Returns:

a view of the field data.

template<typename T>
Eigen::Ref<const img_t<T>> field(const std::string &f) const

Access a lidar data field.

Throws:

std::invalid_argument – if T does not match the runtime field type.

Template Parameters:

T – The type parameter T must match the dynamic type of the field. See the constructor documentation for expected field types or query dynamically for generic operations.

Parameters:

f[in] the field to view.

Returns:

a view of the field data.

Field &field(const std::string &name)

Access a lidar data field.

Parameters:

name[in] string key of the field to access

Returns:

Field reference of the requested field

const Field &field(const std::string &name) const

Access a lidar data field.

Parameters:

name[in] string key of the field to access

Returns:

Field reference of the requested field

bool has_field(const std::string &name) const

Check if a field exists

Parameters:

name[in] string key of the field to check

Returns:

true if the lidar scan has the field, else false

Field &add_field(const std::string &name, FieldDescriptor d, FieldClass field_class = FieldClass::PIXEL_FIELD)

Add a new zero-filled field to lidar scan.

Throws:

std::invalid_argument – if key duplicates a preexisting field, or if flags dimensional requirements are not met

Parameters:
  • name[in] string key of the field to add

  • d[in] descriptor of the field to add

  • field_class[in] class to be assigned to the field, e.g. PIXEL_FIELD

Returns:

field

Field &add_field(const FieldType &type)

Add a new zero-filled field to lidar scan.

Throws:

std::invalid_argument – if key duplicates a preexisting field

Parameters:

type[in] Descriptor of the field to add.

Returns:

field The value of the field added.

Field del_field(const std::string &name)

Release the field and remove it from lidar scan

Throws:

std::invalid_argument – if field under key does not exist

Parameters:

name[in] string key of the field to remove

Returns:

field The deleted field.

FieldType field_type(const std::string &name) const

Get the type of the specified field.

Parameters:

name[in] the string key of the field to query.

Returns:

the type associated with the field.

LidarScanFieldTypes field_types() const

Get the FieldType of all fields in the scan

Returns:

The type associated with every field in the scan.

std::unordered_map<std::string, Field> &fields()

Reference to the internal fields map

Returns:

The unordered map of field type and field.

const std::unordered_map<std::string, Field> &fields() const

Reference to the internal fields map

Returns:

The unordered map of field type and field.

Eigen::Ref<Header<uint64_t>> timestamp()

Access the measurement timestamp headers.

Returns:

a view of timestamp as a w-element vector.

Eigen::Ref<const Header<uint64_t>> timestamp() const

Access the measurement timestamp headers.

Returns:

a view of timestamp as a w-element vector.

Eigen::Ref<Header<uint64_t>> packet_timestamp()

Access the packet timestamp headers (usually host time).

Returns:

a view of timestamp as a vector with w / columns-per-packet elements.

Eigen::Ref<const Header<uint64_t>> packet_timestamp() const

Access the host timestamp headers (usually host time).

Returns:

a view of timestamp as a vector with w / columns-per-packet elements.

Eigen::Ref<Header<uint8_t>> alert_flags()

Access the packet alert flags headers.

Returns:

a view of timestamp as a vector with w / columns-per-packet elements.

Eigen::Ref<const Header<uint8_t>> alert_flags() const

Access the packet alert flags headers.

Returns:

a view of timestamp as a vector with w / columns-per-packet elements.

uint64_t get_first_valid_packet_timestamp() const

Return the first valid packet timestamp

Returns:

the first valid packet timestamp, 0 if none available

uint64_t get_last_valid_packet_timestamp() const

Return the last valid packet timestamp

Returns:

the last valid packet timestamp, 0 if none available

uint64_t get_first_valid_column_timestamp() const

Return the first valid column timestamp

Returns:

the first valid column timestamp, 0 if none available

uint64_t get_last_valid_column_timestamp() const

Return the last valid column timestamp

Returns:

the last valid column timestamp, 0 if none available

int get_first_valid_column() const

Return the first valid column index

Returns:

the first valid column index, -1 if none available

int get_last_valid_column() const

Return the last valid column index

Returns:

the last valid column index, -1 if none available

Eigen::Ref<Header<uint16_t>> measurement_id()

Access the measurement id headers.

Returns:

a view of measurement ids as a w-element vector.

Eigen::Ref<const Header<uint16_t>> measurement_id() const

Access the measurement id headers.

Returns:

a view of measurement ids as a w-element vector.

Eigen::Ref<Header<uint32_t>> status()

Access the measurement status headers.

Returns:

a view of measurement statuses as a w-element vector.

Eigen::Ref<const Header<uint32_t>> status() const

Access the measurement status headers.

Returns:

a view of measurement statuses as a w-element vector.

Field &pose()

Access the array of poses (per each timestamp). Cast to ArrayView3<double> in order to access as 3d

Returns:

3d field of homogenous pose matrices, shaped (w, 4, 4).

const Field &pose() const

Access the array of poses (per each timestamp). Cast to ArrayView3<double> in order to access as 3d

Returns:

3d field of homogenous pose matrices, shaped (w, 4, 4).

bool complete(sensor::ColumnWindow window) const

Assess completeness of scan.

Parameters:

window[in] The column window to use for validity assessment

Returns:

whether all columns within given column window were valid

bool complete() const

Assess completeness of scan.

Throws:

std::runtime_error – if the LidarScan does not have an associated sensor_info

Returns:

whether all columns within the column window were valid

size_t packet_count() const

Returns the number of lidar packets used to produce this scan.

Returns:

the number of packets

bool equals(const LidarScan &other) const

Equality for scans.

Parameters:

other[in] The other scan to compare to.

Returns:

if a == b.

Public Members

size_t w = {0}

Pointer offsets to deal with strides.

Warning

Members variables: use with caution, some of these will become private.

size_t h = {0}

Pointer offsets to deal with strides.

Warning

Members variables: use with caution, some of these will become private.

size_t columns_per_packet_ = {DEFAULT_COLUMNS_PER_PACKET}

Number of columns contained in each packet making up the scan.

uint64_t frame_status = {0}

Frame status - information from the packet header which corresponds to a frame

Warning

Member variables: use with caution, some of these will become private.

uint8_t shutdown_countdown = {0}

Thermal shutdown counter. Please refer to the firmware documentation for more information.

uint8_t shot_limiting_countdown = {0}

Shot limiting counter. Please refer to the firmware documentation for more information.

int64_t frame_id = {-1}

The current frame ID.

Warning

Members variables: use with caution, some of these will become private.

std::shared_ptr<sensor::sensor_info> sensor_info

The associated sensor info for this lidar scan

class ScanBatcher

Parse lidar packets into a LidarScan.

Make a function that batches a single scan (revolution) of data to a LidarScan.

Public Functions

ScanBatcher(size_t w, const sensor::packet_format &pf)

Create a batcher given information about the scan and packet format.

Deprecated:

Use ScanBatcher::ScanBatcher(const sensor_info&) instead.

Parameters:
  • w[in] number of columns in the lidar scan. One of 512, 1024, or 2048.

  • pf[in] expected format of the incoming packets used for parsing.

ScanBatcher(const sensor::sensor_info &info)

Create a batcher given information about the scan and packet format.

Parameters:

info[in] sensor metadata returned from the client.

ScanBatcher(const std::shared_ptr<sensor::sensor_info> &info)

Create a batcher given information about the scan and packet format.

Parameters:

info[in] sensor metadata returned from the client.

bool operator()(const sensor::LidarPacket &packet, LidarScan &ls)

Add a packet to the scan.

Parameters:
  • packet[in] a LidarPacket.

  • ls[in] lidar scan to populate.

Returns:

true when the provided lidar scan is ready to use.

void reset()

Reset the batcher and clear any cached packets.

Public Members

sensor::packet_format pf

The packet format object used for decoding.

template<typename T>
class XYZLutT

Lookup table of beam directions and offsets.

Structs

struct FieldType

Public Functions

FieldType()

Initialize a default FieldType with no name.

FieldType(const std::string &name_, sensor::ChanFieldType element_type_, const std::vector<size_t> extra_dims_ = {}, FieldClass class_ = FieldClass::PIXEL_FIELD)

Initialize a lidar scan from another with only the indicated fields. Casts, zero pads or removes fields from the original scan if necessary.

Parameters:
  • name_[in] Name of the field described by the type.

  • element_type_[in] Primitive type for elements in the field.

  • extra_dims_[in] Additional dimensions of the field

  • class_[in] Category of field, determins the first dimensions of the field

inline bool operator<(const FieldType &other) const

Less than operated needed to allow sorting FieldTypes by name

Parameters:

other[in] The FieldType to compare with

Returns:

if the name is “less than” the provided FieldType

Public Members

std::string name

Name of the field.

sensor::ChanFieldType element_type

Type of field elements.

std::vector<size_t> extra_dims

Additional dimensions of the field.

FieldClass field_class = FieldClass::PIXEL_FIELD

Category of field, determines the first dimensions of the field