Apollo 11.0
自动驾驶开放平台
lidar_output_component.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
19#include <vector>
20
23
24namespace apollo {
25namespace perception {
26namespace lidar {
27
31
33 if (save_benchmark_frame_) {
34 is_terminate_.store(true);
35 benchmark_thread_->join();
36 }
37}
38
41 if (!GetProtoConfig(&comp_config)) {
42 AERROR << "Get LidarOutputComponentConfig file failed";
43 return false;
44 }
45 AINFO << "Lidar Output Component Configs: "
46 << comp_config.DebugString();
47
48 // writer
49 output_channel_name_ = comp_config.output_channel_name();
50 writer_ = node_->CreateWriter<PerceptionObstacles>(output_channel_name_);
51 // for saving benchmark frame
52 save_benchmark_frame_ = comp_config.save_benchmark_frame();
53 benchmark_frame_output_dir_ = comp_config.benchmark_frame_output_dir();
54 is_terminate_.store(false);
55 if (save_benchmark_frame_) {
56 benchmark_thread_.reset(
57 new std::thread(&LidarOutputComponent::BenchmarkThreadFunc, this));
58 }
59
60 // for saving LidarFrame
61 lidar_frame_output_dir_ = comp_config.lidar_frame_output_dir();
62 use_lidar_cooridinate_ = comp_config.use_lidar_cooridinate();
63 cyber::ReaderConfig reader_config;
64 reader_config.channel_name = comp_config.lidar_frame_channel_name();
65 reader_config.pending_queue_size = 5;
66 if (!comp_config.save_lidar_frame_message()) {
67 return true;
68 }
69 std::function<void(const std::shared_ptr<LidarFrameMessage>&)> model_call
71 this, std::placeholders::_1);
72 lidar_frame_reader_ = this->node_->CreateReader<LidarFrameMessage>(
73 reader_config, model_call);
74
75 // Attention:
76 // For DKIT-2024 Part2 benchmark-data: timestamp is just two-decimal-places
77 // But in apollo-benchmark, the timestamp diff is set to 1e-4
78 // So this should also save timestamp to two-decimal-places
79 // Trick-action: WE should modify apollo-benchmark code
80 // PS: part1 is RIGHT, completely equal to pointcloud-timestamp)
81 timestamp_two_decimal_format_ = comp_config.timestamp_two_decimal_format();
82
83 AINFO << "Register LidarFrameMessage for benchmark";
84 return true;
85}
86
88 const std::shared_ptr<SensorFrameMessage>& in_message) {
89 std::shared_ptr<PerceptionObstacles> out_message(new (std::nothrow)
91 double timestamp = in_message->timestamp_;
92 double lidar_timestamp = in_message->lidar_timestamp_;
94 std::vector<base::ObjectPtr> valid_objects;
95
96 if (in_message != nullptr && in_message->frame_ != nullptr) {
97 auto lidar_objects = in_message->frame_->objects;
98 valid_objects.assign(lidar_objects.begin(), lidar_objects.end());
99 }
100
101 if (save_benchmark_frame_) {
102 std::lock_guard<std::mutex> lock(benchmark_mutex_);
103 message_buffer_.push(in_message);
104 }
105
107 timestamp,
108 lidar_timestamp,
109 in_message->seq_num_,
110 valid_objects,
111 error_code,
112 out_message.get())) {
113 AERROR << "Failed to gen PerceptionObstacles object.";
114 return false;
115 }
116
117 writer_->Write(out_message);
118 AINFO << "Send lidar tracking output message.";
119
120 return true;
121}
122
124 const std::shared_ptr<SensorFrameMessage>& in_message) {
125 std::shared_ptr<PerceptionBenchmarkFrame> out_message(new (std::nothrow)
127 double timestamp = in_message->timestamp_;
128 double lidar_timestamp = in_message->lidar_timestamp_;
129 std::vector<base::ObjectPtr> valid_objects;
130
131 if (in_message != nullptr && in_message->frame_ != nullptr) {
132 auto lidar_objects = in_message->frame_->objects;
133 valid_objects.assign(lidar_objects.begin(), lidar_objects.end());
134 }
135
136 auto sensor_frame_info = out_message->mutable_sensor_frame_info();
137 sensor_frame_info->set_sensor_id(in_message->sensor_id_);
138 sensor_frame_info->set_timestamp(timestamp);
139
140 Eigen::Affine3d sensor2world_pose = Eigen::Affine3d::Identity();
141 if (in_message == nullptr || in_message->frame_ == nullptr) {
142 AERROR << "SaveBenchmarkFrame error, Can't get sensor2world_pose.";
143 }
144 sensor2world_pose = in_message->frame_->sensor2world_pose;
145 for (int i = 0; i < 4; ++i) {
146 for (int j = 0; j < 4; ++j) {
147 double val = sensor2world_pose.matrix()(i, j);
148 sensor_frame_info->add_sensor2world_pose(val);
149 }
150 }
151
152 // Serialize benchmark message
154 timestamp,
155 lidar_timestamp,
156 in_message->seq_num_,
157 valid_objects,
158 out_message.get())) {
159 AERROR << "Failed to get PerceptionBenchmarkFrame object.";
160 return false;
161 }
162
163 if (!EnsureDirectory(benchmark_frame_output_dir_)) {
164 AINFO << "Create dir " << benchmark_frame_output_dir_ << " error.";
165 return false;
166 }
167
168 double two_demical_time = round(timestamp * 100) / 100.0;
169 std::string pb_name = "";
170 if (timestamp_two_decimal_format_) {
171 pb_name = GetAbsolutePath(benchmark_frame_output_dir_,
172 std::to_string(two_demical_time) + ".pb");
173 } else {
174 pb_name = GetAbsolutePath(benchmark_frame_output_dir_,
175 std::to_string(timestamp) + ".pb");
176 }
177 SetProtoToASCIIFile(*out_message, pb_name);
178
179 return true;
180}
181
183 const std::shared_ptr<LidarFrameMessage>& in_message) {
184 std::shared_ptr<PerceptionBenchmarkFrame> out_message(
185 new (std::nothrow) PerceptionBenchmarkFrame);
186 double timestamp = in_message->timestamp_;
187 double lidar_timestamp = in_message->lidar_timestamp_;
188
189 std::vector<base::ObjectPtr> valid_objects;
190 if (in_message != nullptr && in_message->lidar_frame_ != nullptr) {
191 auto lidar_objects = in_message->lidar_frame_->segmented_objects;
192 valid_objects.assign(lidar_objects.begin(), lidar_objects.end());
193 }
194
195 auto sensor_frame_info = out_message->mutable_sensor_frame_info();
196 sensor_frame_info->set_sensor_id(
197 in_message->lidar_frame_->sensor_info.name);
198 sensor_frame_info->set_timestamp(timestamp);
199
200 Eigen::Affine3d sensor2world_pose = Eigen::Affine3d::Identity();
201 if (in_message == nullptr || in_message->lidar_frame_ == nullptr) {
202 AERROR << "SaveBenchmarkLidarFrame Error, Can't get lidar2world_pose";
203 }
204 sensor2world_pose = in_message->lidar_frame_->lidar2world_pose;
205 for (int i = 0; i < 4; ++i) {
206 for (int j = 0; j < 4; ++j) {
207 double val = sensor2world_pose.matrix()(i, j);
208 sensor_frame_info->add_sensor2world_pose(val);
209 }
210 }
211
212 // Serialize LidarFrame benchmark message
214 timestamp,
215 lidar_timestamp,
216 in_message->seq_num_,
217 sensor2world_pose,
218 valid_objects,
219 out_message.get(),
220 use_lidar_cooridinate_)) {
221 AERROR << "Failed to get SerializeLidarFrameMsg object.";
222 return false;
223 }
224
225 if (!EnsureDirectory(lidar_frame_output_dir_)) {
226 AERROR << "Create dir " << lidar_frame_output_dir_ << " error.";
227 return false;
228 }
229 double two_demical_time = round(timestamp * 100) / 100.0;
230 std::string pb_name = "";
231 if (timestamp_two_decimal_format_) {
232 pb_name = GetAbsolutePath(lidar_frame_output_dir_,
233 std::to_string(two_demical_time) + ".pb");
234 } else {
235 pb_name = GetAbsolutePath(lidar_frame_output_dir_,
236 std::to_string(timestamp) + ".pb");
237 }
238 SetProtoToASCIIFile(*out_message, pb_name);
239
240 AINFO << "SaveBenchmarkLidarFrame Success: time is "
241 << std::to_string(timestamp);
242 return true;
243}
244
246 std::shared_ptr<SensorFrameMessage> message = nullptr;
247 while (true) {
248 {
249 std::lock_guard<std::mutex> lock(benchmark_mutex_);
250 if (!message_buffer_.empty()) {
251 message = message_buffer_.front();
252 message_buffer_.pop();
253 } else {
254 message = nullptr;
255 }
256 }
257
258 if (is_terminate_.load()) {
259 break;
260 }
261 if (message != nullptr) {
262 SaveBenchmarkFrame(message);
263 }
264 std::this_thread::sleep_for(std::chrono::milliseconds(1));
265 }
266 AINFO << "Save benchmark frames finished.";
267}
268
269} // namespace lidar
270} // namespace perception
271} // namespace apollo
bool GetProtoConfig(T *config) const
std::shared_ptr< Node > node_
bool SaveBenchmarkFrame(const std::shared_ptr< SensorFrameMessage > &message)
Save benchmark frame for end-to-end evaluation
bool SaveBenchmarkLidarFrame(const std::shared_ptr< LidarFrameMessage > &message)
bool Init() override
Init lidar output component
bool Proc(const std::shared_ptr< SensorFrameMessage > &message) override
Process of lidar output component
static bool SerializeMsg(double timestamp, uint64_t lidar_timestamp, int seq_num, const std::vector< base::ObjectPtr > &objects, const apollo::common::ErrorCode &error_code, PerceptionObstacles *obstacles)
static bool SerializeLidarFrameMsg(double timestamp, uint64_t lidar_timestamp, int seq_num, const Eigen::Affine3d &pose, const std::vector< base::ObjectPtr > &objects, PerceptionBenchmarkFrame *obstacles, bool use_lidar_cooridinate=true)
static bool SerializeBenchmarkMsg(double timestamp, uint64_t lidar_timestamp, int seq_num, const std::vector< base::ObjectPtr > &objects, PerceptionBenchmarkFrame *obstacles)
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
bool SetProtoToASCIIFile(const google::protobuf::Message &message, int file_descriptor)
Definition file.cc:43
std::string GetAbsolutePath(const std::string &prefix, const std::string &relative_path)
Get absolute path by concatenating prefix and relative_path.
Definition file.cc:179
bool EnsureDirectory(const std::string &directory_path)
Check if a specified directory specified by directory_path exists.
Definition file.cc:285
class register implement
Definition arena_queue.h:37
uint32_t pending_queue_size
configuration for responding ChannelBuffer.