Apollo 10.0
自动驾驶开放平台
asensing_parser.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2024 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
17// An parser for decoding binary messages from a NovAtel receiver. The following
18// messages must be
19// logged in order for this parser to work properly.
20//
21#include <cmath>
22#include <iostream>
23#include <limits>
24#include <memory>
25#include <vector>
26
27#include "modules/common_msgs/sensor_msgs/gnss.pb.h"
28#include "modules/common_msgs/sensor_msgs/gnss_best_pose.pb.h"
29#include "modules/common_msgs/sensor_msgs/gnss_raw_observation.pb.h"
30#include "modules/common_msgs/sensor_msgs/heading.pb.h"
31#include "modules/common_msgs/sensor_msgs/imu.pb.h"
32#include "modules/common_msgs/sensor_msgs/ins.pb.h"
33
34#include "cyber/cyber.h"
39
40namespace apollo {
41namespace drivers {
42namespace gnss {
43
44class AsensingParser : public Parser {
45 public:
47 explicit AsensingParser(const config::Config &config);
48
49 virtual void GetMessages(MessageInfoVec *messages);
50
51 private:
52 void PrepareMessage();
53
54 void FillGnssBestpos();
55 void FillIns();
56 void FillInsStat();
57 void FillImu();
58 void FillHeading();
59
61 SolutionType solution_type_ = SolutionType::NONE;
62 double gps_sec_;
63
64 GnssBestPose bestpos_;
65 // bestpos 1hz rate control
66 RateControl bestpos_ratecontrol_{PERIOD_NS_1HZ};
67 Imu imu_;
68 Heading heading_;
69 Ins ins_;
70 InsStat ins_stat_;
71
72 ProtocolAsensing asensing;
73 Decode_0A decode_a;
74 Decode_0B decode_b;
75};
76
78 return new AsensingParser(config);
79}
80
82
84 if (data_ == nullptr) {
85 return;
86 }
87 asensing.addData(
88 std::string(reinterpret_cast<const char *>(data_), data_end_ - data_));
89 if (asensing.getProtocol() != decode_b.m_typeImu) {
90 return;
91 }
92 PrepareMessage();
93
94 FillGnssBestpos();
95 FillImu();
96 FillHeading();
97 FillIns();
98 FillInsStat();
99
100 if (bestpos_ratecontrol_.check()) {
101 messages->push_back(MessageInfo{MessageType::BEST_GNSS_POS,
102 reinterpret_cast<MessagePtr>(&bestpos_)});
103 }
104 messages->push_back(
105 MessageInfo{MessageType::IMU, reinterpret_cast<MessagePtr>(&imu_)});
106 messages->push_back(MessageInfo{MessageType::HEADING,
107 reinterpret_cast<MessagePtr>(&heading_)});
108 messages->push_back(
109 MessageInfo{MessageType::INS, reinterpret_cast<MessagePtr>(&ins_)});
110 messages->push_back(MessageInfo{MessageType::INS_STAT,
111 reinterpret_cast<MessagePtr>(&ins_stat_)});
112}
113
114void AsensingParser::PrepareMessage() {
115 if ((decode_b.insdata.InsStatus & 0x0F) == 0x0F) {
116 solution_status_ = SolutionStatus::SOL_COMPUTED;
117 } else {
118 solution_status_ = SolutionStatus::INSUFFICIENT_OBS;
119 }
120 if (SolutionType_IsValid(decode_b.insdata.flag_pos)) {
121 solution_type_ = SolutionType(decode_b.insdata.flag_pos);
122 } else {
123 solution_type_ = SolutionType::NONE;
124 }
125 gps_sec_ =
127}
128
129void AsensingParser::FillGnssBestpos() {
130 bestpos_.set_measurement_time(gps_sec_);
131 bestpos_.set_sol_status(solution_status_);
132 bestpos_.set_sol_type(solution_type_);
133 bestpos_.set_latitude(decode_b.insdata.Lat_deg);
134 bestpos_.set_longitude(decode_b.insdata.Lon_deg);
135 bestpos_.set_height_msl(decode_b.insdata.Alt_m);
136
137 if (decode_b.insdata.LoopType == 0) {
138 bestpos_.set_latitude_std_dev(exp(decode_b.insdata.data1 / 100));
139 bestpos_.set_longitude_std_dev(exp(decode_b.insdata.data2 / 100));
140 bestpos_.set_height_std_dev(exp(decode_b.insdata.data3 / 100));
141 }
142 bestpos_.set_differential_age(decode_b.insdata.differential_age);
143 // bestpos_.set_num_sats_tracked(0);
144 // bestpos_.set_num_sats_in_solution(0);
145 // bestpos_.set_num_sats_l1(0);
146 // bestpos_.set_num_sats_multi(0);
147}
148
149void AsensingParser::FillIns() {
150 ins_.mutable_euler_angles()->set_x(decode_b.insdata.Roll_rad);
151 ins_.mutable_euler_angles()->set_y(-decode_b.insdata.Pitch_rad);
152 ins_.mutable_euler_angles()->set_z(decode_b.insdata.Yaw_rad);
153
154 ins_.mutable_position()->set_lon(decode_b.insdata.Lon_deg);
155 ins_.mutable_position()->set_lat(decode_b.insdata.Lat_deg);
156 ins_.mutable_position()->set_height(decode_b.insdata.Alt_m);
157 ins_.mutable_linear_velocity()->set_x(decode_b.insdata.VelE_mps);
158 ins_.mutable_linear_velocity()->set_y(decode_b.insdata.VelN_mps);
159 ins_.mutable_linear_velocity()->set_z(-decode_b.insdata.VelD_mps);
160 rfu_to_flu(decode_b.insdata.AccX_g, decode_b.insdata.AccY_g,
161 decode_b.insdata.AccZ_g, ins_.mutable_linear_acceleration());
162 rfu_to_flu(decode_b.insdata.GyroX, decode_b.insdata.GyroY,
163 decode_b.insdata.GyroZ, ins_.mutable_angular_velocity());
164 ins_.set_measurement_time(gps_sec_);
165 ins_.mutable_header()->set_timestamp_sec(cyber::Time::Now().ToSecond());
166
167 switch (solution_type_) {
172 ins_.set_type(Ins::GOOD);
173 break;
175 ins_.set_type(Ins::CONVERGING);
176 break;
177 default:
178 ins_.set_type(Ins::INVALID);
179 break;
180 }
181}
182
183void AsensingParser::FillInsStat() {
184 ins_stat_.set_ins_status(solution_status_);
185 ins_stat_.set_pos_type(solution_type_);
186}
187
188void AsensingParser::FillImu() {
189 rfu_to_flu(decode_b.insdata.AccX_g, decode_b.insdata.AccY_g,
190 decode_b.insdata.AccZ_g, imu_.mutable_linear_acceleration());
191 rfu_to_flu(decode_b.insdata.GyroX, decode_b.insdata.GyroY,
192 decode_b.insdata.GyroZ, imu_.mutable_angular_velocity());
193 imu_.set_measurement_time(gps_sec_);
194}
195
196void AsensingParser::FillHeading() {
197 heading_.set_solution_status(solution_status_);
198 heading_.set_position_type(solution_type_);
199 heading_.set_measurement_time(gps_sec_);
200 heading_.set_heading(decode_b.insdata.Yaw_deg);
201 heading_.set_pitch(decode_b.insdata.Pitch_deg);
202
203 if (decode_b.insdata.LoopType == 2) {
204 heading_.set_heading_std_dev(exp(decode_b.insdata.data3 / 100));
205 heading_.set_pitch_std_dev(exp(decode_b.insdata.data2 / 100));
206 }
207
208 // heading_.set_station_id("0");
209 // heading_.set_satellite_number_multi(0);
210 // heading_.set_satellite_soulution_number(0);
211}
212
213} // namespace gnss
214} // namespace drivers
215} // namespace apollo
std::string m_typeImu
std::string getProtocol()
void addData(const std::string &data)
static Time Now()
get the current time.
Definition time.cc:57
virtual void GetMessages(MessageInfoVec *messages)
const uint8_t * data_
Definition parser.h:138
const uint8_t * data_end_
Definition parser.h:139
static Parser * CreateAsensing(const config::Config &config)
::google::protobuf::Message * MessagePtr
Definition parser.h:34
void rfu_to_flu(double r, double f, double u, ::apollo::common::Point3D *flu)
constexpr uint64_t PERIOD_NS_1HZ
std::vector< MessageInfo > MessageInfoVec
Definition parser.h:57
T unix2gps(const T unix_seconds)
class register implement
Definition arena_queue.h:37
uint8_t InsStatus
float differential_age
uint8_t flag_pos
uint8_t LoopType
int64_t SysTime_ms