Apollo 10.0
自动驾驶开放平台
lidar_pointcloud.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2023 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
18
19namespace apollo {
20namespace cyber {
21
22#ifdef ENABLE_ROS_MSG
23void ParseField(sensor_msgs::msg::PointField field,
24 std::shared_ptr<apollo::drivers::PointCloud> point_clouds,
25 std::string field_name,
26 sensor_msgs::msg::PointCloud2& raw_message) {
27 switch (field.datatype) {
28 case sensor_msgs::msg::PointField::INT8: {
29 sensor_msgs::PointCloud2ConstIterator<int8_t> iter(raw_message,
30 field_name);
31 int index = 0;
32 for (; iter != iter.end(); ++iter) {
33 if (field_name == "intensity") {
34 point_clouds->mutable_point(index)->set_intensity(
35 static_cast<uint32_t>(*iter));
36 } else {
37 point_clouds->mutable_point(index)->set_timestamp(
38 static_cast<uint64_t>(*iter));
39 AERROR << *iter;
40 }
41 index++;
42 }
43 break;
44 }
45 case sensor_msgs::msg::PointField::UINT8: {
46 sensor_msgs::PointCloud2ConstIterator<int8_t> iter(raw_message,
47 field_name);
48 int index = 0;
49 for (; iter != iter.end(); ++iter) {
50 if (field_name == "intensity") {
51 point_clouds->mutable_point(index)->set_intensity(
52 static_cast<uint32_t>(*iter));
53 } else {
54 point_clouds->mutable_point(index)->set_timestamp(
55 static_cast<uint64_t>(*iter));
56 AERROR << *iter;
57 }
58 index++;
59 }
60 break;
61 }
62 case sensor_msgs::msg::PointField::INT16: {
63 sensor_msgs::PointCloud2ConstIterator<int16_t> iter(raw_message,
64 field_name);
65 int index = 0;
66 for (; iter != iter.end(); ++iter) {
67 if (field_name == "intensity") {
68 point_clouds->mutable_point(index)->set_intensity(
69 static_cast<uint32_t>(*iter));
70 } else {
71 point_clouds->mutable_point(index)->set_timestamp(
72 static_cast<uint64_t>(*iter));
73 AERROR << *iter;
74 }
75 index++;
76 }
77 break;
78 }
79 case sensor_msgs::msg::PointField::UINT16: {
80 sensor_msgs::PointCloud2ConstIterator<int16_t> iter(raw_message,
81 field_name);
82 int index = 0;
83 for (; iter != iter.end(); ++iter) {
84 if (field_name == "intensity") {
85 point_clouds->mutable_point(index)->set_intensity(
86 static_cast<uint32_t>(*iter));
87 } else {
88 point_clouds->mutable_point(index)->set_timestamp(
89 static_cast<uint64_t>(*iter));
90 AERROR << *iter;
91 }
92 index++;
93 }
94 break;
95 }
96 case sensor_msgs::msg::PointField::INT32: {
97 sensor_msgs::PointCloud2ConstIterator<int32_t> iter(raw_message,
98 field_name);
99 int index = 0;
100 for (; iter != iter.end(); ++iter) {
101 if (field_name == "intensity") {
102 point_clouds->mutable_point(index)->set_intensity(
103 static_cast<uint32_t>(*iter));
104 } else {
105 point_clouds->mutable_point(index)->set_timestamp(
106 static_cast<uint64_t>(*iter));
107 AERROR << *iter;
108 }
109 index++;
110 }
111 break;
112 }
113 case sensor_msgs::msg::PointField::UINT32: {
114 sensor_msgs::PointCloud2ConstIterator<uint32_t> iter(raw_message,
115 field_name);
116 int index = 0;
117 for (; iter != iter.end(); ++iter) {
118 if (field_name == "intensity") {
119 point_clouds->mutable_point(index)->set_intensity(
120 static_cast<uint32_t>(*iter));
121 } else {
122 point_clouds->mutable_point(index)->set_timestamp(
123 static_cast<uint64_t>(*iter));
124 AERROR << *iter;
125 }
126 index++;
127 }
128 break;
129 }
130 case sensor_msgs::msg::PointField::FLOAT32: {
131 sensor_msgs::PointCloud2ConstIterator<float> iter(raw_message,
132 field_name);
133 int index = 0;
134 for (; iter != iter.end(); ++iter) {
135 if (field_name == "intensity") {
136 point_clouds->mutable_point(index)->set_intensity(
137 static_cast<uint32_t>(*iter));
138 } else {
139 point_clouds->mutable_point(index)->set_timestamp(
140 static_cast<uint64_t>(*iter));
141 AERROR << *iter;
142 }
143 index++;
144 }
145 break;
146 }
147 case sensor_msgs::msg::PointField::FLOAT64: {
148 sensor_msgs::PointCloud2ConstIterator<double> iter(raw_message,
149 field_name);
150 int index = 0;
151 for (; iter != iter.end(); ++iter) {
152 if (field_name == "intensity") {
153 point_clouds->mutable_point(index)->set_intensity(
154 static_cast<uint32_t>(*iter));
155 } else {
156 point_clouds->mutable_point(index)->set_timestamp(
157 static_cast<uint64_t>(*iter));
158 AERROR << *iter;
159 }
160 index++;
161 }
162 break;
163 }
164 default:
165 throw std::runtime_error("Unsupported PointField datatype");
166 }
167}
168#endif
169
172#ifdef ENABLE_ROS_MSG
173 auto in_msg = std::get<0>(in.values);
174 auto out_msg = std::get<0>(out.values);
175 float x, y, z;
176 float intensity = -1.0;
177 double timestamp = 0.0;
178 auto& cloud_msg = (*in_msg);
179
180 bool has_x = false, has_y = false, has_z = false, has_intensity = false,
181 has_time = false;
182 std::string time_field_name;
183 sensor_msgs::msg::PointField time_field_type;
184 sensor_msgs::msg::PointField intensity_field_type;
185 for (const auto& field : cloud_msg.fields) {
186 if (field.name == "x") has_x = true;
187 if (field.name == "y") has_y = true;
188 if (field.name == "z") has_z = true;
189 if (field.name == "intensity") {
190 has_intensity = true;
191 intensity_field_type = field;
192 }
193 if (field.name == "t" || field.name == "time" ||
194 field.name == "timestamp") {
195 has_time = true;
196 time_field_type = field;
197 time_field_name = field.name;
198 }
199 }
200 if (!(has_x && has_y && has_z)) {
201 AERROR << "PointCloud2 does not contain x, y, z fields.";
202 return false;
203 }
204
205 sensor_msgs::PointCloud2ConstIterator<float> iter_x(cloud_msg, "x");
206 sensor_msgs::PointCloud2ConstIterator<float> iter_y(cloud_msg, "y");
207 sensor_msgs::PointCloud2ConstIterator<float> iter_z(cloud_msg, "z");
208
209 for (; iter_x != iter_x.end(); ++iter_x, ++iter_y, ++iter_z) {
210 x = *iter_x;
211 y = *iter_y;
212 z = *iter_z;
213
214 auto pointcloud = out_msg->add_point();
215 pointcloud->set_x(x);
216 pointcloud->set_y(y);
217 pointcloud->set_z(z);
218 }
219 if (has_time) {
220 ParseField(time_field_type, out_msg, time_field_name, cloud_msg);
221 }
222 if (has_intensity) {
223 ParseField(intensity_field_type, out_msg, "intensity", cloud_msg);
224 }
225#endif
226 return true;
227}
228
229} // namespace cyber
230} // namespace apollo
virtual bool ConvertMsg(InputTypes< InputMsgPtr > &, OutputTypes< OutputMsgPtr > &)
convert the message between ros and apollo
#define AERROR
Definition log.h:44
class register implement
Definition arena_queue.h:37
std::tuple< Types... > values
std::tuple< Types... > values