Apollo 11.0
自动驾驶开放平台
motion_service_component.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2019 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 <limits>
19#include <string>
20#include <unordered_map>
21
22#include <boost/algorithm/string.hpp>
23#include <boost/format.hpp>
24
25#include "cyber/common/log.h"
28
29namespace apollo {
30namespace perception {
31namespace camera {
32
34 AINFO << "start to init MotionService.";
35 vehicle_planemotion_ = new PlaneMotion(motion_buffer_size_);
36
37 // the macro READ_CONF would return cyber::FAIL if config not exists
39 if (!GetProtoConfig(&motion_service_param)) {
40 AINFO << "load lane detection component proto param failed";
41 return false;
42 }
43
44 std::string camera_names_str = motion_service_param.camera_names();
45 boost::algorithm::split(camera_names_, camera_names_str,
46 boost::algorithm::is_any_of(","));
47
48 std::string input_camera_channel_names_str =
49 motion_service_param.input_camera_channel_names();
50 boost::algorithm::split(input_camera_channel_names_,
51 input_camera_channel_names_str,
52 boost::algorithm::is_any_of(","));
53 if (input_camera_channel_names_.size() != camera_names_.size()) {
54 AERROR << "wrong input_camera_channel_names_.size(): "
55 << input_camera_channel_names_.size();
56 return cyber::FAIL;
57 }
58
59 // initialize image listener
60 const std::string &channel_name_img = input_camera_channel_names_[0];
61 const std::string &camera_name = camera_names_[0];
62 std::function<void(const ImageMsgType &)> camera_callback =
63 std::bind(&MotionServiceComponent::OnReceiveImage, this,
64 std::placeholders::_1, camera_name);
65 auto camera_reader = node_->CreateReader(channel_name_img, camera_callback);
66
67 // initialize localization listener
68 const std::string &channel_name_local =
69 motion_service_param.input_localization_channel_name();
70 std::function<void(const LocalizationMsgType &)> localization_callback =
71 std::bind(&MotionServiceComponent::OnLocalization, this,
72 std::placeholders::_1);
73 auto localization_reader =
74 node_->CreateReader(channel_name_local, localization_callback);
75
76 // initialize writer to output channel
77 writer_ = node_->CreateWriter<MotionService>(
78 motion_service_param.output_topic_channel_name());
79 AINFO << "init MotionService success.";
80 return true;
81}
82
83// On receiving image input, just need to record its timestamp
84void MotionServiceComponent::OnReceiveImage(const ImageMsgType &message,
85 const std::string &camera_name) {
86 std::lock_guard<std::mutex> lock(mutex_);
87 const double curr_timestamp = message->measurement_time() + timestamp_offset_;
88 ADEBUG << "image received: camera_name: " << camera_name
89 << " image ts: " << curr_timestamp;
90 camera_timestamp_ = curr_timestamp;
91}
92
93// On reveiving localization input, register it to camera timestamp,
94// compute motion between camera time stamps
95void MotionServiceComponent::OnLocalization(
96 const LocalizationMsgType &message) {
97 std::lock_guard<std::mutex> lock(mutex_);
98 ADEBUG << "localization received: localization ts: "
99 << message->measurement_time();
100 const auto &velocity = message->pose().linear_velocity();
101 // Get base::VehicleStatus
102 base::VehicleStatus vehicle_status;
103 float velx = static_cast<float>(velocity.x());
104 float vely = static_cast<float>(velocity.y());
105 float velz = static_cast<float>(velocity.z());
106 vehicle_status.velocity =
107 static_cast<float>(sqrt(velx * velx + vely * vely + velz * velz));
108 vehicle_status.velocity_x = velx;
109 vehicle_status.velocity_y = vely;
110 vehicle_status.velocity_z = velz;
111 double timestamp_diff = 0;
112 if (!start_flag_) {
113 start_flag_ = true;
114 vehicle_status.yaw_rate = 0;
115 timestamp_diff = 0;
116 vehicle_status.time_d = 0;
117 vehicle_status.time_ts = 0;
118
119 } else {
120 vehicle_status.roll_rate =
121 static_cast<float>(message->pose().angular_velocity_vrf().y());
122 vehicle_status.pitch_rate =
123 static_cast<float>(-message->pose().angular_velocity_vrf().x());
124 vehicle_status.yaw_rate =
125 static_cast<float>(message->pose().angular_velocity_vrf().z());
126 timestamp_diff = message->measurement_time() - pre_timestamp_;
127 vehicle_status.time_d = timestamp_diff;
128 vehicle_status.time_ts = message->measurement_time();
129 }
130
131 pre_timestamp_ = message->measurement_time();
132
133 // add motion to buffer
134 // double camera_timestamp = camera_shared_data_->GetLatestTimestamp();
135 double camera_timestamp = 0;
136 camera_timestamp = camera_timestamp_;
137 ADEBUG << "motion processed for camera timestamp: " << camera_timestamp;
138
139 if (start_flag_) {
140 if (std::abs(camera_timestamp - pre_camera_timestamp_) <
141 std::numeric_limits<double>::epsilon()) {
142 ADEBUG << "Motion_status: accum";
143 vehicle_planemotion_->add_new_motion(
144 pre_camera_timestamp_, camera_timestamp, PlaneMotion::ACCUM_MOTION,
145 &vehicle_status);
146 } else if (camera_timestamp > pre_camera_timestamp_) {
147 ADEBUG << "Motion_status: accum_push";
148 vehicle_planemotion_->add_new_motion(
149 pre_camera_timestamp_, camera_timestamp,
150 PlaneMotion::ACCUM_PUSH_MOTION, &vehicle_status);
151 PublishEvent(camera_timestamp);
152 } else {
153 ADEBUG << "Motion_status: pop";
154 vehicle_planemotion_->add_new_motion(pre_camera_timestamp_,
155 camera_timestamp, PlaneMotion::RESET,
156 &vehicle_status);
157 }
158 }
159
160 pre_camera_timestamp_ = camera_timestamp;
161}
162
163// pubulish vehicle status buffer to output channel
164// which is at camera timestamp
165void MotionServiceComponent::PublishEvent(const double timestamp) {
166 // protobuf msg
167 std::shared_ptr<apollo::perception::MotionService> motion_service_msg(
168 new (std::nothrow) apollo::perception::MotionService);
169 apollo::common::Header *header = motion_service_msg->mutable_header();
170
171 // output camera_time when motion service last proceesed
172 header->set_timestamp_sec(timestamp);
173 header->set_module_name("motion_service");
174
175 // convert vehicle status buffer to output message
176 auto motion_buffer = GetMotionBuffer();
177 for (int k = static_cast<int>(motion_buffer.size()) - 1; k >= 0; k--) {
179 motion_service_msg->add_vehicle_status();
180 ConvertVehicleMotionToMsgOut(motion_buffer.at(k), v_status_msg);
181 }
182 writer_->Write(motion_service_msg);
183}
184
185// convert vehicle status buffer to output message
186void MotionServiceComponent::ConvertVehicleMotionToMsgOut(
187 base::VehicleStatus vs, apollo::perception::VehicleStatus *v_status_msg) {
188 v_status_msg->set_roll_rate(vs.roll_rate);
189 v_status_msg->set_pitch_rate(vs.pitch_rate);
190 v_status_msg->set_yaw_rate(vs.yaw_rate);
191 v_status_msg->set_velocity(vs.velocity);
192 v_status_msg->set_velocity_x(vs.velocity_x);
193 v_status_msg->set_velocity_y(vs.velocity_y);
194 v_status_msg->set_velocity_z(vs.velocity_z);
195 v_status_msg->set_time_ts(vs.time_ts);
196 v_status_msg->set_time_d(vs.time_d);
197 apollo::perception::MotionType *motion_msg = v_status_msg->mutable_motion();
198 motion_msg->set_m00(vs.motion(0, 0));
199 motion_msg->set_m01(vs.motion(0, 1));
200 motion_msg->set_m02(vs.motion(0, 2));
201 motion_msg->set_m03(vs.motion(0, 3));
202 motion_msg->set_m10(vs.motion(1, 0));
203 motion_msg->set_m11(vs.motion(1, 1));
204 motion_msg->set_m12(vs.motion(1, 2));
205 motion_msg->set_m13(vs.motion(1, 3));
206 motion_msg->set_m20(vs.motion(2, 0));
207 motion_msg->set_m21(vs.motion(2, 1));
208 motion_msg->set_m22(vs.motion(2, 2));
209 motion_msg->set_m23(vs.motion(2, 3));
210 motion_msg->set_m30(vs.motion(3, 0));
211 motion_msg->set_m31(vs.motion(3, 1));
212 motion_msg->set_m32(vs.motion(3, 2));
213 motion_msg->set_m33(vs.motion(3, 3));
214}
215
216// load vehicle status buffer from vehicle_planemotion_
218 std::lock_guard<std::mutex> lock(motion_mutex_);
219 return vehicle_planemotion_->get_buffer();
220}
221
223 return pre_camera_timestamp_;
224}
225
226// retrieve vehiclestattus at the closeset cameratimestamp
229 return vehicle_planemotion_->find_motion_with_timestamp(timestamp, vs);
230}
231
232} // namespace camera
233} // namespace perception
234} // namespace apollo
bool GetProtoConfig(T *config) const
std::shared_ptr< Node > node_
bool GetMotionInformation(double timestamp, base::VehicleStatus *vs)
bool find_motion_with_timestamp(double timestamp, base::VehicleStatus *vs)
void add_new_motion(double pre_image_timestamp, double image_timestamp, int motion_operation_flag, base::VehicleStatus *vehicledata)
Math-related util functions.
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
boost::circular_buffer< VehicleStatus > MotionBuffer
std::shared_ptr< localization::LocalizationEstimate > LocalizationMsgType
std::shared_ptr< apollo::drivers::Image > ImageMsgType
class register implement
Definition arena_queue.h:37