35 #include "novatel_oem7_msgs/SolutionStatus.h"
36 #include "novatel_oem7_msgs/PositionOrVelocityType.h"
37 #include "novatel_oem7_msgs/BESTGNSSPOS.h"
38 #include "novatel_oem7_msgs/BESTPOS.h"
39 #include "novatel_oem7_msgs/BESTUTM.h"
40 #include "novatel_oem7_msgs/BESTVEL.h"
41 #include "novatel_oem7_msgs/PPPPOS.h"
42 #include "novatel_oem7_msgs/AccessStatus.h"
43 #include "novatel_oem7_msgs/GeogatingStatus.h"
44 #include "novatel_oem7_msgs/LocalAreaStatus.h"
45 #include "novatel_oem7_msgs/RegionRestriction.h"
46 #include "novatel_oem7_msgs/SubscriptionPermission.h"
47 #include "novatel_oem7_msgs/SubscriptionType.h"
48 #include "novatel_oem7_msgs/SyncState.h"
49 #include "novatel_oem7_msgs/TERRASTARINFO.h"
50 #include "novatel_oem7_msgs/TERRASTARSTATUS.h"
51 #include "novatel_oem7_msgs/INSPVA.h"
52 #include "novatel_oem7_msgs/INSPVAX.h"
54 #include "nav_msgs/Odometry.h"
55 #include "gps_common/GPSFix.h"
56 #include "sensor_msgs/NavSatFix.h"
57 #include "geometry_msgs/Point.h"
76 return radians * 180.0 / M_PI;
86 return degrees * M_PI / 180.0;
98 std::pow(lat_stdev, 2) +
99 std::pow(lon_stdev, 2) +
100 std::pow(hgt_stdev, 2)
112 return 2.0 * std::sqrt(
113 std::pow(lat_stdev, 2) +
114 std::pow(lon_stdev, 2));
123 return 2.0 * hgt_stdev;
132 return 0.833 * (lat_stdev + lon_stdev + hgt_stdev);
145 switch(bestpos->pos_type.type)
147 case novatel_oem7_msgs::PositionOrVelocityType::PSRDIFF:
148 case novatel_oem7_msgs::PositionOrVelocityType::INS_PSRDIFF:
149 case novatel_oem7_msgs::PositionOrVelocityType::L1_FLOAT:
150 case novatel_oem7_msgs::PositionOrVelocityType::NARROW_FLOAT:
151 case novatel_oem7_msgs::PositionOrVelocityType::L1_INT:
152 case novatel_oem7_msgs::PositionOrVelocityType::WIDE_INT:
153 case novatel_oem7_msgs::PositionOrVelocityType::NARROW_INT:
154 case novatel_oem7_msgs::PositionOrVelocityType::RTK_DIRECT_INS:
155 case novatel_oem7_msgs::PositionOrVelocityType::INS_RTKFLOAT:
156 case novatel_oem7_msgs::PositionOrVelocityType::INS_RTKFIXED:
157 return gps_common::GPSStatus::STATUS_DGPS_FIX;
159 case novatel_oem7_msgs::PositionOrVelocityType::FIXEDPOS:
160 case novatel_oem7_msgs::PositionOrVelocityType::FIXEDHEIGHT:
161 case novatel_oem7_msgs::PositionOrVelocityType::DOPPLER_VELOCITY:
162 case novatel_oem7_msgs::PositionOrVelocityType::SINGLE:
163 case novatel_oem7_msgs::PositionOrVelocityType::INS_PSRSP:
164 case novatel_oem7_msgs::PositionOrVelocityType::PROPAGATED:
165 case novatel_oem7_msgs::PositionOrVelocityType::OPERATIONAL:
166 case novatel_oem7_msgs::PositionOrVelocityType::WARNING:
167 case novatel_oem7_msgs::PositionOrVelocityType::OUT_OF_BOUNDS:
168 return gps_common::GPSStatus::STATUS_FIX;
170 case novatel_oem7_msgs::PositionOrVelocityType::WAAS:
171 case novatel_oem7_msgs::PositionOrVelocityType::INS_SBAS:
172 case novatel_oem7_msgs::PositionOrVelocityType::PPP_CONVERGING:
173 case novatel_oem7_msgs::PositionOrVelocityType::PPP:
174 case novatel_oem7_msgs::PositionOrVelocityType::INS_PPP_CONVERGING:
175 case novatel_oem7_msgs::PositionOrVelocityType::INS_PPP:
176 case novatel_oem7_msgs::PositionOrVelocityType::PPP_BASIC_CONVERGING:
177 case novatel_oem7_msgs::PositionOrVelocityType::PPP_BASIC:
178 case novatel_oem7_msgs::PositionOrVelocityType::INS_PPP_BASIC_CONVERGING:
179 case novatel_oem7_msgs::PositionOrVelocityType::INS_PPP_BASIC:
180 return gps_common::GPSStatus::STATUS_SBAS_FIX;
182 case novatel_oem7_msgs::PositionOrVelocityType::NONE:
183 return gps_common::GPSStatus::STATUS_NO_FIX;
186 ROS_ERROR_STREAM(
"Unknown OEM7 PositionOrVelocityType: " << bestpos->pos_type.type);
187 return gps_common::GPSStatus::STATUS_NO_FIX;
198 static const double SECONDS_IN_GPS_WEEK = 604800.0;
199 static const double MILLISECONDS_IN_SECOND = 1000.0;
201 return gps_week * SECONDS_IN_GPS_WEEK +
202 gps_milliseconds / MILLISECONDS_IN_SECOND;
222 novatel_oem7_msgs::Oem7Header msg_hdr_1,
223 novatel_oem7_msgs::Oem7Header msg_hdr_2)
225 if(msg_hdr_1.gps_week_number > msg_hdr_2.gps_week_number)
228 if(msg_hdr_1.gps_week_number == msg_hdr_2.gps_week_number)
230 if(msg_hdr_1.gps_week_milliseconds > msg_hdr_2.gps_week_milliseconds)
233 if(msg_hdr_1.gps_week_milliseconds == msg_hdr_1.gps_week_milliseconds)
248 switch(covariance_type)
250 case gps_common::GPSFix::COVARIANCE_TYPE_APPROXIMATED:
251 return sensor_msgs::NavSatFix::COVARIANCE_TYPE_APPROXIMATED;
253 case gps_common::GPSFix::COVARIANCE_TYPE_DIAGONAL_KNOWN:
254 return sensor_msgs::NavSatFix::COVARIANCE_TYPE_DIAGONAL_KNOWN;
256 case gps_common::GPSFix::COVARIANCE_TYPE_KNOWN:
257 return sensor_msgs::NavSatFix::COVARIANCE_TYPE_KNOWN;
259 case gps_common::GPSFix::COVARIANCE_TYPE_UNKNOWN:
260 return sensor_msgs::NavSatFix::COVARIANCE_TYPE_UNKNOWN;
264 return sensor_msgs::NavSatFix::COVARIANCE_TYPE_UNKNOWN;
273 case gps_common::GPSStatus::STATUS_NO_FIX:
274 return sensor_msgs::NavSatStatus::STATUS_NO_FIX;
276 case gps_common::GPSStatus::STATUS_FIX:
277 return sensor_msgs::NavSatStatus::STATUS_FIX;
279 case gps_common::GPSStatus::STATUS_SBAS_FIX:
280 case gps_common::GPSStatus::STATUS_WAAS_FIX:
281 return sensor_msgs::NavSatStatus::STATUS_SBAS_FIX;
283 case gps_common::GPSStatus::STATUS_DGPS_FIX:
284 case gps_common::GPSStatus::STATUS_GBAS_FIX:
285 return sensor_msgs::NavSatStatus::STATUS_GBAS_FIX;
289 return gps_common::GPSStatus::STATUS_NO_FIX;
297 uint16_t service = 0;
299 if(bestpos->gps_glonass_sig_mask & 0x07)
301 service |= sensor_msgs::NavSatStatus::SERVICE_GPS;
304 if(bestpos->gps_glonass_sig_mask & 0x70)
306 service |= sensor_msgs::NavSatStatus::SERVICE_GLONASS;
309 if(bestpos->galileo_beidou_sig_mask & 0x0F)
311 service |= sensor_msgs::NavSatStatus::SERVICE_GALILEO;
314 if(bestpos->galileo_beidou_sig_mask & 0x70)
316 service |= sensor_msgs::NavSatStatus::SERVICE_COMPASS;
326 geometry_msgs::Point& pt,
342 switch(status.status)
344 case novatel_oem7_msgs::InertialSolutionStatus::INS_HIGH_VARIANCE:
345 case novatel_oem7_msgs::InertialSolutionStatus::INS_SOLUTION_GOOD:
346 case novatel_oem7_msgs::InertialSolutionStatus::INS_SOLUTION_FREE:
347 case novatel_oem7_msgs::InertialSolutionStatus::INS_ALIGNMENT_COMPLETE:
415 int64_t& last_msg_msec,
419 if(last_msg_msec > 0)
421 int32_t period = cur_msg_msec - last_msg_msec;
428 ROS_ERROR_STREAM(
"updatePeriod: msg= " << msg->nov_header.message_id <<
"; per= " << period <<
"; ignored.");
432 last_msg_msec = cur_msg_msec;
499 gpsfix_->status.position_source = gps_common::GPSStatus::SOURCE_NONE;
500 gpsfix_->status.orientation_source = gps_common::GPSStatus::SOURCE_NONE;
501 gpsfix_->status.motion_source = gps_common::GPSStatus::SOURCE_NONE;
502 gpsfix_->position_covariance_type = gps_common::GPSFix::COVARIANCE_TYPE_UNKNOWN;
517 gpsfix_->position_covariance_type = gps_common::GPSFix::COVARIANCE_TYPE_DIAGONAL_KNOWN;
524 bestpos_->nov_header.gps_week_number,
525 bestpos_->nov_header.gps_week_milliseconds);
532 gpsfix_->status.position_source = gps_common::GPSStatus::SOURCE_GPS;
544 bestvel_->nov_header.gps_week_number,
545 bestvel_->nov_header.gps_week_milliseconds);
548 if(
bestvel_->vel_type.type == novatel_oem7_msgs::PositionOrVelocityType::DOPPLER_VELOCITY)
550 gpsfix_->status.motion_source |= gps_common::GPSStatus::SOURCE_DOPPLER;
554 gpsfix_->status.motion_source |= gps_common::GPSStatus::SOURCE_POINTS;
566 gpsfix_->status.position_source |= (gps_common::GPSStatus::SOURCE_GYRO | gps_common::GPSStatus::SOURCE_ACCEL);
567 gpsfix_->status.orientation_source = (gps_common::GPSStatus::SOURCE_GYRO | gps_common::GPSStatus::SOURCE_ACCEL);
568 gpsfix_->status.motion_source = (gps_common::GPSStatus::SOURCE_GYRO | gps_common::GPSStatus::SOURCE_ACCEL);
572 inspva_->nov_header.gps_week_number,
573 inspva_->nov_header.gps_week_milliseconds);
592 static const float ACCURACY_MARGIN_FACTOR = 1.1;
600 bestpos_->hgt_stdev) * ACCURACY_MARGIN_FACTOR;
607 static bool prev_prefer_INS =
false;
608 if(prev_prefer_INS != prefer_INS)
611 <<
" --> " << prefer_INS
613 <<
inspva_->nov_header.gps_week_number <<
" "
614 <<
inspva_->nov_header.gps_week_milliseconds <<
"]"
617 prev_prefer_INS = prefer_INS;
639 gpsfix_->status.position_source |= (gps_common::GPSStatus::SOURCE_GYRO | gps_common::GPSStatus::SOURCE_ACCEL);
644 gpsfix_->position_covariance[0] = std::pow(
inspvax_->longitude_stdev, 2);
645 gpsfix_->position_covariance[4] = std::pow(
inspvax_->latitude_stdev, 2);
647 gpsfix_->position_covariance_type = gps_common::GPSFix::COVARIANCE_TYPE_DIAGONAL_KNOWN;
662 gpsfix_->speed = std::sqrt(std::pow(
inspva_->north_velocity, 2.0) +
663 std::pow(
inspva_->east_velocity, 2.0));
699 navsatfix->latitude =
gpsfix_->latitude;
700 navsatfix->longitude =
gpsfix_->longitude;
703 navsatfix->position_covariance[0] =
gpsfix_->position_covariance[0];
704 navsatfix->position_covariance[4] =
gpsfix_->position_covariance[4];
705 navsatfix->position_covariance[8] =
gpsfix_->position_covariance[8];
722 odometry->pose.pose.position,
727 odometry->pose.covariance[ 0] =
gpsfix_->position_covariance[0];
728 odometry->pose.covariance[ 7] =
gpsfix_->position_covariance[4];
729 odometry->pose.covariance[14] =
gpsfix_->position_covariance[8];
746 tf2::Vector3 local_frame_velocity = velocity_transform.inverse()(tf2::Vector3(
inspva_->east_velocity,
inspva_->north_velocity,
inspva_->up_velocity));
748 odometry->pose.pose.orientation =
tf2::toMsg(ros_orientation);
749 tf2::convert(local_frame_velocity, odometry->twist.twist.linear);
755 odometry->pose.covariance[21] = std::pow(
inspvax_->roll_stdev, 2);
756 odometry->pose.covariance[28] = std::pow(
inspvax_->pitch_stdev, 2);
757 odometry->pose.covariance[35] = std::pow(
inspvax_->azimuth_stdev, 2);
759 odometry->twist.covariance[0] = std::pow(
inspvax_->north_velocity_stdev, 2);
760 odometry->twist.covariance[7] = std::pow(
inspvax_->east_velocity_stdev, 2);
761 odometry->twist.covariance[14] = std::pow(
inspvax_->up_velocity_stdev, 2);
813 std::string position_source;
814 nh.
getParam(
"position_source", position_source);
815 if(position_source ==
"BESTPOS")
819 else if(position_source ==
"INSPVAS")
825 position_source =
"BESTPOS or INSPVAS based on quality";
832 static const std::vector<int> MSG_IDS(
848 void handleMsg(Oem7RawMessageIf::ConstPtr msg)
912 MakeROSMessage<novatel_oem7_msgs::INSPVAX>(msg,
inspvax_);