23#include "Eigen/Geometry"
24#include "boost/array.hpp"
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"
41using ::apollo::localization::CorrectedImu;
42using ::apollo::localization::Gps;
48constexpr double DEG_TO_RAD_LOCAL = M_PI / 180.0;
49const char *WGS84_TEXT =
"+proj=latlong +ellps=WGS84";
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};
59 const std::shared_ptr<apollo::cyber::Node> &node)
60 : config_(config), tf_broadcaster_(node), node_(node) {
61 std::string utm_target_param;
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);
73 ins_status_.mutable_header()->set_timestamp_sec(
75 gnss_status_.mutable_header()->set_timestamp_sec(
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_ =
86 epochobservation_writer_ =
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);
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_);
100 AFATAL <<
"Failed to create data parser.";
110 AERROR <<
"Data parser not init.";
114 std::lock_guard<std::mutex> lock(data_mutex_);
115 data_parser_->Update(msg);
117 data_parser_->GetMessagesByChannel(channel, &messages);
118 for (
auto &message : messages) {
119 DispatchMessage(message);
126 if (ins_status_record_ !=
static_cast<uint32_t
>(ins->
type()) ||
127 (now - last_notify) > 1.0) {
129 ins_status_record_ =
static_cast<uint32_t
>(ins->
type());
130 switch (ins->
type()) {
145 common::util::FillHeader(
"gnss", &ins_status_);
146 insstatus_writer_->Write(ins_status_);
151 gnss_status_.set_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()));
157 gnss_status_.set_solution_completed(
true);
159 gnss_status_.set_solution_completed(
false);
161 common::util::FillHeader(
"gnss", &gnss_status_);
162 gnssstatus_writer_->Write(gnss_status_);
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));
173 PublishBestpos(message);
181 CheckInsStatus(As<::apollo::drivers::gnss::Ins>(message));
182 PublishCorrimu(message);
183 PublishOdometry(message);
186 if (!has_ins_stat_message_) {
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);
199 PublishInsStat(message);
200 has_ins_stat_message_ =
true;
206 PublishEphemeris(message);
210 PublishObservation(message);
214 PublishHeading(message);
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);
228void DataParser::PublishBestpos(
const MessagePtr message) {
229 auto bestpos = std::make_shared<GnssBestPose>(*As<GnssBestPose>(message));
230 common::util::FillHeader(
"gnss", bestpos.get());
233 }
else if (bestpos->has_measurement_time()) {
234 bestpos->set_measurement_time(
237 gnssbestpose_writer_->Write(bestpos);
240void DataParser::PublishImu(
const MessagePtr message) {
241 auto raw_imu = std::make_shared<Imu>(*As<Imu>(message));
242 Imu *imu = As<Imu>(message);
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());
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());
253 common::util::FillHeader(
"gnss", raw_imu.get());
256 }
else if (raw_imu->has_measurement_time()) {
257 raw_imu->set_measurement_time(
260 rawimu_writer_->Write(raw_imu);
263void DataParser::PublishOdometry(
const MessagePtr message) {
264 Ins *ins = As<Ins>(message);
265 auto gps = std::make_shared<Gps>();
267 common::util::FillHeader(
"gnss", gps.get());
269 gps->mutable_header()->set_timestamp_sec(
272 auto *gps_msg = gps->mutable_localization();
275 double x = ins->position().lon();
276 double y = ins->position().lat();
277 x *= DEG_TO_RAD_LOCAL;
278 y *= DEG_TO_RAD_LOCAL;
280 pj_transform(wgs84pj_source_, utm_target_, 1, 1, &x, &y, NULL);
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());
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());
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());
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());
302 gps_writer_->Write(gps);
304 TransformStamped transform;
305 GpsToTransformStamped(gps, &transform);
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());
315 imu->mutable_header()->set_timestamp_sec(
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());
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());
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);
333 corrimu_writer_->Write(imu);
336void DataParser::PublishEphemeris(
const MessagePtr message) {
337 auto eph = std::make_shared<GnssEphemeris>(*As<GnssEphemeris>(message));
338 gnssephemeris_writer_->Write(eph);
341void DataParser::PublishObservation(
const MessagePtr message) {
343 std::make_shared<EpochObservation>(*As<EpochObservation>(message));
344 epochobservation_writer_->Write(observation);
347void DataParser::PublishHeading(
const MessagePtr message) {
348 auto heading = std::make_shared<Heading>(*As<Heading>(message));
351 }
else if (heading->has_measurement_time()) {
352 heading->set_measurement_time(
355 heading_writer_->Write(heading);
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());
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());
Cyber has builtin time type Time.
static Time Now()
get the current time.
double ToSecond() const
convert time to second.
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)
Some string util functions.
::google::protobuf::Message * MessagePtr
std::vector< MessageInfo > MessageInfoVec
T gps2unix(const T gps_seconds)
optional uint32 solution_status
optional uint32 position_type
optional string proj4_text
optional bool use_gnss_time
optional string child_frame_id