Apollo 11.0
自动驾驶开放平台
multi_sensor_fusion_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 *****************************************************************************/
17
19#include "cyber/time/clock.h"
24
25namespace apollo {
26namespace perception {
27namespace fusion {
28
29uint32_t MultiSensorFusionComponent::s_seq_num_ = 0;
30std::mutex MultiSensorFusionComponent::s_mutex_;
31
33 FusionComponentConfig comp_config;
34 if (!GetProtoConfig(&comp_config)) {
35 return false;
36 }
37 AINFO << "Fusion Component Configs: " << comp_config.DebugString();
38
39 // to load component configs
40 object_in_roi_check_ = comp_config.object_in_roi_check();
41 radius_for_roi_object_check_ = comp_config.radius_for_roi_object_check();
42
43 // init algorithm plugin
44 ACHECK(InitAlgorithmPlugin(comp_config))
45 << "Failed to init algorithm plugin.";
46
47 writer_ = node_->CreateWriter<PerceptionObstacles>(
48 comp_config.output_obstacles_channel_name());
49 inner_writer_ = node_->CreateWriter<SensorFrameMessage>(
51
52 algorithm::SensorManager::Instance()->Init();
53 return true;
54}
55
57 const std::shared_ptr<SensorFrameMessage>& message) {
59 if (message->process_stage_ == onboard::ProcessStage::SENSOR_FUSION) {
60 return true;
61 }
62 std::shared_ptr<PerceptionObstacles> out_message(new (std::nothrow)
64 std::shared_ptr<SensorFrameMessage> viz_message(new (std::nothrow)
66 bool status = InternalProc(message, out_message, viz_message);
67 if (status) {
68 // TODO(conver sensor id)
69 bool is_main_sensor =
70 algorithm::SensorManager::Instance()->IsMainSensor(message->sensor_id_);
71 if (is_main_sensor) {
72 writer_->Write(out_message);
73 AINFO << "Send fusion processing output message.";
74 // send msg for visualization
75 if (onboard::FLAGS_obs_enable_visualization) {
76 inner_writer_->Write(viz_message);
77 }
78 } else {
79 AINFO << "Fusion receive from " << message->sensor_id_
80 << ". Skip because it is not the main sensor.";
81 }
82 }
83 return status;
84}
85
86bool MultiSensorFusionComponent::InitAlgorithmPlugin(
87 const FusionComponentConfig& config) {
88 auto fusion_param = config.fusion_param();
89 FusionInitOptions init_options;
90 init_options.config_path = fusion_param.config_path();
91 init_options.config_file = fusion_param.config_file();
92 BaseFusionSystem* fusion =
93 BaseFusionSystemRegisterer::GetInstanceByName(fusion_param.name());
94 CHECK_NOTNULL(fusion);
95 fusion_.reset(fusion);
96 ACHECK(fusion_->Init(init_options)) << "Failed to init ProbabilisticFusion";
97
98 if (onboard::FLAGS_obs_enable_hdmap_input && object_in_roi_check_) {
99 hdmap_input_ = map::HDMapInput::Instance();
100 ACHECK(hdmap_input_->Init()) << "Failed to init hdmap input.";
101 }
102 AINFO << "Init algorithm successfully, onboard fusion: "
103 << fusion_param.name();
104 return true;
105}
106
107bool MultiSensorFusionComponent::InternalProc(
108 const std::shared_ptr<SensorFrameMessage const>& in_message,
109 std::shared_ptr<PerceptionObstacles> out_message,
110 std::shared_ptr<SensorFrameMessage> viz_message) {
111 {
112 std::unique_lock<std::mutex> lock(s_mutex_);
113 s_seq_num_++;
114 }
115
116 PERF_BLOCK("fusion_process")
117 const double timestamp = in_message->timestamp_;
118 const uint64_t lidar_timestamp = in_message->lidar_timestamp_;
119 std::vector<base::ObjectPtr> valid_objects;
120 if (in_message->error_code_ != apollo::common::ErrorCode::OK) {
122 timestamp, lidar_timestamp, in_message->seq_num_, valid_objects,
123 in_message->error_code_, out_message.get())) {
124 AERROR << "Failed to gen PerceptionObstacles object.";
125 return false;
126 }
127 if (onboard::FLAGS_obs_enable_visualization) {
128 viz_message->process_stage_ = onboard::ProcessStage::SENSOR_FUSION;
129 viz_message->error_code_ = in_message->error_code_;
130 }
131 AERROR << "Fusion receive message with error code, skip it.";
132 return true;
133 }
134 base::FramePtr frame = in_message->frame_;
135 frame->timestamp = in_message->timestamp_;
136
137 std::vector<base::ObjectPtr> fused_objects;
138 if (!fusion_->Fuse(frame, &fused_objects)) {
139 AERROR << "Failed to call fusion plugin.";
140 return false;
141 }
143
144 bool is_main_sensor = algorithm::SensorManager::Instance()->IsMainSensor(
145 in_message->sensor_id_);
146 if (!is_main_sensor) {
147 return true;
148 }
149
150 PERF_BLOCK("fusion_roi_check")
151 Eigen::Matrix4d sensor2world_pose =
152 in_message->frame_->sensor2world_pose.matrix();
153 if (object_in_roi_check_ && onboard::FLAGS_obs_enable_hdmap_input) {
154 // get hdmap
155 base::HdmapStructPtr hdmap(new base::HdmapStruct());
156 if (hdmap_input_) {
157 base::PointD position;
158 position.x = sensor2world_pose(0, 3);
159 position.y = sensor2world_pose(1, 3);
160 position.z = sensor2world_pose(2, 3);
161 hdmap_input_->GetRoiHDMapStruct(position, radius_for_roi_object_check_,
162 hdmap);
163 // TODO(use check)
164 // ObjectInRoiSlackCheck(hdmap, fused_objects, &valid_objects);
165 valid_objects.assign(fused_objects.begin(), fused_objects.end());
166 } else {
167 valid_objects.assign(fused_objects.begin(), fused_objects.end());
168 }
169 } else {
170 valid_objects.assign(fused_objects.begin(), fused_objects.end());
171 }
173
174 PERF_BLOCK("fusion_serialize_message")
175 // produce visualization msg
176 if (onboard::FLAGS_obs_enable_visualization) {
177 viz_message->timestamp_ = in_message->timestamp_;
178 viz_message->seq_num_ = in_message->seq_num_;
179 viz_message->frame_ = base::FramePool::Instance().Get();
180 viz_message->frame_->sensor2world_pose =
181 in_message->frame_->sensor2world_pose;
182 viz_message->sensor_id_ = in_message->sensor_id_;
183 viz_message->hdmap_ = in_message->hdmap_;
184 viz_message->process_stage_ = onboard::ProcessStage::SENSOR_FUSION;
185 viz_message->error_code_ = in_message->error_code_;
186 viz_message->frame_->objects = fused_objects;
187 }
188 // produce pb output msg
190 if (!onboard::MsgSerializer::SerializeMsg(timestamp, lidar_timestamp,
191 in_message->seq_num_, valid_objects,
192 error_code, out_message.get())) {
193 AERROR << "Failed to gen PerceptionObstacles object.";
194 return false;
195 }
197
198 const double cur_time = ::apollo::cyber::Clock::NowInSeconds();
199 const double latency = (cur_time - timestamp) * 1e3;
200 AINFO << std::setprecision(16) << "FRAME_STATISTICS:Obstacle:End:msg_time["
201 << timestamp << "]:cur_time[" << cur_time << "]:cur_latency[" << latency
202 << "]:obj_cnt[" << valid_objects.size() << "]";
203 AINFO << "publish_number: " << valid_objects.size() << " obj";
204 return true;
205}
206
207} // namespace fusion
208} // namespace perception
209} // namespace apollo
static double NowInSeconds()
gets the current time in second.
Definition clock.cc:56
bool GetProtoConfig(T *config) const
std::shared_ptr< Node > node_
bool Proc(const std::shared_ptr< SensorFrameMessage > &message) override
bool GetRoiHDMapStruct(const base::PointD &pointd, const double distance, std::shared_ptr< base::HdmapStruct > hdmap_struct_prt)
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)
#define ACHECK(cond)
Definition log.h:80
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
std::shared_ptr< HdmapStruct > HdmapStructPtr
Point< double > PointD
Definition point.h:57
std::shared_ptr< Frame > FramePtr
Definition frame.h:60
class register implement
Definition arena_queue.h:37
Definition future.h:29
#define PERF_FUNCTION(...)
Definition profiler.h:54
#define PERF_BLOCK_END
Definition profiler.h:53
#define PERF_BLOCK(...)
Definition profiler.h:52