24#include <boost/algorithm/string.hpp>
25#include <boost/format.hpp>
29#include "absl/strings/str_cat.h"
30#include "yaml-cpp/yaml.h"
47using ::apollo::cyber::Clock;
50FunInfoType LaneDetectionComponent::init_func_arry_[] = {
51 {&LaneDetectionComponent::InitSensorInfo,
"InitSensorInfo"},
52 {&LaneDetectionComponent::InitCameraFrames,
"InitCameraFrames"},
53 {&LaneDetectionComponent::InitProjectMatrix,
"InitProjectMatrix"},
54 {&LaneDetectionComponent::InitMotionService,
"InitMotionService"},
55 {&LaneDetectionComponent::InitCameraListeners,
"InitCameraListeners"}};
57static int GetGpuId(
const camera::CameraPerceptionInitOptions &options) {
58 camera::app::PerceptionParam perception_param;
59 std::string config_file =
62 AERROR <<
"Read config failed: " << config_file;
65 if (!perception_param.has_gpu_id()) {
66 AINFO <<
"gpu id not found.";
69 return perception_param.gpu_id();
72static bool SetCameraHeight(
const std::string &sensor_name,
73 const std::string ¶ms_dir,
74 const std::string &lidar_sensor_name,
75 float default_camera_height,
float *camera_height) {
76 float base_h = default_camera_height;
77 float camera_offset = 0.0f;
79 YAML::Node lidar_height =
80 YAML::LoadFile(params_dir +
"/" + lidar_sensor_name +
"_height.yaml");
81 base_h = lidar_height[
"vehicle"][
"parameters"][
"height"].as<
float>();
83 YAML::Node camera_ex =
84 YAML::LoadFile(params_dir +
"/" + sensor_name +
"_extrinsics.yaml");
85 camera_offset = camera_ex[
"transform"][
"translation"][
"z"].as<
float>();
86 AINFO << camera_offset;
87 *camera_height = base_h + camera_offset;
88 }
catch (YAML::InvalidNode &in) {
89 AERROR <<
"load camera extrisic file error, YAML::InvalidNode exception";
91 }
catch (YAML::TypedBadConversion<float> &bc) {
92 AERROR <<
"load camera extrisic file error, "
93 <<
"YAML::TypedBadConversion exception";
95 }
catch (YAML::Exception &e) {
96 AERROR <<
"load camera extrisic file "
97 <<
" error, YAML exception:" << e.what();
104static bool LoadExtrinsics(
const std::string &yaml_file,
105 Eigen::Matrix4d *camera_extrinsic) {
107 AINFO << yaml_file <<
" not exist!";
110 YAML::Node node = YAML::LoadFile(yaml_file);
120 AINFO <<
"Load " << yaml_file <<
" failed! please check!";
123 qw = node[
"transform"][
"rotation"][
"w"].as<
double>();
124 qx = node[
"transform"][
"rotation"][
"x"].as<
double>();
125 qy = node[
"transform"][
"rotation"][
"y"].as<
double>();
126 qz = node[
"transform"][
"rotation"][
"z"].as<
double>();
127 tx = node[
"transform"][
"translation"][
"x"].as<
double>();
128 ty = node[
"transform"][
"translation"][
"y"].as<
double>();
129 tz = node[
"transform"][
"translation"][
"z"].as<
double>();
130 }
catch (YAML::InvalidNode &in) {
131 AERROR <<
"load camera extrisic file " << yaml_file
132 <<
" with error, YAML::InvalidNode exception";
134 }
catch (YAML::TypedBadConversion<double> &bc) {
135 AERROR <<
"load camera extrisic file " << yaml_file
136 <<
" with error, YAML::TypedBadConversion exception";
138 }
catch (YAML::Exception &e) {
139 AERROR <<
"load camera extrisic file " << yaml_file
140 <<
" with error, YAML exception:" << e.what();
143 camera_extrinsic->setConstant(0);
144 Eigen::Quaterniond q;
149 (*camera_extrinsic).block<3, 3>(0, 0) = q.normalized().toRotationMatrix();
150 (*camera_extrinsic)(0, 3) = tx;
151 (*camera_extrinsic)(1, 3) = ty;
152 (*camera_extrinsic)(2, 3) = tz;
153 (*camera_extrinsic)(3, 3) = 1;
158static bool GetProjectMatrix(
159 const std::vector<std::string> &camera_names,
160 const EigenMap<std::string, Eigen::Matrix4d> &extrinsic_map,
161 const EigenMap<std::string, Eigen::Matrix3f> &intrinsic_map,
162 Eigen::Matrix3d *project_matrix,
double *pitch_diff =
nullptr) {
163 if (camera_names.size() != 2) {
164 AINFO <<
"camera number must be 2!";
168 intrinsic_map.at(camera_names[0]).cast<
double>() *
169 extrinsic_map.at(camera_names[0]).block<3, 3>(0, 0).inverse() *
170 extrinsic_map.at(camera_names[1]).block<3, 3>(0, 0) *
171 intrinsic_map.at(camera_names[1]).cast<
double>().inverse();
173 if (pitch_diff !=
nullptr) {
174 Eigen::Vector3d euler =
175 (extrinsic_map.at(camera_names[0]).block<3, 3>(0, 0).inverse() *
176 extrinsic_map.at(camera_names[1]).block<3, 3>(0, 0))
177 .eulerAngles(0, 1, 2);
178 *pitch_diff = euler(0);
179 AINFO <<
"pitch diff: " << *pitch_diff;
188 AERROR <<
"InitConfig() failed.";
194 LaneDetectionComponent::init_func_arry_)) {
197 SetCameraHeightAndPitch();
204 double pitch_adj_degree = 0.0;
205 double yaw_adj_degree = 0.0;
206 double roll_adj_degree = 0.0;
208 Eigen::Matrix4d ex_lidar2imu;
210 LoadExtrinsics(FLAGS_obs_sensor_intrinsic_path +
"/" +
211 FLAGS_lidar_sensor_name +
"_novatel_extrinsics.yaml",
213 AINFO << FLAGS_lidar_sensor_name +
"_novatel_extrinsics.yaml: "
217 camera_names_, visual_camera_, intrinsic_map_, extrinsic_map_,
218 ex_lidar2imu, pitch_adj_degree, yaw_adj_degree, roll_adj_degree,
219 image_height_, image_width_));
221 camera_lane_pipeline_->SetIm2CarHomography(homography_image2ground_);
223 if (enable_visualization_) {
224 if (write_visual_img_) {
229 AINFO <<
"Init processes all succeed";
234void LaneDetectionComponent::OnMotionService(
235 const MotionServiceMsgType &message) {
240 vehicledata.
roll_rate = message->vehicle_status()[0].roll_rate();
241 vehicledata.
pitch_rate = message->vehicle_status()[0].pitch_rate();
242 vehicledata.
yaw_rate = message->vehicle_status()[0].yaw_rate();
243 vehicledata.
velocity = message->vehicle_status()[0].velocity();
244 vehicledata.
velocity_x = message->vehicle_status()[0].velocity_x();
245 vehicledata.
velocity_y = message->vehicle_status()[0].velocity_y();
246 vehicledata.
velocity_z = message->vehicle_status()[0].velocity_z();
247 vehicledata.
time_ts = message->vehicle_status()[0].time_ts();
248 vehicledata.
time_d = message->vehicle_status()[0].time_d();
251 motion_2d(0, 0) = message->vehicle_status()[0].motion().m00();
252 motion_2d(0, 1) = message->vehicle_status()[0].motion().m01();
253 motion_2d(0, 2) = message->vehicle_status()[0].motion().m02();
254 motion_2d(0, 3) = message->vehicle_status()[0].motion().m03();
255 motion_2d(1, 0) = message->vehicle_status()[0].motion().m10();
256 motion_2d(1, 1) = message->vehicle_status()[0].motion().m11();
257 motion_2d(1, 2) = message->vehicle_status()[0].motion().m12();
258 motion_2d(1, 3) = message->vehicle_status()[0].motion().m13();
259 motion_2d(2, 0) = message->vehicle_status()[0].motion().m20();
260 motion_2d(2, 1) = message->vehicle_status()[0].motion().m21();
261 motion_2d(2, 2) = message->vehicle_status()[0].motion().m22();
262 motion_2d(2, 3) = message->vehicle_status()[0].motion().m23();
263 motion_2d(3, 0) = message->vehicle_status()[0].motion().m30();
264 motion_2d(3, 1) = message->vehicle_status()[0].motion().m31();
265 motion_2d(3, 2) = message->vehicle_status()[0].motion().m32();
266 motion_2d(3, 3) = message->vehicle_status()[0].motion().m33();
267 vehicledata.
motion = motion_2d;
269 mot_buffer_->push_back(vehicledata);
274void LaneDetectionComponent::OnReceiveImage(
275 const std::shared_ptr<apollo::drivers::Image> &message,
276 const std::string &camera_name) {
277 std::lock_guard<std::mutex> lock(mutex_);
278 const double msg_timestamp = message->measurement_time() + timestamp_offset_;
279 AINFO <<
"Enter LaneDetectionComponent::Proc(), camera_name: " << camera_name
280 <<
" image ts: " << msg_timestamp;
282 if (last_timestamp_ - msg_timestamp > ts_diff_) {
283 AINFO <<
"Received an old message. Last ts is " << std::setprecision(19)
284 << last_timestamp_ <<
" current ts is " << msg_timestamp
285 <<
" last - current is " << last_timestamp_ - msg_timestamp;
288 last_timestamp_ = msg_timestamp;
294 const double start_latency = (cur_time - message->measurement_time()) * 1e3;
295 AINFO <<
"FRAME_STATISTICS:Camera:Start:msg_time[" << camera_name <<
"-"
302 std::shared_ptr<apollo::perception::PerceptionLanes> out_message(
307 std::shared_ptr<SensorFrameMessage> prefused_message(
new (std::nothrow)
309 if (InternalProc(message, camera_name, &error_code, prefused_message.get(),
311 AERROR <<
"InternalProc failed, error_code: " << error_code;
318 const double end_latency =
319 (end_timestamp - message->measurement_time()) * 1e3;
320 AINFO <<
"FRAME_STATISTICS:Camera:End:msg_time[" << camera_name <<
"-"
327int LaneDetectionComponent::InitConfig() {
331 AINFO <<
"load lane detection component proto param failed";
335 std::string camera_names_str = lane_detection_param.
camera_names();
336 boost::algorithm::split(camera_names_, camera_names_str,
337 boost::algorithm::is_any_of(
","));
338 if (camera_names_.size() != 2) {
339 AERROR <<
"Now LaneDetectionComponent only support 2 cameras";
343 std::string input_camera_channel_names_str =
345 boost::algorithm::split(input_camera_channel_names_,
346 input_camera_channel_names_str,
347 boost::algorithm::is_any_of(
","));
348 if (input_camera_channel_names_.size() != camera_names_.size()) {
349 AERROR <<
"wrong input_camera_channel_names_.size(): "
350 << input_camera_channel_names_.size();
356 camera_perception_init_options_.
config_path = detection_param.config_path();
357 camera_perception_init_options_.
config_file = detection_param.config_file();
368 default_camera_pitch_ =
370 default_camera_height_ =
372 ts_diff_ = lane_detection_param.
ts_diff();
375 std::string format_str = R
"(
376 LaneDetectionComponent InitConfig success
378 camera_lane_perception_config_path: %s
379 camera_lane_perception_config_file: %s
381 image_channel_num: %d
382 enable_undistortion: %d
383 enable_visualization: %d
384 visual_debug_folder_: %s
386 output_lanes_channel_name: %s
387 write_visual_img_: %s)";
388 std::string config_info_str =
389 str(boost::format(format_str.c_str()) % camera_names_[0] %
390 camera_names_[1] % camera_perception_init_options_.config_path %
391 camera_perception_init_options_.config_file % frame_capacity_ %
392 image_channel_num_ % enable_undistortion_ % enable_visualization_ %
393 visual_debug_folder_ % visual_camera_ % output_lanes_channel_name_ %
395 AINFO << config_info_str;
400int LaneDetectionComponent::InitSensorInfo() {
401 if (camera_names_.size() != 2) {
402 AERROR <<
"invalid camera_names_.size(): " << camera_names_.size();
406 auto *sensor_manager = algorithm::SensorManager::Instance();
407 for (
size_t i = 0; i < camera_names_.size(); ++i) {
408 if (!sensor_manager->IsSensorExist(camera_names_[i])) {
409 AERROR << (
"sensor_name: " + camera_names_[i] +
" not exists.");
413 base::SensorInfo sensor_info;
414 if (!(sensor_manager->GetSensorInfo(camera_names_[i], &sensor_info))) {
415 AERROR <<
"Failed to get sensor info, sensor name: " << camera_names_[i];
418 sensor_info_map_[camera_names_[i]] = sensor_info;
420 std::string tf_camera_frame_id =
421 sensor_manager->GetFrameId(camera_names_[i]);
422 tf_camera_frame_id_map_[camera_names_[i]] = tf_camera_frame_id;
423 std::shared_ptr<TransformWrapper> trans_wrapper(
new TransformWrapper);
424 trans_wrapper->Init(tf_camera_frame_id);
425 camera2world_trans_wrapper_map_[camera_names_[i]] = trans_wrapper;
430 sensor_manager->GetUndistortCameraModel(camera_names_[0]);
431 ACHECK(camera_model_ptr) <<
"Can't find " << camera_names_[0]
432 <<
" in data/conf/sensor_meta.pb.txt";
433 image_width_ =
static_cast<int>(camera_model_ptr->get_width());
434 image_height_ =
static_cast<int>(camera_model_ptr->get_height());
436 std::string format_str = R
"(
438 tf_camera_frame_ids: %s %s
441 image_channel_num: %d)";
442 std::string sensor_info_str =
443 str(boost::format(format_str.c_str()) % camera_names_[0] %
444 camera_names_[1] % tf_camera_frame_id_map_[camera_names_[0]] %
445 tf_camera_frame_id_map_[camera_names_[1]] % image_width_ %
446 image_height_ % image_channel_num_);
447 AINFO << sensor_info_str;
452int LaneDetectionComponent::InitAlgorithmPlugin() {
453 camera_lane_pipeline_.reset(
new camera::LaneCameraPerception);
454 if (!camera_lane_pipeline_->Init(camera_perception_init_options_)) {
455 AERROR <<
"camera_lane_pipeline_->Init() failed";
458 AINFO <<
"camera_lane_pipeline_->Init() succeed";
462int LaneDetectionComponent::InitCameraFrames() {
463 if (camera_names_.size() != 2) {
464 AERROR <<
"invalid camera_names_.size(): " << camera_names_.size();
468 camera_frames_.resize(frame_capacity_);
469 if (camera_frames_.empty()) {
470 AERROR <<
"frame_capacity_ must > 0";
475 for (
const auto &camera_name : camera_names_) {
476 camera::DataProvider::InitOptions data_provider_init_options;
477 data_provider_init_options.image_height = image_height_;
478 data_provider_init_options.image_width = image_width_;
479 data_provider_init_options.do_undistortion = enable_undistortion_;
480 data_provider_init_options.sensor_name = camera_name;
481 int gpu_id = GetGpuId(camera_perception_init_options_);
485 data_provider_init_options.device_id = gpu_id;
486 AINFO <<
"data_provider_init_options.device_id: "
487 << data_provider_init_options.device_id
488 <<
" camera_name: " << camera_name;
490 std::shared_ptr<camera::DataProvider> data_provider(
491 new camera::DataProvider);
492 data_provider->Init(data_provider_init_options);
493 data_providers_map_[camera_name] = data_provider;
497 for (
const auto &camera_name : camera_names_) {
499 model = algorithm::SensorManager::Instance()->GetUndistortCameraModel(
501 ACHECK(model) <<
"Can't find " << camera_name
502 <<
" in data/conf/sensor_meta.pb.txt";
503 auto pinhole =
static_cast<base::PinholeCameraModel *
>(model.get());
504 Eigen::Matrix3f intrinsic = pinhole->get_intrinsic_params();
505 intrinsic_map_[camera_name] = intrinsic;
506 AINFO <<
"#intrinsics of " << camera_name <<
": "
507 << intrinsic_map_[camera_name];
508 Eigen::Matrix4d extrinsic;
510 LoadExtrinsics(FLAGS_obs_sensor_intrinsic_path +
"/" + camera_name +
513 extrinsic_map_[camera_name] = extrinsic;
517 for (
const auto &camera_name : camera_names_) {
520 SetCameraHeight(camera_name, FLAGS_obs_sensor_intrinsic_path,
521 FLAGS_lidar_sensor_name, default_camera_height_, &height);
522 camera_height_map_[camera_name] =
height;
525 for (
auto &frame : camera_frames_) {
526 frame.track_feature_blob.reset(
new base::Blob<float>());
527 frame.lane_detected_blob.reset(
new base::Blob<float>());
532int LaneDetectionComponent::InitProjectMatrix() {
533 if (!GetProjectMatrix(camera_names_, extrinsic_map_, intrinsic_map_,
534 &project_matrix_, &pitch_diff_)) {
535 AERROR <<
"GetProjectMatrix failed";
538 AINFO <<
"project_matrix_: " << project_matrix_;
539 AINFO <<
"pitch_diff_:" << pitch_diff_;
540 name_camera_pitch_angle_diff_map_[camera_names_[0]] = 0.f;
541 name_camera_pitch_angle_diff_map_[camera_names_[1]] =
542 static_cast<float>(pitch_diff_);
547int LaneDetectionComponent::InitMotionService() {
548 const std::string &channel_name_local =
"/apollo/perception/motion_service";
550 std::bind(&LaneDetectionComponent::OnMotionService,
this,
551 std::placeholders::_1);
552 auto motion_service_reader =
553 node_->CreateReader(channel_name_local, motion_service_callback);
555 if (mot_buffer_ ==
nullptr) {
558 mot_buffer_->set_capacity(motion_buffer_size_);
563int LaneDetectionComponent::InitCameraListeners() {
564 for (
size_t i = 0; i < camera_names_.size(); ++i) {
565 const std::string &camera_name = camera_names_[i];
566 const std::string &channel_name = input_camera_channel_names_[i];
567 const std::string &listener_name = camera_name +
"_fusion_camera_listener";
568 AINFO <<
"listener name: " << listener_name;
570 typedef std::shared_ptr<apollo::drivers::Image>
ImageMsgType;
571 std::function<void(
const ImageMsgType &)> camera_callback =
572 std::bind(&LaneDetectionComponent::OnReceiveImage,
this,
573 std::placeholders::_1, camera_name);
574 auto camera_reader =
node_->CreateReader(channel_name, camera_callback);
579void LaneDetectionComponent::SetCameraHeightAndPitch() {
580 camera_lane_pipeline_->SetCameraHeightAndPitch(
581 camera_height_map_, name_camera_pitch_angle_diff_map_,
582 default_camera_pitch_);
585int LaneDetectionComponent::InternalProc(
586 const std::shared_ptr<apollo::drivers::Image const> &in_message,
588 SensorFrameMessage *prefused_message,
590 const double msg_timestamp =
591 in_message->measurement_time() + timestamp_offset_;
592 const int frame_size =
static_cast<int>(camera_frames_.size());
593 camera::CameraFrame &camera_frame = camera_frames_[frame_id_ % frame_size];
595 prefused_message->timestamp_ = msg_timestamp;
596 prefused_message->seq_num_ = seq_num_;
598 prefused_message->sensor_id_ = camera_name;
599 prefused_message->frame_ = base::FramePool::Instance().Get();
600 prefused_message->frame_->sensor_info = sensor_info_map_[camera_name];
601 prefused_message->frame_->timestamp = msg_timestamp;
604 Eigen::Affine3d camera2world_trans;
605 if (!camera2world_trans_wrapper_map_[camera_name]->GetSensor2worldTrans(
606 msg_timestamp, &camera2world_trans)) {
607 const std::string err_str =
608 absl::StrCat(
"failed to get camera to world pose, ts: ", msg_timestamp,
609 " camera_name: ", camera_name);
612 prefused_message->error_code_ = *error_code;
615 Eigen::Affine3d world2camera = camera2world_trans.inverse();
616 prefused_message->frame_->sensor2world_pose = camera2world_trans;
620 camera_frame.camera2world_pose = camera2world_trans;
621 camera_frame.data_provider = data_providers_map_[camera_name].get();
622 camera_frame.data_provider->FillImageData(
623 image_height_, image_width_,
624 reinterpret_cast<const uint8_t *
>(in_message->data().data()),
625 in_message->encoding());
627 camera_frame.frame_id = frame_id_;
628 camera_frame.timestamp = msg_timestamp;
630 if (camera_frame.data_provider->sensor_name() == camera_names_[1]) {
631 camera_frame.project_matrix = project_matrix_;
633 camera_frame.project_matrix.setIdentity();
638 camera_lane_pipeline_->GetCalibrationService(
639 &camera_frame.calibration_service);
641 camera::CameraPerceptionOptions camera_perception_options;
642 if (!camera_lane_pipeline_->Perception(camera_perception_options,
644 AERROR <<
"camera_lane_pipeline_->Perception() failed msg_timestamp: "
647 prefused_message->error_code_ = *error_code;
650 AINFO <<
"##" << camera_name <<
": pitch "
651 << camera_frame.calibration_service->QueryPitchAngle()
652 <<
" | camera_grond_height "
653 << camera_frame.calibration_service->QueryCameraToGroundHeight();
654 prefused_message->frame_->objects = camera_frame.tracked_objects;
657 prefused_message->error_code_ = *error_code;
659 prefused_message->frame_->camera_frame_supplement.on_use =
true;
660 if (FLAGS_obs_enable_visualization) {
661 camera::DataProvider::ImageOptions image_options;
665 prefused_message->frame_->camera_frame_supplement.image_blob.reset(
666 new base::Blob<uint8_t>);
667 camera_frame.data_provider->GetImageBlob(
669 prefused_message->frame_->camera_frame_supplement.image_blob.get());
673 if (enable_visualization_) {
674 camera::DataProvider::ImageOptions image_options;
676 std::shared_ptr<base::Blob<uint8_t>> image_blob(
new base::Blob<uint8_t>);
677 camera_frame.data_provider->GetImageBlob(image_options, image_blob.get());
679 cv::Mat output_image(image_height_, image_width_, CV_8UC3,
680 cv::Scalar(0, 0, 0));
682 camera_frame.data_provider->GetImage(image_options, &out_image);
683 memcpy(output_image.data, out_image.cpu_data(),
684 out_image.total() *
sizeof(uint8_t));
686 mot_buffer_, world2camera);
691 std::shared_ptr<apollo::perception::PerceptionLanes> lanes_msg(
693 if (MakeProtobufMsg(msg_timestamp, camera_name, camera_frame,
695 AERROR <<
"make lanes_msg failed";
698 writer_->Write(lanes_msg);
703int LaneDetectionComponent::ConvertLaneToCameraLaneline(
704 const base::LaneLine &lane_line,
705 apollo::perception::camera::CameraLaneLine *camera_laneline) {
706 if (camera_laneline ==
nullptr) {
707 AERROR <<
"camera_laneline is not available";
711 apollo::perception::camera::LaneLineType line_type =
712 static_cast<apollo::perception::camera::LaneLineType
>(lane_line.type);
713 camera_laneline->set_type(line_type);
714 apollo::perception::camera::LaneLinePositionType pos_type =
715 static_cast<apollo::perception::camera::LaneLinePositionType
>(
717 camera_laneline->set_pos_type(pos_type);
718 camera_laneline->set_track_id(lane_line.track_id);
719 camera_laneline->set_confidence(lane_line.confidence);
720 apollo::perception::camera::LaneLineUseType use_type =
721 static_cast<apollo::perception::camera::LaneLineUseType
>(
723 camera_laneline->set_use_type(use_type);
725 camera_laneline->mutable_curve_camera_coord()->set_longitude_min(
726 lane_line.curve_camera_coord.x_start);
727 camera_laneline->mutable_curve_camera_coord()->set_longitude_max(
728 lane_line.curve_camera_coord.x_end);
729 camera_laneline->mutable_curve_camera_coord()->set_a(
730 lane_line.curve_camera_coord.a);
731 camera_laneline->mutable_curve_camera_coord()->set_b(
732 lane_line.curve_camera_coord.b);
733 camera_laneline->mutable_curve_camera_coord()->set_c(
734 lane_line.curve_camera_coord.c);
735 camera_laneline->mutable_curve_camera_coord()->set_d(
736 lane_line.curve_camera_coord.d);
738 camera_laneline->mutable_curve_image_coord()->set_longitude_min(
739 lane_line.curve_image_coord.x_start);
740 camera_laneline->mutable_curve_image_coord()->set_longitude_max(
741 lane_line.curve_image_coord.x_end);
742 camera_laneline->mutable_curve_image_coord()->set_a(
743 lane_line.curve_image_coord.a);
744 camera_laneline->mutable_curve_image_coord()->set_b(
745 lane_line.curve_image_coord.b);
746 camera_laneline->mutable_curve_image_coord()->set_c(
747 lane_line.curve_image_coord.c);
748 camera_laneline->mutable_curve_image_coord()->set_d(
749 lane_line.curve_image_coord.d);
751 for (
size_t i = 0; i < lane_line.curve_image_point_set.size(); i++) {
752 const base::Point2DF &image_point2d = lane_line.curve_image_point_set[i];
754 camera_laneline->add_curve_image_point_set();
755 lane_point_2d->set_x(image_point2d.x);
756 lane_point_2d->set_y(image_point2d.y);
759 for (
size_t i = 0; i < lane_line.curve_camera_point_set.size(); i++) {
760 const base::Point3DF &point3d = lane_line.curve_camera_point_set[i];
762 camera_laneline->add_curve_camera_point_set();
763 lane_point_3d->set_x(point3d.x);
764 lane_point_3d->set_y(point3d.y);
765 lane_point_3d->set_z(point3d.z);
768 for (
size_t i = 0; i < lane_line.image_end_point_set.size(); i++) {
769 const base::EndPoints &end_points = lane_line.image_end_point_set[i];
770 apollo::perception::camera::EndPoints *lane_end_points =
771 camera_laneline->add_image_end_point_set();
772 lane_end_points->mutable_start()->set_x(end_points.start.x);
773 lane_end_points->mutable_start()->set_y(end_points.start.y);
774 lane_end_points->mutable_end()->set_x(end_points.end.x);
775 lane_end_points->mutable_end()->set_y(end_points.end.y);
780int LaneDetectionComponent::MakeProtobufMsg(
781 double msg_timestamp,
const std::string &camera_name,
782 const camera::CameraFrame &camera_frame,
784 if (lanes_msg ==
nullptr) {
785 AERROR <<
"lanes_msg is not available";
788 auto itr = std::find(camera_names_.begin(), camera_names_.end(), camera_name);
789 if (itr == camera_names_.end()) {
790 AERROR <<
"invalid camera_name: " << camera_name;
793 int input_camera_channel_names_idx =
794 static_cast<int>(itr - camera_names_.begin());
795 int input_camera_channel_names_size =
796 static_cast<int>(input_camera_channel_names_.size());
797 if (input_camera_channel_names_idx < 0 ||
798 input_camera_channel_names_idx >= input_camera_channel_names_size) {
799 AERROR <<
"invalid input_camera_channel_names_idx: "
800 << input_camera_channel_names_idx
801 <<
" input_camera_channel_names_.size(): "
802 << input_camera_channel_names_.size();
805 std::string source_channel_name =
806 input_camera_channel_names_[input_camera_channel_names_idx];
807 lanes_msg->set_source_topic(source_channel_name);
811 header->set_camera_timestamp(
static_cast<uint64_t
>(msg_timestamp * 1.0e9));
814 const std::vector<base::LaneLine> &lane_objects = camera_frame.lane_objects;
815 for (
const auto &lane_obj : lane_objects) {
816 apollo::perception::camera::CameraLaneLine *camera_laneline =
817 lanes_msg->add_camera_laneline();
818 ConvertLaneToCameraLaneline(lane_obj, camera_laneline);
822 float pitch_angle = camera_frame.calibration_service->QueryPitchAngle();
823 lanes_msg->mutable_camera_calibrator()->set_pitch_angle(pitch_angle);
static double NowInSeconds()
gets the current time in second.
bool GetProtoConfig(T *config) const
std::shared_ptr< Node > node_
bool SetDirectory(const std::string &path)
Eigen::Matrix3d homography_im2car(std::string camera_name)
bool Init_all_info_single_camera(const std::vector< std::string > &camera_names, const std::string &visual_camera, const EigenMap< std::string, Eigen::Matrix3f > &intrinsic_map, const EigenMap< std::string, Eigen::Matrix4d > &extrinsic_map, const Eigen::Matrix4d &ex_lidar2imu, const double pitch_adj, const double yaw_adj, const double roll_adj, const int image_height, const int image_width)
void ShowResult_all_info_single_camera(const cv::Mat &img, const CameraFrame &frame, const base::MotionBufferPtr motion_buffer, const Eigen::Affine3d &world2camera)
std::shared_ptr< apollo::perception::MotionService > MotionServiceMsgType
~LaneDetectionComponent()
Math-related util functions.
#define EXEC_ALL_FUNS(type, obj, list)
std::map< T, EigenType, std::less< T >, Eigen::aligned_allocator< std::pair< const T, EigenType > > > EigenMap
@ PERCEPTION_ERROR_PROCESS
bool PathExists(const std::string &path)
Check if the path exists.
bool GetProtoFromFile(const std::string &file_name, google::protobuf::Message *message)
Parses the content of the file specified by the file_name as a representation of protobufs,...
std::string GetAbsolutePath(const std::string &prefix, const std::string &relative_path)
Get absolute path by concatenating prefix and relative_path.
uint32_t height
Height of point cloud
boost::circular_buffer< VehicleStatus > MotionBuffer
std::shared_ptr< BaseCameraModel > BaseCameraModelPtr
Point3D< float > Point3DF
Point2D< float > Point2DF
Eigen::Matrix4f MotionType
std::shared_ptr< apollo::drivers::Image > ImageMsgType
@ MONOCULAR_CAMERA_DETECTION
FunctionInfo< LaneDetectionComponent > FunInfoType
Some string util functions.
#define FORMAT_TIMESTAMP(timestamp)
std::string lane_calibration_working_sensor_name
optional string output_lanes_channel_name
optional bool enable_visualization
optional bool enable_undistortion
optional string camera_names
optional int32 frame_capacity
optional bool write_visual_img
optional string visual_debug_folder
optional string lane_calibration_working_sensor_name
optional string visual_camera
optional int32 image_channel_num
optional double default_camera_height
optional string input_camera_channel_names
optional double default_camera_pitch
optional PluginParam detection_param