19#include "yaml-cpp/yaml.h"
28namespace localization {
34 : gnss_solver_(new GnssSolver()),
35 enable_ins_aid_rtk_(true),
36 gnss_lever_arm_{0.0, 0.0, 0.0},
37 sins_align_finish_(false),
38 double_antenna_solver_(new GnssSolver()),
39 current_obs_time_(0.0),
45 map_gnss_eph_.clear();
48 gnss_solver_ =
nullptr;
49 delete double_antenna_solver_;
50 double_antenna_solver_ =
nullptr;
56 gnss_solver_->set_enable_external_prediction(enable_ins_aid_rtk_);
62 map_gnss_eph_.clear();
63 sins_align_finish_ =
false;
68void LocalizationGnssProcess::SetDefaultOption() {
70 gnss_solver_->set_position_option(3);
71 gnss_solver_->set_tropsphere_option(0);
72 gnss_solver_->enable_cycle_slip_fix();
73 enable_ins_aid_rtk_ =
false;
75 gnss_lever_arm_.
arm_x = -0.030;
76 gnss_lever_arm_.
arm_y = 0.338;
77 gnss_lever_arm_.
arm_z = 1.291;
82 if (!raw_obs.has_receiver_id()) {
83 AERROR <<
"Obs data being invalid if without receiver id!";
86 const double unix_to_gps = 315964800;
87 const double sec_per_week = 604800;
88 double leap_second_s = gnss_solver_->get_leap_second(raw_obs.
gnss_week(),
91 double sys_secs_to_gnss =
95 double obs_delay = sys_secs_to_gnss - obs_secs;
97 double obs_xyz[3] = {0.0};
98 if (raw_obs.has_position_x() && raw_obs.has_position_y() &&
99 raw_obs.has_position_z()) {
104 const unsigned int max_msg_size = 256;
105 char message[max_msg_size] = {
'\0'};
107 message, max_msg_size,
108 "user %u time:%12.3f sat_num:%d obs_delay:%12.3f%16.3f%16.3f%16.3f\n",
110 obs_delay, obs_xyz[0], obs_xyz[1], obs_xyz[2]);
113 EpochObservationMsg raw_obs_msg;
117 gnss_solver_->save_baser_observation(raw_obs_msg);
122 const unsigned int second_per_week = 604800;
123 double new_obs_time =
125 if (new_obs_time <= current_obs_time_) {
128 current_obs_time_ = new_obs_time;
129 GnssPosition(&raw_obs_msg);
134 if (!msg.has_gnss_type()) {
137 auto gnss_orbit = msg;
144 gnss_solver_->get_leap_second(gnss_orbit.glonass_orbit().week_num(),
145 gnss_orbit.glonass_orbit().toe());
146 double toe = gnss_orbit.glonass_orbit().toe() - leap_sec;
147 gnss_orbit.mutable_glonass_orbit()->set_toe(toe);
148 gnss_orbit.mutable_glonass_orbit()->set_week_second_s(toe);
150 static int eph_counter = 0;
153 if (DuplicateEph(gnss_orbit)) {
154 AINFO <<
"received an existed gnss ephemeris!";
158 GnssEphemerisMsg gnss_orbit_msg;
160 gnss_solver_->save_gnss_ephemris(gnss_orbit_msg);
164 const double variance[9][9]) {
165 if (!sins_pva_msg.init_and_alignment) {
169 sins_align_finish_ =
true;
172 double sec_s = sins_pva_msg.time;
173 double llh[3] = {sins_pva_msg.pos.longitude, sins_pva_msg.pos.latitude,
174 sins_pva_msg.pos.height};
175 double velocity[3] = {sins_pva_msg.vel.ve, sins_pva_msg.vel.vn,
176 sins_pva_msg.vel.vu};
177 double lever_arm[3] = {gnss_lever_arm_.
arm_x, gnss_lever_arm_.
arm_y,
178 gnss_lever_arm_.
arm_z};
179 double euler[3] = {sins_pva_msg.att.pitch, sins_pva_msg.att.roll,
180 sins_pva_msg.att.yaw};
182 double std_pos[3][3] = {0.0};
183 double std_vel[3][3] = {0.0};
185 for (
unsigned int i = 0; i < 3; ++i) {
186 for (
unsigned int j = 0; j < 3; ++j) {
187 std_pos[i][j] = variance[i][j];
188 std_vel[i][j] = variance[i + 3][j + 3];
192 gnss_solver_->motion_update(sec_s, llh, std_pos, velocity, std_vel, euler,
197 MeasureData *gnss_msg) {
198 CHECK_NOTNULL(gnss_msg);
203 const unsigned int second_per_week = 604800;
204 double sec_s = gnss_pnt_result_.gnss_week() * second_per_week +
205 gnss_pnt_result_.gnss_second_s();
206 gnss_msg->time = sec_s;
207 gnss_msg->frame_type = FrameType::ECEF;
211 for (
int i = 0; i < dim; ++i) {
212 for (
int j = 0; j < dim; ++j) {
213 gnss_msg->variance[i][j] = 0.0;
218 if (gnss_pnt_result_.has_pos_x_m() && gnss_pnt_result_.has_pos_y_m() &&
219 gnss_pnt_result_.has_pos_z_m()) {
221 gnss_msg->gnss_pos.longitude = gnss_pnt_result_.pos_x_m();
222 gnss_msg->gnss_pos.latitude = gnss_pnt_result_.pos_y_m();
223 gnss_msg->gnss_pos.height = gnss_pnt_result_.pos_z_m();
224 gnss_msg->measure_type = MeasureType::GNSS_POS_ONLY;
226 gnss_msg->is_have_variance =
true;
228 gnss_msg->variance[0][0] =
229 gnss_pnt_result_.std_pos_x_m() * gnss_pnt_result_.std_pos_x_m();
230 gnss_msg->variance[1][1] =
231 gnss_pnt_result_.std_pos_y_m() * gnss_pnt_result_.std_pos_y_m();
232 gnss_msg->variance[2][2] =
233 gnss_pnt_result_.std_pos_z_m() * gnss_pnt_result_.std_pos_z_m();
236 if (gnss_pnt_result_.has_vel_x_m() && gnss_pnt_result_.has_vel_y_m() &&
237 gnss_pnt_result_.has_vel_z_m()) {
240 gnss_msg->gnss_vel.ve = gnss_pnt_result_.vel_x_m();
241 gnss_msg->gnss_vel.vn = gnss_pnt_result_.vel_y_m();
242 gnss_msg->gnss_vel.vu = gnss_pnt_result_.vel_z_m();
243 gnss_msg->measure_type = MeasureType::ENU_VEL_ONLY;
244 gnss_msg->is_have_variance =
true;
246 gnss_msg->variance[3][3] =
247 gnss_pnt_result_.std_vel_x_m() * gnss_pnt_result_.std_vel_x_m();
248 gnss_msg->variance[4][4] =
249 gnss_pnt_result_.std_vel_y_m() * gnss_pnt_result_.std_vel_y_m();
250 gnss_msg->variance[5][5] =
251 gnss_pnt_result_.std_vel_z_m() * gnss_pnt_result_.std_vel_z_m();
253 if (b_pos && b_vel) {
254 gnss_msg->measure_type = MeasureType::GNSS_POS_VEL;
260bool LocalizationGnssProcess::DuplicateEph(
268 unsigned int sat_prn = 0;
269 unsigned int week_num = 0;
281 if (map_gnss_eph_.find(temp) != map_gnss_eph_.end()) {
284 map_gnss_eph_.insert(
285 std::map<EphKey, drivers::gnss::GnssEphemeris>::value_type(temp,
290inline void LocalizationGnssProcess::LogPnt(
const GnssPntResultMsg &rover_pnt,
292 char print_infor[256] = {
'\0'};
293 snprintf(print_infor,
sizeof(print_infor),
294 "%6d%12.3f%4d%16.3f%16.3f%16.3f%4d%4.1f%6.1f%8.3f%8.3f%8.3f%8.3f%8."
296 rover_pnt.gnss_week(), rover_pnt.gnss_second_s(),
297 static_cast<int>(rover_pnt.pnt_type()), rover_pnt.pos_x_m(),
298 rover_pnt.pos_y_m(), rover_pnt.pos_z_m(), rover_pnt.sovled_sat_num(),
299 rover_pnt.pdop(), ratio, rover_pnt.vel_x_m(), rover_pnt.vel_y_m(),
300 rover_pnt.vel_z_m(), rover_pnt.std_pos_x_m(),
301 rover_pnt.std_pos_y_m(), rover_pnt.std_pos_z_m());
302 AINFO << print_infor;
305bool LocalizationGnssProcess::GnssPosition(EpochObservationMsg *raw_rover_obs) {
306 CHECK_NOTNULL(raw_rover_obs);
309 if (raw_rover_obs->receiver_id() != 0) {
310 AERROR <<
"Wrong Rover Obs Data!";
313 int b_solved = gnss_solver_->solve(raw_rover_obs, &gnss_pnt_result_);
317 LogPnt(gnss_pnt_result_, gnss_solver_->get_ratio());
318 if (!sins_align_finish_) {
319 AWARN <<
"Sins-ekf has not converged or finished its alignment!";
321 if (gnss_pnt_result_.has_std_pos_x_m() &&
322 gnss_pnt_result_.has_std_pos_y_m() &&
323 gnss_pnt_result_.has_std_pos_z_m()) {
325 gnss_pnt_result_.std_pos_x_m() * gnss_pnt_result_.std_pos_x_m() +
326 gnss_pnt_result_.std_pos_y_m() * gnss_pnt_result_.std_pos_y_m() +
327 gnss_pnt_result_.std_pos_z_m() * gnss_pnt_result_.std_pos_z_m();
328 sigma = std::sqrt(fabs(sigma));
329 const double sigma_threshold = 10.0;
330 if (fabs(sigma) > sigma_threshold) {
331 AWARN <<
"Position std exceeds the threshold " << sigma_threshold <<
"!";
A general class to denote the return status of an API call.
static Status OK()
generate a success status.
a singleton clock that can be used to get the current timestamp.
static double NowInSeconds()
gets the current time in second.
static void Transfer(const apollo::drivers::gnss::BandObservation &in, BandObservationMsg *out)
void RawObservationProcess(const drivers::gnss::EpochObservation &raw_obs)
void RawEphemerisProcess(const drivers::gnss::GnssEphemeris &gnss_orbit)
LocalizationGnssProcess()
apollo::common::Status Init(const LocalizationIntegParam ¶m)
~LocalizationGnssProcess()
LocalizationMeasureState GetResult(MeasureData *gnss_measure)
void IntegSinsPvaProcess(const InsPva &sins_pva, const double variance[9][9])
The class of GnssMsgTransfer
The class of LocalizationGnssProcess
optional double position_z
optional double gnss_second_s
optional uint32 sat_obs_num
optional uint32 gnss_week
optional double position_y
optional uint32 receiver_id
optional double position_x
optional GnssType gnss_type
optional GlonassOrbit glonass_orbit
optional KepplerOrbit keppler_orbit
ImuToAntOffset imu_to_ant_offset