Apollo 11.0
自动驾驶开放平台
data_parser.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2017 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
19#include <cmath>
20#include <memory>
21#include <string>
22
23#include "Eigen/Geometry"
24#include "boost/array.hpp"
25
26#include "modules/common_msgs/localization_msgs/imu.pb.h"
27#include "modules/common_msgs/sensor_msgs/gnss_best_pose.pb.h"
28#include "modules/common_msgs/sensor_msgs/gnss_raw_observation.pb.h"
29#include "modules/common_msgs/sensor_msgs/heading.pb.h"
30
31#include "cyber/cyber.h"
36
37namespace apollo {
38namespace drivers {
39namespace gnss {
40
41using ::apollo::localization::CorrectedImu;
42using ::apollo::localization::Gps;
43
45
46namespace {
47
48constexpr double DEG_TO_RAD_LOCAL = M_PI / 180.0;
49const char *WGS84_TEXT = "+proj=latlong +ellps=WGS84";
50
51// covariance data for pose if can not get from novatel inscov topic
52static const boost::array<double, 36> POSE_COVAR = {
53 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,
54 0, 0, 0, 0.01, 0, 0, 0, 0, 0, 0, 0.01, 0, 0, 0, 0, 0, 0, 0.01};
55
56} // namespace
57
59 const std::shared_ptr<apollo::cyber::Node> &node)
60 : config_(config), tf_broadcaster_(node), node_(node) {
61 std::string utm_target_param;
62
63 wgs84pj_source_ = pj_init_plus(WGS84_TEXT);
64 utm_target_ = pj_init_plus(config_.proj4_text().c_str());
65 gnss_status_.set_solution_status(0);
66 gnss_status_.set_num_sats(0);
67 gnss_status_.set_position_type(0);
68 gnss_status_.set_solution_completed(false);
69 ins_status_.set_type(InsStatus::INVALID);
70}
71
73 ins_status_.mutable_header()->set_timestamp_sec(
74 cyber::Time::Now().ToSecond());
75 gnss_status_.mutable_header()->set_timestamp_sec(
76 cyber::Time::Now().ToSecond());
77
78 gnssstatus_writer_ = node_->CreateWriter<GnssStatus>(FLAGS_gnss_status_topic);
79 insstatus_writer_ = node_->CreateWriter<InsStatus>(FLAGS_ins_status_topic);
80 gnssbestpose_writer_ =
81 node_->CreateWriter<GnssBestPose>(FLAGS_gnss_best_pose_topic);
82 corrimu_writer_ = node_->CreateWriter<CorrectedImu>(FLAGS_imu_topic);
83 insstat_writer_ = node_->CreateWriter<InsStat>(FLAGS_ins_stat_topic);
84 gnssephemeris_writer_ =
85 node_->CreateWriter<GnssEphemeris>(FLAGS_gnss_rtk_eph_topic);
86 epochobservation_writer_ =
87 node_->CreateWriter<EpochObservation>(FLAGS_gnss_rtk_obs_topic);
88 heading_writer_ = node_->CreateWriter<Heading>(FLAGS_heading_topic);
89 rawimu_writer_ = node_->CreateWriter<Imu>(FLAGS_raw_imu_topic);
90 gps_writer_ = node_->CreateWriter<Gps>(FLAGS_gps_topic);
91
92 common::util::FillHeader("gnss", &ins_status_);
93 insstatus_writer_->Write(ins_status_);
94 common::util::FillHeader("gnss", &gnss_status_);
95 gnssstatus_writer_->Write(gnss_status_);
96
97 AINFO << "Creating data parser of format: " << config_.data().format();
98 data_parser_.reset(Parser::CreateParser(config_));
99 if (!data_parser_) {
100 AFATAL << "Failed to create data parser.";
101 return false;
102 }
103
104 init_flag_ = true;
105 return true;
106}
107
108void DataParser::ParseRawData(const std::string &msg, const uint8_t &channel) {
109 if (!init_flag_) {
110 AERROR << "Data parser not init.";
111 return;
112 }
113
114 std::lock_guard<std::mutex> lock(data_mutex_);
115 data_parser_->Update(msg);
116 MessageInfoVec messages;
117 data_parser_->GetMessagesByChannel(channel, &messages);
118 for (auto &message : messages) {
119 DispatchMessage(message);
120 }
121}
122
123void DataParser::CheckInsStatus(::apollo::drivers::gnss::Ins *ins) {
124 static double last_notify = cyber::Time().Now().ToSecond();
125 double now = cyber::Time().Now().ToSecond();
126 if (ins_status_record_ != static_cast<uint32_t>(ins->type()) ||
127 (now - last_notify) > 1.0) {
128 last_notify = now;
129 ins_status_record_ = static_cast<uint32_t>(ins->type());
130 switch (ins->type()) {
132 ins_status_.set_type(apollo::drivers::gnss::InsStatus::GOOD);
133 break;
134
137 break;
138
140 default:
141 ins_status_.set_type(apollo::drivers::gnss::InsStatus::INVALID);
142 break;
143 }
144
145 common::util::FillHeader("gnss", &ins_status_);
146 insstatus_writer_->Write(ins_status_);
147 }
148}
149
150void DataParser::CheckGnssStatus(::apollo::drivers::gnss::Gnss *gnss) {
151 gnss_status_.set_solution_status(
152 static_cast<uint32_t>(gnss->solution_status()));
153 gnss_status_.set_num_sats(static_cast<uint32_t>(gnss->num_sats()));
154 gnss_status_.set_position_type(static_cast<uint32_t>(gnss->position_type()));
155
156 if (static_cast<uint32_t>(gnss->solution_status()) == 0) {
157 gnss_status_.set_solution_completed(true);
158 } else {
159 gnss_status_.set_solution_completed(false);
160 }
161 common::util::FillHeader("gnss", &gnss_status_);
162 gnssstatus_writer_->Write(gnss_status_);
163}
164
165void DataParser::DispatchMessage(const MessageInfo &message_info) {
166 auto &message = message_info.message_ptr;
167 switch (message_info.type) {
169 CheckGnssStatus(As<::apollo::drivers::gnss::Gnss>(message));
170 break;
171
173 PublishBestpos(message);
174 break;
175
176 case MessageType::IMU:
177 PublishImu(message);
178 break;
179
180 case MessageType::INS:
181 CheckInsStatus(As<::apollo::drivers::gnss::Ins>(message));
182 PublishCorrimu(message);
183 PublishOdometry(message);
184
185 // if not has ins_stat message, publish ins_stat from best pose
186 if (!has_ins_stat_message_) {
187 MessagePtr msg_ptr;
188 if (data_parser_->GetInsStat(&msg_ptr)) {
189 auto ins_stat = std::make_shared<InsStat>(*As<InsStat>(msg_ptr));
190 if (ins_stat->has_ins_status()) {
191 common::util::FillHeader("gnss", ins_stat.get());
192 insstat_writer_->Write(ins_stat);
193 }
194 }
195 }
196 break;
197
199 PublishInsStat(message);
200 has_ins_stat_message_ = true;
201 break;
202
206 PublishEphemeris(message);
207 break;
208
210 PublishObservation(message);
211 break;
212
214 PublishHeading(message);
215 break;
216
217 default:
218 break;
219 }
220}
221
222void DataParser::PublishInsStat(const MessagePtr message) {
223 auto ins_stat = std::make_shared<InsStat>(*As<InsStat>(message));
224 common::util::FillHeader("gnss", ins_stat.get());
225 insstat_writer_->Write(ins_stat);
226}
227
228void DataParser::PublishBestpos(const MessagePtr message) {
229 auto bestpos = std::make_shared<GnssBestPose>(*As<GnssBestPose>(message));
230 common::util::FillHeader("gnss", bestpos.get());
231 if (!config_.use_gnss_time()) {
232 bestpos->set_measurement_time(cyber::Time::Now().ToSecond());
233 } else if (bestpos->has_measurement_time()) {
234 bestpos->set_measurement_time(
235 apollo::drivers::util::gps2unix(bestpos->measurement_time()));
236 }
237 gnssbestpose_writer_->Write(bestpos);
238}
239
240void DataParser::PublishImu(const MessagePtr message) {
241 auto raw_imu = std::make_shared<Imu>(*As<Imu>(message));
242 Imu *imu = As<Imu>(message);
243
244 raw_imu->mutable_linear_acceleration()->set_x(
245 -imu->linear_acceleration().y());
246 raw_imu->mutable_linear_acceleration()->set_y(imu->linear_acceleration().x());
247 raw_imu->mutable_linear_acceleration()->set_z(imu->linear_acceleration().z());
248
249 raw_imu->mutable_angular_velocity()->set_x(-imu->angular_velocity().y());
250 raw_imu->mutable_angular_velocity()->set_y(imu->angular_velocity().x());
251 raw_imu->mutable_angular_velocity()->set_z(imu->angular_velocity().z());
252
253 common::util::FillHeader("gnss", raw_imu.get());
254 if (!config_.use_gnss_time()) {
255 raw_imu->set_measurement_time(cyber::Time::Now().ToSecond());
256 } else if (raw_imu->has_measurement_time()) {
257 raw_imu->set_measurement_time(
258 apollo::drivers::util::gps2unix(raw_imu->measurement_time()));
259 }
260 rawimu_writer_->Write(raw_imu);
261}
262
263void DataParser::PublishOdometry(const MessagePtr message) {
264 Ins *ins = As<Ins>(message);
265 auto gps = std::make_shared<Gps>();
266
267 common::util::FillHeader("gnss", gps.get());
268 if (config_.use_gnss_time()) {
269 gps->mutable_header()->set_timestamp_sec(
270 apollo::drivers::util::gps2unix(ins->measurement_time()));
271 }
272 auto *gps_msg = gps->mutable_localization();
273
274 // 1. pose xyz
275 double x = ins->position().lon();
276 double y = ins->position().lat();
277 x *= DEG_TO_RAD_LOCAL;
278 y *= DEG_TO_RAD_LOCAL;
279
280 pj_transform(wgs84pj_source_, utm_target_, 1, 1, &x, &y, NULL);
281
282 gps_msg->mutable_position()->set_x(x);
283 gps_msg->mutable_position()->set_y(y);
284 gps_msg->mutable_position()->set_z(ins->position().height());
285
286 // 2. orientation
287 Eigen::Quaterniond q =
288 Eigen::AngleAxisd(ins->euler_angles().z() - 90 * DEG_TO_RAD_LOCAL,
289 Eigen::Vector3d::UnitZ()) *
290 Eigen::AngleAxisd(-ins->euler_angles().y(), Eigen::Vector3d::UnitX()) *
291 Eigen::AngleAxisd(ins->euler_angles().x(), Eigen::Vector3d::UnitY());
292
293 gps_msg->mutable_orientation()->set_qx(q.x());
294 gps_msg->mutable_orientation()->set_qy(q.y());
295 gps_msg->mutable_orientation()->set_qz(q.z());
296 gps_msg->mutable_orientation()->set_qw(q.w());
297
298 gps_msg->mutable_linear_velocity()->set_x(ins->linear_velocity().x());
299 gps_msg->mutable_linear_velocity()->set_y(ins->linear_velocity().y());
300 gps_msg->mutable_linear_velocity()->set_z(ins->linear_velocity().z());
301
302 gps_writer_->Write(gps);
303 if (config_.tf().enable()) {
304 TransformStamped transform;
305 GpsToTransformStamped(gps, &transform);
306 tf_broadcaster_.SendTransform(transform);
307 }
308}
309
310void DataParser::PublishCorrimu(const MessagePtr message) {
311 Ins *ins = As<Ins>(message);
312 auto imu = std::make_shared<CorrectedImu>();
313 common::util::FillHeader("gnss", imu.get());
314 if (config_.use_gnss_time()) {
315 imu->mutable_header()->set_timestamp_sec(
316 apollo::drivers::util::gps2unix(ins->measurement_time()));
317 }
318 auto *imu_msg = imu->mutable_imu();
319 imu_msg->mutable_linear_acceleration()->set_x(
320 -ins->linear_acceleration().y());
321 imu_msg->mutable_linear_acceleration()->set_y(ins->linear_acceleration().x());
322 imu_msg->mutable_linear_acceleration()->set_z(ins->linear_acceleration().z());
323
324 imu_msg->mutable_angular_velocity()->set_x(-ins->angular_velocity().y());
325 imu_msg->mutable_angular_velocity()->set_y(ins->angular_velocity().x());
326 imu_msg->mutable_angular_velocity()->set_z(ins->angular_velocity().z());
327
328 imu_msg->mutable_euler_angles()->set_x(ins->euler_angles().x());
329 imu_msg->mutable_euler_angles()->set_y(-ins->euler_angles().y());
330 imu_msg->mutable_euler_angles()->set_z(ins->euler_angles().z() -
331 90 * DEG_TO_RAD_LOCAL);
332
333 corrimu_writer_->Write(imu);
334}
335
336void DataParser::PublishEphemeris(const MessagePtr message) {
337 auto eph = std::make_shared<GnssEphemeris>(*As<GnssEphemeris>(message));
338 gnssephemeris_writer_->Write(eph);
339}
340
341void DataParser::PublishObservation(const MessagePtr message) {
342 auto observation =
343 std::make_shared<EpochObservation>(*As<EpochObservation>(message));
344 epochobservation_writer_->Write(observation);
345}
346
347void DataParser::PublishHeading(const MessagePtr message) {
348 auto heading = std::make_shared<Heading>(*As<Heading>(message));
349 if (!config_.use_gnss_time()) {
350 heading->set_measurement_time(cyber::Time::Now().ToSecond());
351 } else if (heading->has_measurement_time()) {
352 heading->set_measurement_time(
353 apollo::drivers::util::gps2unix(heading->measurement_time()));
354 }
355 heading_writer_->Write(heading);
356}
357
358void DataParser::GpsToTransformStamped(const std::shared_ptr<Gps> &gps,
359 TransformStamped *transform) {
360 transform->mutable_header()->set_timestamp_sec(gps->header().timestamp_sec());
361 transform->mutable_header()->set_frame_id(config_.tf().frame_id());
362 transform->set_child_frame_id(config_.tf().child_frame_id());
363 auto translation = transform->mutable_transform()->mutable_translation();
364 translation->set_x(gps->localization().position().x());
365 translation->set_y(gps->localization().position().y());
366 translation->set_z(gps->localization().position().z());
367 auto rotation = transform->mutable_transform()->mutable_rotation();
368 rotation->set_qx(gps->localization().orientation().qx());
369 rotation->set_qy(gps->localization().orientation().qy());
370 rotation->set_qz(gps->localization().orientation().qz());
371 rotation->set_qw(gps->localization().orientation().qw());
372}
373
374} // namespace gnss
375} // namespace drivers
376} // namespace apollo
Cyber has builtin time type Time.
Definition time.h:31
static Time Now()
get the current time.
Definition time.cc:57
double ToSecond() const
convert time to second.
Definition time.cc:77
DataParser(const config::Config &config, const std::shared_ptr< apollo::cyber::Node > &node)
void ParseRawData(const std::string &msg, const uint8_t &channel=0)
static Parser * CreateParser(const config::Config &config)
Definition parser.h:87
void SendTransform(const TransformStamped &transform)
Send a TransformStamped message The stamped data structure includes frame_id, and time,...
#define AERROR
Definition log.h:44
#define AFATAL
Definition log.h:45
#define AINFO
Definition log.h:42
Some string util functions.
::google::protobuf::Message * MessagePtr
Definition parser.h:34
std::vector< MessageInfo > MessageInfoVec
Definition parser.h:57
T gps2unix(const T gps_seconds)
class register implement
Definition arena_queue.h:37
optional uint32 solution_status
Definition gnss.proto:53
optional uint32 position_type
Definition gnss.proto:54
optional int32 num_sats
Definition gnss.proto:34