Apollo 11.0
自动驾驶开放平台
pointcloud_preprocess_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
20#include "cyber/time/clock.h"
23
24namespace apollo {
25namespace perception {
26namespace lidar {
27
30
31std::atomic<uint32_t> PointCloudPreprocessComponent::seq_num_{0};
32
35 if (!GetProtoConfig(&comp_config)) {
36 AERROR << "Get PointCloudPreprocessComponentConfig file failed";
37 return false;
38 }
39 AINFO << "PointCloud Preprocess Component Configs: "
40 << comp_config.DebugString();
41
42 output_channel_name_ = comp_config.output_channel_name();
43 sensor_name_ = comp_config.sensor_name();
44 // Use sensor_name as lidar to novatel child_frame_id. If not equal
45 // we can use `sensor_info_` to get child_frame_id
46 lidar2novatel_tf2_child_frame_id_ = comp_config.sensor_name();
47 lidar_query_tf_offset_ =
48 static_cast<float>(comp_config.lidar_query_tf_offset());
49
50 auto plugin_param = comp_config.plugin_param();
51 std::string cloud_preprocessor_name = plugin_param.name();
52 config_path_ = plugin_param.config_path();
53 config_file_ = plugin_param.config_file();
54 cloud_preprocessor_ = BasePointCloudPreprocessorRegisterer::GetInstanceByName(
55 cloud_preprocessor_name);
56 CHECK_NOTNULL(cloud_preprocessor_);
57 // writer
58 writer_ =
59 node_->CreateWriter<onboard::LidarFrameMessage>(output_channel_name_);
60
61 if (!InitAlgorithmPlugin()) {
62 AERROR << "Failed to init pointcloud preprocess component plugin.";
63 return false;
64 }
65
66 return true;
67}
68
70 const std::shared_ptr<drivers::PointCloud>& message) {
72 AINFO << std::setprecision(16)
73 << "Enter pointcloud preprocess component, message timestamp: "
74 << message->measurement_time()
75 << " current timestamp: " << Clock::NowInSeconds();
76
77 auto out_message = std::make_shared<onboard::LidarFrameMessage>();
78
79 bool status = InternalProc(message, out_message);
80 if (status) {
81 writer_->Write(out_message);
82 AINFO << "Send pointcloud preprocess output message.";
83 }
84
85 return status;
86}
87
88bool PointCloudPreprocessComponent::InitAlgorithmPlugin() {
89 ACHECK(algorithm::SensorManager::Instance()->GetSensorInfo(sensor_name_,
90 &sensor_info_));
91 // pointcloud preprocessor init
92 PointCloudPreprocessorInitOptions preprocessor_init_options;
93 preprocessor_init_options.sensor_name = sensor_name_;
94 preprocessor_init_options.config_path = config_path_;
95 preprocessor_init_options.config_file = config_file_;
96 ACHECK(cloud_preprocessor_->Init(preprocessor_init_options));
97
98 // static transform
99 lidar2world_trans_.Init(lidar2novatel_tf2_child_frame_id_);
100 return true;
101}
102
103bool PointCloudPreprocessComponent::InternalProc(
104 const std::shared_ptr<const drivers::PointCloud>& in_message,
105 const std::shared_ptr<onboard::LidarFrameMessage>& out_message) {
106 uint32_t seq_num = seq_num_.fetch_add(1);
107 const double timestamp = in_message->measurement_time();
108 const double cur_time = Clock::NowInSeconds();
109 const double start_latency = (cur_time - timestamp) * 1e3;
110 AINFO << std::setprecision(16) << "FRAME:Preprocess:Start:msg_time["
111 << timestamp << "]:sensor[" << sensor_name_ << "]:cur_time[" << cur_time
112 << "]:cur_latency[" << start_latency << "]";
113
114 out_message->timestamp_ = timestamp;
115 out_message->lidar_timestamp_ = in_message->header().lidar_timestamp();
116 out_message->seq_num_ = seq_num;
117 out_message->process_stage_ = onboard::ProcessStage::LIDAR_DETECTION;
118 out_message->error_code_ = apollo::common::ErrorCode::OK;
119
120 auto& frame = out_message->lidar_frame_;
122 frame->cloud = base::PointFCloudPool::Instance().Get();
123 frame->timestamp = timestamp;
124 frame->sensor_info = sensor_info_;
125
126 Eigen::Affine3d pose = Eigen::Affine3d::Identity();
127 Eigen::Affine3d pose_novatel = Eigen::Affine3d::Identity();
128 const double lidar_query_tf_timestamp =
129 timestamp - lidar_query_tf_offset_ * 0.001;
130 if (!lidar2world_trans_.GetSensor2worldTrans(lidar_query_tf_timestamp, &pose,
131 &pose_novatel)) {
132 out_message->error_code_ = apollo::common::ErrorCode::PERCEPTION_ERROR_TF;
133 AERROR << "Failed to get pose at time: " << lidar_query_tf_timestamp;
134 return false;
135 }
136
137 frame->lidar2world_pose = pose;
138 frame->novatel2world_pose = pose_novatel;
139 // pointcloud preprocessor
140 PointCloudPreprocessorOptions preprocessor_option;
141 if (!lidar2world_trans_.GetExtrinsics(
142 &preprocessor_option.sensor2novatel_extrinsics)) {
143 AERROR << "Get sensor2novatel extrinsics error.";
144 return false;
145 }
146 frame->lidar2novatel_extrinsics =
147 preprocessor_option.sensor2novatel_extrinsics;
148
149 PERF_BLOCK("cloud_preprocessor")
150 if (!cloud_preprocessor_->Preprocess(
151 preprocessor_option, in_message, frame.get())) {
152 AERROR << "Pointcloud preprocess error.";
153 return false;
154 }
156
157 return true;
158}
159
160} // namespace lidar
161} // namespace perception
162} // namespace apollo
a singleton clock that can be used to get the current timestamp.
Definition clock.h:39
static double NowInSeconds()
gets the current time in second.
Definition clock.cc:56
bool GetProtoConfig(T *config) const
std::shared_ptr< Node > node_
std::shared_ptr< ObjectType > Get() override
virtual bool Init(const PointCloudPreprocessorInitOptions &options=PointCloudPreprocessorInitOptions())=0
Init pointcloud preprocessor
bool Proc(const std::shared_ptr< drivers::PointCloud > &message) override
Process of pointcloud preprocess
bool Init() override
Init pointcloud preprocess component
bool GetSensor2worldTrans(double timestamp, Eigen::Affine3d *sensor2world_trans, Eigen::Affine3d *novatel2world_trans=nullptr)
void Init(const std::string &sensor2novatel_tf2_child_frame_id)
#define ACHECK(cond)
Definition log.h:80
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
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
class register implement
Definition arena_queue.h:37
#define PERF_FUNCTION(...)
Definition profiler.h:54
#define PERF_BLOCK_END
Definition profiler.h:53
#define PERF_BLOCK(...)
Definition profiler.h:52