Apollo 11.0
自动驾驶开放平台
camera_detection_bev_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
18#include <string>
19
20#include "cyber/common/file.h"
21#include "cyber/common/log.h"
22#include "cyber/time/clock.h"
25
26namespace apollo {
27namespace perception {
28namespace camera {
29
30bool CameraDetectionBevComponent::InitDetector(
31 const CameraDetectionBEV &detection_param) {
32 ObstacleDetectorInitOptions init_options;
33 // Init conf file
34 auto plugin_param = detection_param.plugin_param();
35 init_options.config_path = plugin_param.config_path();
36 init_options.config_file = plugin_param.config_file();
37 init_options.gpu_id = detection_param.gpu_id();
38
39 // Init camera params
40 std::string camera_name = detection_param.camera_name();
42 algorithm::SensorManager::Instance()->GetUndistortCameraModel(
43 camera_name);
44 ACHECK(model) << "Can't find " << camera_name
45 << " in data/conf/sensor_meta.pb.txt";
46 auto pinhole = static_cast<base::PinholeCameraModel *>(model.get());
47 init_options.intrinsic = pinhole->get_intrinsic_params();
48 init_options.image_height = model->get_height();
49 init_options.image_width = model->get_width();
50 image_height_ = model->get_height();
51 image_width_ = model->get_width();
52
53 // Init detector
54 detector_.reset(
55 BaseObstacleDetectorRegisterer::GetInstanceByName(plugin_param.name()));
56 detector_->Init(init_options);
57 return true;
58}
59
60bool CameraDetectionBevComponent::InitCameraFrame(
61 const CameraDetectionBEV &detection_param) {
62 DataProvider::InitOptions init_options;
63 init_options.image_height = image_height_;
64 init_options.image_width = image_width_;
65 init_options.do_undistortion = detection_param.enable_undistortion();
66 init_options.sensor_name = detection_param.camera_name();
67 init_options.device_id = detection_param.gpu_id();
68 AINFO << "init_options.device_id: " << init_options.device_id
69 << " camera_name: " << init_options.sensor_name;
70
71 frame_ptr_ = std::make_shared<CameraFrame>();
72 int num = 6;
73 frame_ptr_->data_provider.resize(num);
74 for (int i = 0; i < num; ++i) {
75 frame_ptr_->data_provider[i] = std::make_shared<DataProvider>();
76 frame_ptr_->data_provider[i]->Init(init_options);
77 }
78 return true;
79}
80
81bool CameraDetectionBevComponent::InitListeners(
82 const CameraDetectionBEV &detection_param) {
83 for (const auto &channel :
84 detection_param.channel().input_camera_channel_name()) {
85 std::shared_ptr<cyber::Reader<drivers::Image>> reader;
86 if (channel == "/apollo/sensor/camera/CAM_BACK/image") {
87 reader = node_->CreateReader<drivers::Image>(
88 channel, [&](const std::shared_ptr<drivers::Image> &msg) {
89 OnReceiveImage(msg);
90 });
91 } else {
92 reader = node_->CreateReader<drivers::Image>(channel);
93 }
94 readers_.emplace_back(reader);
95 }
96 return true;
97}
98
99bool CameraDetectionBevComponent::InitTransformWrapper(
100 const CameraDetectionBEV &detection_param) {
101 trans_wrapper_.reset(new onboard::TransformWrapper());
102 // tf_camera_frame_id
103 trans_wrapper_->Init(detection_param.frame_id());
104 return true;
105}
106
108 CameraDetectionBEV detection_param;
109 if (!GetProtoConfig(&detection_param)) {
110 AERROR << "Load camera detection 3d component config failed!";
111 return false;
112 }
113
114 // todo(zero): need init image_height_\image_width_
115 InitDetector(detection_param);
116 InitCameraFrame(detection_param);
117 InitListeners(detection_param);
118 InitTransformWrapper(detection_param);
119
120 writer_ = node_->CreateWriter<PerceptionObstacles>(
121 detection_param.channel().output_obstacles_channel_name());
122 return true;
123}
124
125void CameraDetectionBevComponent::CameraToWorldCoor(
126 const Eigen::Affine3d &camera2world, std::vector<base::ObjectPtr> *objs) {
127 for (auto &obj : *objs) {
128 Eigen::Vector3d local_center =
129 obj->camera_supplement.local_center.cast<double>();
130 obj->center = camera2world * local_center;
131
132 obj->direction = camera2world.linear().cast<float>() * obj->direction;
133 obj->theta = std::atan2(obj->direction(1), obj->direction(0));
134 }
135}
136
137int CameraDetectionBevComponent::ConvertObjectToPb(
138 const base::ObjectPtr &object_ptr, PerceptionObstacle *pb_msg) {
139 if (!object_ptr || !pb_msg) {
140 return cyber::FAIL;
141 }
142 pb_msg->set_id(object_ptr->track_id);
143
144 apollo::common::Point3D *obj_center = pb_msg->mutable_position();
145 obj_center->set_x(object_ptr->center(0));
146 obj_center->set_y(object_ptr->center(1));
147 obj_center->set_z(object_ptr->center(2));
148
149 pb_msg->set_length(object_ptr->size(0));
150 pb_msg->set_width(object_ptr->size(1));
151 pb_msg->set_height(object_ptr->size(2));
152
153 pb_msg->set_theta(object_ptr->theta);
154
155 // for camera results, set object's center as anchor point
156 pb_msg->set_type(static_cast<PerceptionObstacle::Type>(object_ptr->type));
157 pb_msg->set_sub_type(
158 static_cast<PerceptionObstacle::SubType>(object_ptr->sub_type));
159 pb_msg->set_timestamp(object_ptr->latest_tracked_time); // in seconds.
160
161 pb_msg->set_height_above_ground(object_ptr->size(2));
162
163 return cyber::SUCC;
164}
165
166int CameraDetectionBevComponent::MakeProtobufMsg(
167 double msg_timestamp, int seq_num,
168 const std::vector<base::ObjectPtr> &objects,
169 PerceptionObstacles *obstacles) {
170 double publish_time = apollo::cyber::Clock::NowInSeconds();
171 auto header = obstacles->mutable_header();
172 header->set_timestamp_sec(publish_time);
173 header->set_module_name("perception_camera");
174 header->set_sequence_num(seq_num);
175 // in nanosecond
176 // PnC would use lidar timestamp to predict
177 header->set_lidar_timestamp(static_cast<uint64_t>(msg_timestamp * 1e9));
178 header->set_camera_timestamp(static_cast<uint64_t>(msg_timestamp * 1e9));
179
180 // write out obstacles in world coordinates
181 int count = 0;
182 for (const auto &obj : objects) {
183 obj->track_id = count++;
184 PerceptionObstacle *obstacle = obstacles->add_perception_obstacle();
185 if (ConvertObjectToPb(obj, obstacle) != cyber::SUCC) {
186 AERROR << "ConvertObjectToPb failed, Object:" << obj->ToString();
187 return cyber::FAIL;
188 }
189 }
190
191 return cyber::SUCC;
192}
193
194bool CameraDetectionBevComponent::OnReceiveImage(
195 const std::shared_ptr<drivers::Image> &msg) {
196 const double msg_timestamp = msg->measurement_time() + timestamp_offset_;
197
198 for (size_t i = 0; i < readers_.size(); ++i) {
199 readers_[i]->Observe();
200 const auto &camera_msg = readers_[i]->GetLatestObserved();
201 if (camera_msg == nullptr) {
202 return false;
203 }
204 frame_ptr_->data_provider[i]->FillImageData(
205 image_height_, image_width_,
206 reinterpret_cast<const uint8_t *>(camera_msg->data().data()),
207 camera_msg->encoding());
208 }
209
210 frame_ptr_->timestamp = msg_timestamp;
211 ++frame_ptr_->frame_id;
212
213 // Detect
214 detector_->Detect(frame_ptr_.get());
215
216 // Get sensor to world pose from TF
217 Eigen::Affine3d lidar2world_trans;
218 if (!trans_wrapper_->GetSensor2worldTrans(msg_timestamp,
219 &lidar2world_trans)) {
220 const std::string err_str =
221 absl::StrCat("failed to get camera to world pose, ts: ", msg_timestamp,
222 " camera_name: ", msg->frame_id());
223 AERROR << err_str;
224 }
225
226 CameraToWorldCoor(lidar2world_trans, &frame_ptr_->detected_objects);
227
228 std::shared_ptr<PerceptionObstacles> out_message(new (std::nothrow)
230 if (MakeProtobufMsg(msg_timestamp, seq_num_, frame_ptr_->detected_objects,
231 out_message.get()) != cyber::SUCC) {
232 AERROR << "MakeProtobufMsg failed ts: " << msg_timestamp;
233 return false;
234 }
235 seq_num_++;
236 // Send msg
237 writer_->Write(out_message);
238
239 return true;
240}
241
242} // namespace camera
243} // namespace perception
244} // 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 Init() override
Init for camera detection 2d compoment
#define ACHECK(cond)
Definition log.h:80
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
std::shared_ptr< BaseCameraModel > BaseCameraModelPtr
Definition camera.h:75
std::shared_ptr< Object > ObjectPtr
Definition object.h:127
class register implement
Definition arena_queue.h:37