lidar_scan.h
LidarScan
-
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
-
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(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_first_valid_column_timestamp() const
Return the first valid column timestamp
- Returns:
the first valid column timestamp, 0 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
-
size_t packet_count() const
Returns the number of lidar packets used to produce this scan.
- Returns:
the number of packets
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.
-
using Points = Eigen::Array<double, Eigen::Dynamic, 3>
-
LidarScan::Points cartesian(const LidarScan &scan, const XYZLut &lut)
Convert LidarScan to Cartesian points.
-
LidarScan::Points cartesian(const Eigen::Ref<const img_t<uint32_t>> &range, const XYZLut &lut)
Convert a staggered range image to Cartesian points.
-
bool operator==(const LidarScan &a, const LidarScan &b)
Equality for scans.
- Parameters:
a – [in] The first scan to compare.
b – [in] The second scan to compare.
- Returns:
if a == b.
-
inline bool operator!=(const LidarScan &a, const LidarScan &b)
NOT Equality for scans.
- Parameters:
a – [in] The first scan to compare.
b – [in] The second scan to compare.
- Returns:
if a != b.
Destagger
-
template<typename T>
inline img_t<T> destagger(const Eigen::Ref<const img_t<T>> &img, const std::vector<int> &pixel_shift_by_row, bool inverse = false) Generate a destaggered version of a channel field.
In the default staggered representation, each column corresponds to a single timestamp. In the destaggered representation, each column corresponds to a single azimuth angle, compensating for the azimuth offset of each beam.
Destaggering is used for visualizing lidar data as an image or for algorithms that exploit the structure of the lidar data, such as beam_uniformity in ouster_viz, or computer vision algorithms.
- Template Parameters:
T – the datatype of the channel field.
- Parameters:
img – [in] the channel field.
pixel_shift_by_row – [in] offsets, usually queried from the sensor.
inverse – [in] perform the inverse operation.
- Returns:
destaggered version of the image.
-
template<typename T>
inline img_t<T> stagger(const Eigen::Ref<const img_t<T>> &img, const std::vector<int> &pixel_shift_by_row) Generate a staggered version of a channel field.
- Template Parameters:
T – the datatype of the channel field.
- Parameters:
img – [in] the channel field.
pixel_shift_by_row – [in] offsets, usually queried from the sensor.
- Returns:
staggered version of the image.
XYZLut
-
struct XYZLut
Lookup table of beam directions and offsets.
-
XYZLut ouster::make_xyz_lut(size_t w, size_t h, double range_unit, const mat4d &beam_to_lidar_transform, const mat4d &transform, const std::vector<double> &azimuth_angles_deg, const std::vector<double> &altitude_angles_deg)
Generate a set of lookup tables useful for computing Cartesian coordinates from ranges.
The lookup tables are:
direction: a matrix of unit vectors pointing radially outwards.
offset: a matrix of offsets dependent on beam origin distance from lidar origin.
Each table is an n x 3 array of doubles stored in column-major order where each row corresponds to the nth point in a lidar scan, with 0 <= n < h*w.
Projections to XYZ made with this XYZLut will be in the coordinate frame defined by transform*beam_to_lidar_transform.
- Parameters:
w – [in] number of columns in the lidar scan. e.g. 512, 1024, or 2048.
h – [in] number of rows in the lidar scan.
range_unit – [in] the unit, in meters, of the range, e.g. sensor::range_unit.
beam_to_lidar_transform – [in] transform between beams and lidar origin. Translation portion is in millimeters.
transform – [in] additional transformation to apply to resulting points.
azimuth_angles_deg – [in] azimuth offsets in degrees for each of h beams.
altitude_angles_deg – [in] altitude in degrees for each of h beams.
- Returns:
xyz direction and offset vectors for each point in the lidar scan.
-
XYZLut ouster::make_xyz_lut(const sensor::sensor_info &sensor, bool use_extrinsics)
Convenient overload that uses parameters from the supplied sensor_info. Projections to XYZ made with this XYZLut will be in the sensor coordinate frame defined in the sensor documentation unless use_extrinics is true. Then the projections will be in the coordinate frame defined by the provided extrinsics in the metadata.
- Parameters:
sensor – [in] metadata returned from the client.
use_extrinsics – [in] if true, applies the
sensor.extrinsic
transform to the resulting “sensor frame” coordinates
- Returns:
xyz direction and offset vectors for each point in the lidar scan.
ScanBatcher
-
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.
-
bool operator()(const uint8_t *packet_buf, LidarScan &ls)
Add a packet to the scan.
- Deprecated:
this method is deprecated in favor of one that accepts a reference to a LidarPacket.
- Parameters:
packet_buf – [in] a buffer containing raw bytes from a lidar packet.
ls – [in] lidar scan to populate.
- Returns:
true when the provided lidar scan is ready to use.
-
bool operator()(const ouster::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.
-
bool operator()(const uint8_t *packet_buf, uint64_t packet_ts, LidarScan &ls)
Add a packet to the scan.
- Parameters:
packet_buf – [in] a buffer containing raw bytes from a lidar packet.
packet_ts – [in] timestamp of the packet (usually HOST time on receive).
ls – [in] lidar scan to populate.
- Returns:
true when the provided lidar scan is ready to use.
Public Members
-
sensor::packet_format pf
The packet format object used for decoding.
-
ScanBatcher(size_t w, const sensor::packet_format &pf)