32 #include <Eigen/Geometry>
80 param(
"use_gnss_time", settings_.use_gnss_time,
true);
81 param(
"frame_id", settings_.frame_id, (std::string)
"gnss");
82 param(
"imu_frame_id", settings_.imu_frame_id, (std::string)
"imu");
83 param(
"poi_frame_id", settings_.poi_frame_id, (std::string)
"base_link");
84 param(
"vsm_frame_id", settings_.vsm_frame_id, (std::string)
"vsm");
85 param(
"aux1_frame_id", settings_.aux1_frame_id, (std::string)
"aux1");
86 param(
"vehicle_frame_id", settings_.vehicle_frame_id, settings_.poi_frame_id);
87 param(
"local_frame_id", settings_.local_frame_id, (std::string)
"odom");
88 param(
"insert_local_frame", settings_.insert_local_frame,
false);
89 param(
"lock_utm_zone", settings_.lock_utm_zone,
true);
90 param(
"leap_seconds", settings_.leap_seconds, -128);
93 param(
"device", settings_.device, std::string(
"/dev/ttyACM0"));
94 getUint32Param(
"serial/baudrate", settings_.baudrate,
95 static_cast<uint32_t
>(921600));
96 param(
"serial/hw_flow_control", settings_.hw_flow_control, std::string(
"off"));
97 param(
"serial/rx_serial_port", settings_.rx_serial_port, std::string(
"USB1"));
98 param(
"login/user", settings_.login_user, std::string(
""));
99 param(
"login/password", settings_.login_password, std::string(
""));
100 settings_.reconnect_delay_s = 2.0f;
101 param(
"receiver_type", settings_.septentrio_receiver_type, std::string(
"gnss"));
102 if (!((settings_.septentrio_receiver_type ==
"gnss") ||
103 (settings_.septentrio_receiver_type ==
"ins") ||
104 (settings_.septentrio_receiver_type ==
"ins_in_gnss_mode")))
107 settings_.septentrio_receiver_type +
108 " use either gnss or ins.");
112 if (settings_.septentrio_receiver_type ==
"ins_in_gnss_mode")
114 settings_.septentrio_receiver_type =
"gnss";
115 settings_.ins_in_gnss_mode =
true;
119 getUint32Param(
"polling_period/pvt", settings_.polling_period_pvt,
120 static_cast<uint32_t
>(1000));
121 if (!(validPeriod(settings_.polling_period_pvt,
122 settings_.septentrio_receiver_type ==
"ins")))
126 "Please specify a valid polling period for PVT-related SBF blocks and NMEA messages.");
129 getUint32Param(
"polling_period/rest", settings_.polling_period_rest,
130 static_cast<uint32_t
>(1000));
131 if (!(validPeriod(settings_.polling_period_rest,
132 settings_.septentrio_receiver_type ==
"ins")))
136 "Please specify a valid polling period for PVT-unrelated SBF blocks and NMEA messages.");
141 param(
"multi_antenna", settings_.multi_antenna,
false);
144 param(
"publish/gpst", settings_.publish_gpst,
false);
145 param(
"publish/navsatfix", settings_.publish_navsatfix,
true);
146 param(
"publish/gpsfix", settings_.publish_gpsfix,
false);
147 param(
"publish/pose", settings_.publish_pose,
false);
148 param(
"publish/diagnostics", settings_.publish_diagnostics,
false);
149 param(
"publish/gpgga", settings_.publish_gpgga,
false);
150 param(
"publish/gprmc", settings_.publish_gprmc,
false);
151 param(
"publish/gpgsa", settings_.publish_gpgsa,
false);
152 param(
"publish/gpgsv", settings_.publish_gpgsv,
false);
153 param(
"publish/measepoch", settings_.publish_measepoch,
false);
154 param(
"publish/pvtcartesian", settings_.publish_pvtcartesian,
false);
155 param(
"publish/pvtgeodetic", settings_.publish_pvtgeodetic,
156 (settings_.septentrio_receiver_type ==
"gnss"));
157 param(
"publish/basevectorcart", settings_.publish_basevectorcart,
false);
158 param(
"publish/basevectorgeod", settings_.publish_basevectorgeod,
false);
159 param(
"publish/poscovcartesian", settings_.publish_poscovcartesian,
false);
160 param(
"publish/poscovgeodetic", settings_.publish_poscovgeodetic,
161 (settings_.septentrio_receiver_type ==
"gnss"));
162 param(
"publish/velcovgeodetic", settings_.publish_velcovgeodetic,
163 (settings_.septentrio_receiver_type ==
"gnss"));
165 "publish/atteuler", settings_.publish_atteuler,
166 ((settings_.septentrio_receiver_type ==
"gnss") && settings_.multi_antenna));
168 "publish/attcoveuler", settings_.publish_attcoveuler,
169 ((settings_.septentrio_receiver_type ==
"gnss") && settings_.multi_antenna));
170 param(
"publish/insnavcart", settings_.publish_insnavcart,
false);
171 param(
"publish/insnavgeod", settings_.publish_insnavgeod,
172 (settings_.septentrio_receiver_type ==
"ins"));
173 param(
"publish/imusetup", settings_.publish_imusetup,
false);
174 param(
"publish/velsensorsetup", settings_.publish_velsensorsetup,
false);
175 param(
"publish/exteventinsnavgeod", settings_.publish_exteventinsnavgeod,
false);
176 param(
"publish/exteventinsnavcart", settings_.publish_exteventinsnavcart,
false);
177 param(
"publish/extsensormeas", settings_.publish_extsensormeas,
false);
178 param(
"publish/imu", settings_.publish_imu,
false);
179 param(
"publish/localization", settings_.publish_localization,
false);
180 param(
"publish/twist", settings_.publish_twist,
false);
181 param(
"publish/tf", settings_.publish_tf,
false);
184 param(
"datum", settings_.datum, std::string(
"Default"));
185 param(
"ant_type", settings_.ant_type, std::string(
"Unknown"));
186 param(
"ant_aux1_type", settings_.ant_aux1_type, std::string(
"Unknown"));
187 param(
"ant_serial_nr", settings_.ant_serial_nr, std::string());
188 if (settings_.ant_serial_nr.empty())
191 if (getUint32Param(
"ant_serial_nr", sn_tmp,
static_cast<uint32_t
>(0)))
192 settings_.ant_serial_nr = std::to_string(sn_tmp);
194 settings_.ant_serial_nr =
"Unknown";
196 param(
"ant_aux1_serial_nr", settings_.ant_aux1_serial_nr, std::string());
197 if (settings_.ant_aux1_serial_nr.empty())
200 if (getUint32Param(
"ant_aux1_serial_nr", sn_tmp,
static_cast<uint32_t
>(0)))
201 settings_.ant_aux1_serial_nr = std::to_string(sn_tmp);
203 settings_.ant_aux1_serial_nr =
"Unknown";
205 param(
"poi_to_arp/delta_e", settings_.delta_e, 0.0f);
206 param(
"poi_to_arp/delta_n", settings_.delta_n, 0.0f);
207 param(
"poi_to_arp/delta_u", settings_.delta_u, 0.0f);
209 param(
"use_ros_axis_orientation", settings_.use_ros_axis_orientation,
true);
212 bool getConfigFromTf;
213 param(
"get_spatial_config_from_tf", getConfigFromTf,
false);
216 if (settings_.septentrio_receiver_type ==
"ins")
219 getTransform(settings_.vehicle_frame_id, settings_.imu_frame_id,
222 getTransform(settings_.imu_frame_id, settings_.poi_frame_id, T_poi_imu);
224 getTransform(settings_.imu_frame_id, settings_.vsm_frame_id, T_vsm_imu);
226 getTransform(settings_.imu_frame_id, settings_.frame_id, T_ant_imu);
229 double roll, pitch, yaw;
230 getRPY(T_imu_vehicle.transform.rotation, roll, pitch, yaw);
235 settings_.ant_lever_x = T_ant_imu.transform.translation.x;
236 settings_.ant_lever_y = T_ant_imu.transform.translation.y;
237 settings_.ant_lever_z = T_ant_imu.transform.translation.z;
239 settings_.poi_x = T_poi_imu.transform.translation.x;
240 settings_.poi_y = T_poi_imu.transform.translation.y;
241 settings_.poi_z = T_poi_imu.transform.translation.z;
243 settings_.vsm_x = T_vsm_imu.transform.translation.x;
244 settings_.vsm_y = T_vsm_imu.transform.translation.y;
245 settings_.vsm_z = T_vsm_imu.transform.translation.z;
247 if (settings_.multi_antenna)
250 getTransform(settings_.imu_frame_id, settings_.aux1_frame_id,
253 double dy = T_aux1_imu.transform.translation.y -
254 T_ant_imu.transform.translation.y;
255 double dx = T_aux1_imu.transform.translation.x -
256 T_ant_imu.transform.translation.x;
257 settings_.heading_offset =
259 double dz = T_aux1_imu.transform.translation.z -
260 T_ant_imu.transform.translation.z;
263 settings_.pitch_offset =
267 if ((settings_.septentrio_receiver_type ==
"gnss") &&
268 settings_.multi_antenna)
271 getTransform(settings_.vehicle_frame_id, settings_.frame_id,
274 getTransform(settings_.vehicle_frame_id, settings_.aux1_frame_id,
278 double dy = T_aux1_vehicle.transform.translation.y -
279 T_ant_vehicle.transform.translation.y;
280 double dx = T_aux1_vehicle.transform.translation.x -
281 T_ant_vehicle.transform.translation.x;
282 settings_.heading_offset =
284 double dz = T_aux1_vehicle.transform.translation.z -
285 T_ant_vehicle.transform.translation.z;
293 param(
"ins_spatial_config/imu_orientation/theta_x", settings_.theta_x, 0.0);
294 param(
"ins_spatial_config/imu_orientation/theta_y", settings_.theta_y, 0.0);
295 param(
"ins_spatial_config/imu_orientation/theta_z", settings_.theta_z, 0.0);
297 param(
"ins_spatial_config/ant_lever_arm/x", settings_.ant_lever_x, 0.0);
298 param(
"ins_spatial_config/ant_lever_arm/y", settings_.ant_lever_y, 0.0);
299 param(
"ins_spatial_config/ant_lever_arm/z", settings_.ant_lever_z, 0.0);
301 param(
"ins_spatial_config/poi_lever_arm/delta_x", settings_.poi_x, 0.0);
302 param(
"ins_spatial_config/poi_lever_arm/delta_y", settings_.poi_y, 0.0);
303 param(
"ins_spatial_config/poi_lever_arm/delta_z", settings_.poi_z, 0.0);
305 param(
"ins_spatial_config/vsm_lever_arm/vsm_x", settings_.vsm_x, 0.0);
306 param(
"ins_spatial_config/vsm_lever_arm/vsm_y", settings_.vsm_y, 0.0);
307 param(
"ins_spatial_config/vsm_lever_arm/vsm_z", settings_.vsm_z, 0.0);
309 param(
"att_offset/heading", settings_.heading_offset, 0.0);
310 param(
"att_offset/pitch", settings_.pitch_offset, 0.0);
313 if (settings_.use_ros_axis_orientation)
317 settings_.theta_y *= -1.0;
318 settings_.theta_z *= -1.0;
319 settings_.ant_lever_y *= -1.0;
320 settings_.ant_lever_z *= -1.0;
321 settings_.poi_y *= -1.0;
322 settings_.poi_z *= -1.0;
323 settings_.vsm_y *= -1.0;
324 settings_.vsm_z *= -1.0;
325 settings_.heading_offset *= -1.0;
326 settings_.pitch_offset *= -1.0;
329 if (std::abs(settings_.heading_offset) > std::numeric_limits<double>::epsilon())
331 if (settings_.publish_atteuler)
335 "Pitch angle output by topic /atteuler is a tilt angle rotated by " +
336 std::to_string(settings_.heading_offset) +
".");
338 if (settings_.publish_pose && (settings_.septentrio_receiver_type ==
"gnss"))
342 "Pitch angle output by topic /pose is a tilt angle rotated by " +
343 std::to_string(settings_.heading_offset) +
".");
348 "IMU roll offset: " + std::to_string(settings_.theta_x));
350 "IMU pitch offset: " + std::to_string(settings_.theta_y));
352 "IMU yaw offset: " + std::to_string(settings_.theta_z));
354 "Ant heading offset: " + std::to_string(settings_.heading_offset));
356 "Ant pitch offset: " + std::to_string(settings_.pitch_offset));
359 param(
"ins_initial_heading", settings_.ins_initial_heading, std::string(
"auto"));
362 param(
"ins_std_dev_mask/att_std_dev", settings_.att_std_dev, 5.0f);
363 param(
"ins_std_dev_mask/pos_std_dev", settings_.pos_std_dev, 10.0f);
366 param(
"ins_use_poi", settings_.ins_use_poi,
false);
368 if (settings_.publish_tf && !settings_.ins_use_poi)
372 "If tf shall be published, ins_use_poi has to be set to true! It is set automatically to true.");
373 settings_.ins_use_poi =
true;
378 for (uint8_t i = 1; i < 4; ++i)
381 std::string ntrip =
"ntrip_" + std::to_string(i);
383 param(
"rtk_settings/" + ntrip +
"/id", ntripSettings.
id, std::string());
384 if (ntripSettings.
id.empty())
387 param(
"rtk_settings/" + ntrip +
"/caster", ntripSettings.
caster,
389 getUint32Param(
"rtk_settings/" + ntrip +
"/caster_port",
390 ntripSettings.
caster_port,
static_cast<uint32_t
>(0));
391 param(
"rtk_settings/" + ntrip +
"/username", ntripSettings.
username,
393 if (!
param(
"rtk_settings/" + ntrip +
"/password", ntripSettings.
password,
397 getUint32Param(
"rtk_settings/" + ntrip +
"/password", pwd_tmp,
398 static_cast<uint32_t
>(0));
399 ntripSettings.
password = std::to_string(pwd_tmp);
401 param(
"rtk_settings/" + ntrip +
"/mountpoint", ntripSettings.
mountpoint,
403 param(
"rtk_settings/" + ntrip +
"/version", ntripSettings.
version,
405 param(
"rtk_settings/" + ntrip +
"/tls", ntripSettings.
tls,
false);
406 if (ntripSettings.
tls)
407 param(
"rtk_settings/" + ntrip +
"/fingerprint",
410 std::string(
"auto"));
411 param(
"rtk_settings/" + ntrip +
"/send_gga", ntripSettings.
send_gga,
412 std::string(
"auto"));
415 param(
"rtk_settings/" + ntrip +
"/keep_open", ntripSettings.
keep_open,
true);
417 settings_.rtk_settings.ntrip.push_back(ntripSettings);
420 for (uint8_t i = 1; i < 6; ++i)
423 std::string ips =
"ip_server_" + std::to_string(i);
425 param(
"rtk_settings/" + ips +
"/id", ipSettings.
id, std::string(
""));
426 if (ipSettings.
id.empty())
429 getUint32Param(
"rtk_settings/" + ips +
"/port", ipSettings.
port,
430 static_cast<uint32_t
>(0));
432 std::string(
"auto"));
433 param(
"rtk_settings/" + ips +
"/send_gga", ipSettings.
send_gga,
434 std::string(
"auto"));
437 param(
"rtk_settings/" + ips +
"/keep_open", ipSettings.
keep_open,
true);
439 settings_.rtk_settings.ip_server.push_back(ipSettings);
442 for (uint8_t i = 1; i < 6; ++i)
445 std::string serial =
"serial_" + std::to_string(i);
447 param(
"rtk_settings/" + serial +
"/port", serialSettings.
port,
449 if (serialSettings.
port.empty())
452 getUint32Param(
"rtk_settings/" + serial +
"/baud_rate",
453 serialSettings.
baud_rate,
static_cast<uint32_t
>(115200));
454 param(
"rtk_settings/" + serial +
"/rtk_standard",
456 param(
"rtk_settings/" + serial +
"/send_gga", serialSettings.
send_gga,
457 std::string(
"auto"));
458 if (serialSettings.
send_gga.empty())
460 param(
"rtk_settings/" + serial +
"/keep_open", serialSettings.
keep_open,
463 settings_.rtk_settings.serial.push_back(serialSettings);
468 std::string tempString;
471 param(
"ntrip_settings/mode", tempString, std::string(
""));
472 if (tempString !=
"")
475 "Deprecation warning: parameter ntrip_settings/mode has been removed, see README under section rtk_settings.");
476 param(
"ntrip_settings/caster", tempString, std::string(
""));
477 if (tempString !=
"")
480 "Deprecation warning: parameter ntrip_settings/caster has been removed, see README under section rtk_settings.");
481 param(
"ntrip_settings/rx_has_internet", tempBool,
false);
485 "Deprecation warning: parameter ntrip_settings/rx_has_internet has been removed, see README under section rtk_settings.");
486 param(
"ntrip_settings/rx_input_corrections_tcp", tempInt, 0);
490 "Deprecation warning: parameter ntrip_settings/rx_input_corrections_tcp has been removed, see README under section rtk_settings.");
491 param(
"ntrip_settings/rx_input_corrections_serial", tempString,
493 if (tempString !=
"")
496 "Deprecation warning: parameter ntrip_settings/rx_input_corrections_serial has been removed, see README under section rtk_settings.");
499 if (settings_.publish_atteuler)
501 if (!settings_.multi_antenna)
505 "AttEuler needs multi-antenna receiver. Multi-antenna setting automatically activated. Deactivate publishing of AttEuler if multi-antenna operation is not available.");
506 settings_.multi_antenna =
true;
511 if (settings_.septentrio_receiver_type ==
"ins")
513 param(
"ins_vsm/ros/source", settings_.ins_vsm_ros_source, std::string(
""));
515 bool ins_use_vsm =
false;
516 ins_use_vsm = ((settings_.ins_vsm_ros_source ==
"odometry") ||
517 (settings_.ins_vsm_ros_source ==
"twist"));
518 if (!settings_.ins_vsm_ros_source.empty() && !ins_use_vsm)
520 settings_.ins_vsm_ros_source +
521 " -> VSM input will not be used!");
522 param(
"ins_vsm/ip_server/id", settings_.ins_vsm_ip_server_id,
524 if (!settings_.ins_vsm_ip_server_id.empty())
526 getUint32Param(
"ins_vsm/ip_server/port",
527 settings_.ins_vsm_ip_server_port,
528 static_cast<uint32_t
>(0));
529 param(
"ins_vsm/ip_server/keep_open",
530 settings_.ins_vsm_ip_server_keep_open,
true);
533 "external velocity sensor measurements via ip_server are used.");
536 param(
"ins_vsm/serial/port", settings_.ins_vsm_serial_port, std::string(
""));
537 if (!settings_.ins_vsm_serial_port.empty())
539 getUint32Param(
"ins_vsm/serial/baud_rate",
540 settings_.ins_vsm_serial_baud_rate,
541 static_cast<uint32_t
>(115200));
542 param(
"ins_vsm/serial/keep_open", settings_.ins_vsm_serial_keep_open,
545 "external velocity sensor measurements via serial are used.");
548 param(
"ins_vsm/ros/config", settings_.ins_vsm_ros_config,
549 std::vector<bool>());
550 if (ins_use_vsm && (settings_.ins_vsm_ros_config.size() == 3))
552 if (std::all_of(settings_.ins_vsm_ros_config.begin(),
553 settings_.ins_vsm_ros_config.end(),
554 [](
bool v) { return !v; }))
559 "all elements of ins_vsm/ros/config have been set to false -> VSM input will not be used!");
562 param(
"ins_vsm/ros/variances_by_parameter",
563 settings_.ins_vsm_ros_variances_by_parameter,
false);
564 if (settings_.ins_vsm_ros_variances_by_parameter)
566 param(
"ins_vsm/ros/variances", settings_.ins_vsm_ros_variances,
567 std::vector<double>());
568 if (settings_.ins_vsm_ros_variances.size() != 3)
572 "ins_vsm/ros/variances has to be of size 3 for var_x, var_y, and var_z -> VSM input will not be used!");
574 settings_.ins_vsm_ros_source =
"";
577 for (
size_t i = 0; i < settings_.ins_vsm_ros_config.size();
580 if (settings_.ins_vsm_ros_config[i] &&
581 (settings_.ins_vsm_ros_variances[i] <= 0.0))
585 "ins_vsm/ros/config of element " +
587 " has been set to be used but its variance is not > 0.0 -> its VSM input will not be used!");
588 settings_.ins_vsm_ros_config[i] =
false;
592 if (std::all_of(settings_.ins_vsm_ros_config.begin(),
593 settings_.ins_vsm_ros_config.end(),
594 [](
bool v) { return !v; }))
597 settings_.ins_vsm_ros_source =
"";
600 "all elements of ins_vsm/ros/config have been set to false due to invalid covariances -> VSM input will not be used!");
604 }
else if (ins_use_vsm)
606 settings_.ins_vsm_ros_source =
"";
609 "ins_vsm/ros/config has to be of size 3 to signal wether to use v_x, v_y, and v_z -> VSM input will not be used!");
614 settings_.ins_vsm_ros_source +
616 registerSubscriber();
627 return ((period == 0) || ((period == 5 && isIns)) || (period == 10) ||
628 (period == 20) || (period == 40) || (period == 50) || (period == 100) ||
629 (period == 200) || (period == 500) || (period == 1000) ||
630 (period == 2000) || (period == 5000) || (period == 10000) ||
631 (period == 15000) || (period == 30000) || (period == 60000) ||
632 (period == 120000) || (period == 300000) || (period == 600000) ||
633 (period == 900000) || (period == 1800000) || (period == 3600000));
637 const std::string& sourceFrame,
646 T_s_t = tfBuffer_.lookupTransform(targetFrame, sourceFrame,
ros::Time(0),
651 this->log(
LogLevel::WARN,
"Waiting for transform from " + sourceFrame +
652 " to " + targetFrame +
": " + ex.what() +
660 double& pitch,
double& yaw)
662 Eigen::Quaterniond q(qm.w, qm.x, qm.y, qm.z);
663 Eigen::Quaterniond::RotationMatrixType C = q.matrix();
665 roll = std::atan2(C(2, 1), C(2, 2));
666 pitch = std::asin(-C(2, 0));
667 yaw = std::atan2(C(1, 0), C(0, 0));
672 IO_.sendVelocity(velNmea);