CARLA
 
载入中...
搜索中...
未找到
SemanticLidarData.h
浏览该文件的文档.
1// Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma
2// de Barcelona (UAB).
3//
4// This work is licensed under the terms of the MIT license.
5// For a copy, see <https://opensource.org/licenses/MIT>.
6
7#pragma once
8
10
11#include <cstdint>
12#include <vector>
13#include <numeric>
14// 定义carla命名空间
15namespace carla {
16// ros2子命名空间
17namespace ros2 {
18 class ROS2;
19}
20//对传感器数据处理等相关的类定义
21namespace sensor {
22// s11n子命名空间空间,这里前置声明了语义激光雷达相关的序列化器和头视图类
23namespace s11n {
24 class SemanticLidarSerializer;
25 class SemanticLidarHeaderView;
26}
27// data子命名空间,用于存放和传感器数据具体表示、操作相关的类,下面定义了语义激光雷达数据处理相关的类
28namespace data {
29
30 /// Helper class to store and serialize the data generated by a RawLidar.
31 ///
32 /// The header of a Lidar measurement consists of an array of uint32_t's in
33 /// the following layout
34 ///
35 /// {
36 /// Horizontal angle (float),
37 /// Channel count,
38 /// Point count of channel 0,
39 /// ...
40 /// Point count of channel n,
41 /// }
42 ///
43 /// The points are stored in an array of detections, each detection consist in
44 /// four floats, the point detected and the angle between the casted ray and
45 /// the normal of the hitted object, and two unsigned integers, the index
46 /// and the semantic tag of the hitted object
47 ///
48 /// {
49 /// X0, Y0, Z0, Cos(TH0), idx_0, tag_0
50 /// ...
51 /// Xn, Yn, Zn, Cos(THn), idx_n, tag_n
52 /// }
53 /// @brief SemanticLidarDetection类,作为辅助类,用于存储和序列化由原始激光雷达(RawLidar)生成的数据中的单个检测信息。
54 /// @details 一个激光雷达测量的头部信息由一个uint32_t类型的数组构成,其布局如下所述,而每个检测点(SemanticLidarDetection)包含了位置、角度以及被检测物体的索引和语义标签等信息,方便后续对激光雷达检测数据的处理和存储。
55
56 #pragma pack(push, 1)
58 public:
59 geom::Location point{};/// 表示检测到的点的位置信息
60 float cos_inc_angle{};/// 表示检测光线与被击中物体法线之间夹角的余弦值,初始化为0。
61 uint32_t object_idx{};/// 被检测物体的索引
62 uint32_t object_tag{}; /// 被检测物体的语义标签
63//默认构造函数,使用类成员的默认初始化方式创建对象
65/// 构造函数,根据给定的坐标值、夹角余弦值、物体索引和语义标签来初始化对象,方便从具体数值创建检测点对象。
66/// 检测点的x坐标值。
67/// y 检测点的y坐标值。
68 /// @param z 检测点的z坐标值。
69 /// @param cosTh 检测光线与被击中物体法线之间夹角的余弦值。
70 /// @param idx 被检测物体的索引。
71 /// @param tag 被检测物体的语义标签。
72 SemanticLidarDetection(float x, float y, float z, float cosTh, uint32_t idx, uint32_t tag) :
73 point(x, y, z), cos_inc_angle{cosTh}, object_idx{idx}, object_tag{tag} { }
74 /// @brief 构造函数,根据给定的位置对象、夹角余弦值、物体索引和语义标签来初始化对象,同样用于创建检测点对象,只是参数形式使用已有的位置对象。
75 /// @param p 表示检测点位置的geom::Location类型对象。
76/// @param cosTh 检测光线与被击中物体法线之间夹角的余弦值。
77 /// @param idx 被检测物体的索引。
78 /// @param tag 被检测物体的语义标签。
79 SemanticLidarDetection(geom::Location p, float cosTh, uint32_t idx, uint32_t tag) :
80 point(p), cos_inc_angle{cosTh}, object_idx{idx}, object_tag{tag} { }
81/// @brief 将该检测点相关的属性信息以PLY文件格式的头部信息形式写入到给定的输出流中,PLY文件常用于存储三维模型等数据,这里可能用于后续将激光雷达数据保存为PLY格式时写入头部相关描述信息。
82 /// @param out 指向输出流对象(例如文件输出流等)的引用,用于写入数据。
83 void WritePlyHeaderInfo(std::ostream& out) const{
84 out << "property float32 x\n" \
85 "property float32 y\n" \
86 "property float32 z\n" \
87 "property float32 CosAngle\n" \
88 "property uint32 ObjIdx\n" \
89 "property uint32 ObjTag";
90 }
91/// @brief 将该检测点的具体数据(坐标、夹角余弦值、物体索引和语义标签)写入到给定的输出流中,用于将单个检测点的数据输出到流中,可能用于保存数据或者传输等操作。
92 /// @param out 指向输出流对象(例如文件输出流等)的引用,用于写入数据
93 void WriteDetection(std::ostream& out) const{
94 out << point.x << ' ' << point.y << ' ' << point.z << ' ' \
95 << cos_inc_angle << ' ' << object_idx << ' ' << object_tag;
96 }
97 };
98 #pragma pack(pop)
99
100// 使用静态断言来检查 `float` 类型的大小是否和 `uint32_t` 类型的大小相等,若不相等则在编译时输出指定的错误信息 "Invalid float size"
102 static_assert(sizeof(float) == sizeof(uint32_t), "Invalid float size");
103//静态断言,用于在编译时期检查 `float` 类型的大小是否与 `uint32_t` 类型的大小相等。
104// 之所以进行这样的检查,是因为后续代码在内存操作等方面可能基于二者大小一致的假设来实现某些功能,
105// 如果大小不相等,编译时就会报错,并显示 "Invalid float size" 这个错误提示信息。
106 protected:
107 // 定义一个名为 `Index` 的强类型枚举(enum class),其底层类型为 `size_t`,用于表示不同的索引含义
108 enum Index : size_t {
109// 表示水平角度对应的索引,枚举值
111 // 表示通道数量对应的索引,枚举值
113 // 用于表示总的大小相关的一个枚举值,可能作为一种边界或者偏移量相关的标识,具体取决于使用场景
114 SIZE
115 };
116
117 public:
118// 显式的构造函数,参数 `ChannelCount` 有默认值 `0u`,用于初始化 `SemanticLidarData` 类的对象
119 explicit SemanticLidarData(uint32_t ChannelCount = 0u)
120// 使用初始化列表初始化 `_header` 成员变量,将其大小初始化为 `Index::SIZE + ChannelCount`,并将所有元素初始化为 `0u`
121 : _header(Index::SIZE + ChannelCount, 0u) {
122// 将 `_header` 向量中对应 `Index::ChannelCount` 索引位置的元素设置为传入的通道数量 `ChannelCount`
124 }
125 // 默认实现移动赋值运算符,这里使用 `= default` 语法让编译器自动生成默认的移动赋值操作逻辑,以提高代码简洁性
127 // 虚析构函数,用于在派生类对象销毁时进行正确的资源清理等操作,这里为空实现,具体清理逻辑可在派生类中按需重写
129 // 获取水平角度的函数,返回值类型为 `float`,通过将 `_header` 中对应 `Index::HorizontalAngle` 索引位置的元素进行类型重解释转换为 `float` 类型后返回
130 float GetHorizontalAngle() const {
131 return reinterpret_cast<const float &>(_header[Index::HorizontalAngle]);
132 }
133 // 设置水平角度的函数,参数 `angle` 为要设置的角度值(`float` 类型)
134 void SetHorizontalAngle(float angle) {
135 std::memcpy(&_header[Index::HorizontalAngle], &angle, sizeof(uint32_t));
136 }
137// 获取通道数量的函数,返回值类型为 `uint32_t`,直接返回 `_header` 向量中对应 `Index::ChannelCount` 索引位置的元素值
138 uint32_t GetChannelCount() const {
140 }
141 // 虚函数,用于重置内存相关操作,参数 `points_per_channel` 是一个存储每个通道点数的无符号32位整数向量,具体重置逻辑可能因不同派生类而有差异(因为是虚函数)
142 virtual void ResetMemory(std::vector<uint32_t> points_per_channel) {
143 // 使用断言来确保当前对象的通道数量大于传入的 `points_per_channel` 向量的大小,可能是基于某种前置逻辑要求做的检查,若不满足条件则会触发调试断言失败(具体行为取决于 `DEBUG_ASSERT` 的实现)
144 DEBUG_ASSERT(GetChannelCount() > points_per_channel.size());
145 // 使用 `std::memset` 函数将 `_header` 数据(从 `Index::SIZE` 位置开始)所指向的内存区域设置为 `0`,设置的字节数为 `sizeof(uint32_t) * GetChannelCount()`,也就是按照每个通道对应 `uint32_t` 大小的空间来进行内存清零操作
146 std::memset(_header.data() + Index::SIZE, 0, sizeof(uint32_t) * GetChannelCount());
147 // 计算所有通道的总点数,通过使用 `std::accumulate` 函数对传入的每个通道点数列表进行求和操作,将所有通道的点数累加起来,得到总的点数。
148 // `std::accumulate` 函数从给定范围的起始位置(`points_per_channel.begin()`)到结束位置(`points_per_channel.end()`),以初始值0为基础,
149 // 依次将每个元素累加到这个初始值上,最终得到总和,并将结果转换为 `uint32_t` 类型存储在 `total_points` 变量中。
150 uint32_t total_points = static_cast<uint32_t>(
151 std::accumulate(points_per_channel.begin(), points_per_channel.end(), 0));
152// 清空 _ser_points 向量,通常用于清除之前存储的数据,以便重新填充新的数据
153 _ser_points.clear();
154// 为 _ser_points 向量预留足够的空间,以容纳 total_points 个元素,避免后续插入元素时频繁重新分配内存,提高性能
155 _ser_points.reserve(total_points);
156 }
157// 虚函数,用于写入通道计数信息。参数 points_per_channel 是一个存储每个通道点数的无符号32位整数向量
158 virtual void WriteChannelCount(std::vector<uint32_t> points_per_channel) {
159// 循环遍历每个通道,idxChannel 从0开始,直到通道数量(通过 GetChannelCount() 获取
160 for (auto idxChannel = 0u; idxChannel < GetChannelCount(); ++idxChannel)
161 // 将 points_per_channel 中对应通道索引的点数赋值给 _header 向量中相应的位置,Index::SIZE 应该是一个自定义的索引偏移量相关的常量之类的
162 _header[Index::SIZE + idxChannel] = points_per_channel[idxChannel];
163 }
164// 虚函数,用于写入点同步信息,参数 detection 是一个语义激光雷达检测相关的对象
165 virtual void WritePointSync(SemanticLidarDetection &detection) {
166 // 将传入的 SemanticLidarDetection 类型的 detection 对象添加到 _ser_points 向量末尾
167 _ser_points.emplace_back(detection);
168 }
169// 受保护的成员变量,用于存储一些头部相关的信息,元素类型是无符号32位整数
170 protected:
171 // 存储激光雷达数据头部信息的向量,其中包含了水平角度、通道数量以及每个通道的点数等相关信息,以 `uint32_t` 类型的数据进行存储。
172 // 通过这种方式可以方便地进行内存操作(如拷贝、清零等)以及按照特定索引访问不同的数据元素,为整个激光雷达数据的管理提供了基础的数据结构支持。
173 std::vector<uint32_t> _header;
174// 用于存储每个通道最大点数的无符号32位整数变量
176// 私有成员变量,用于存储语义激光雷达检测相关对象的向量,也就是具体的检测数据集合
177 private:
178 // 存储所有检测点数据的向量,每个元素都是一个 `SemanticLidarDetection` 类型的对象,用于保存激光雷达实际检测到的各个点的详细信息,
179 // 包括点的位置(通过 `SemanticLidarDetection` 类中的 `point` 成员表示)、检测光线与被击中物体法线之间夹角的余弦值(`cos_inc_angle` 成员)、
180 // 被检测物体的索引(`object_idx` 成员)以及被检测物体的语义标签(`object_tag` 成员)等。通过这个向量可以集中管理和操作所有的检测点数据。
181 std::vector<SemanticLidarDetection> _ser_points;
182
183// 声明友元类,允许 s11n::SemanticLidarHeaderView 类访问当前类的私有和受保护成员
185// 声明友元类,允许 s11n::SemanticLidarSerializer 类访问当前类的私有和受保护成员
187// 声明友元类,允许 carla::ros2::ROS2 类访问当前类的私有和受保护成员
188 friend class carla::ros2::ROS2;
189
190 };
191
192} // namespace s11n
193} // namespace sensor
194} // namespace carla
#define DEBUG_ASSERT(predicate)
Definition Debug.h:68
virtual void WriteChannelCount(std::vector< uint32_t > points_per_channel)
std::vector< SemanticLidarDetection > _ser_points
virtual void ResetMemory(std::vector< uint32_t > points_per_channel)
SemanticLidarData & operator=(SemanticLidarData &&)=default
SemanticLidarData(uint32_t ChannelCount=0u)
virtual void WritePointSync(SemanticLidarDetection &detection)
Helper class to store and serialize the data generated by a RawLidar.
uint32_t object_idx
表示检测光线与被击中物体法线之间夹角的余弦值,初始化为0。
uint32_t object_tag
被检测物体的索引
float cos_inc_angle
表示检测到的点的位置信息
SemanticLidarDetection(float x, float y, float z, float cosTh, uint32_t idx, uint32_t tag)
构造函数,根据给定的坐标值、夹角余弦值、物体索引和语义标签来初始化对象,方便从具体数值创建检测点对象。 检测点的x坐标值。 y 检测点的y坐标值。
void WriteDetection(std::ostream &out) const
将该检测点的具体数据(坐标、夹角余弦值、物体索引和语义标签)写入到给定的输出流中,用于将单个检测点的数据输出到流中,可能用于保存数据或者传输等操作。
void WritePlyHeaderInfo(std::ostream &out) const
将该检测点相关的属性信息以PLY文件格式的头部信息形式写入到给定的输出流中,PLY文件常用于存储三维模型等数据,这里可能用于后续将激光雷达数据保存为PLY格式时写入头部相关描述信息。
SemanticLidarDetection(geom::Location p, float cosTh, uint32_t idx, uint32_t tag)
构造函数,根据给定的位置对象、夹角余弦值、物体索引和语义标签来初始化对象,同样用于创建检测点对象,只是参数形式使用已有的位置对象。
SemanticLidarDetection()=default
被检测物体的语义标签
A view over the header of a Lidar measurement.
Serializes the data generated by Lidar sensors.
CARLA模拟器的主命名空间。
Definition Carla.cpp:139