From 918c42fb774b94eb87d2ca9a74a9cc7775e50514 Mon Sep 17 00:00:00 2001 From: James Jackson Date: Fri, 19 Oct 2018 15:17:49 -0600 Subject: [PATCH 01/13] update to 1.7.0 - changed GPS message to reflect published ECEF velocity --- include/inertial_sense.h | 6 ++- lib/InertialSenseSDK | 2 +- msg/GPS.msg | 3 +- src/inertial_sense.cpp | 98 ++++++++++++++++++++++++---------------- 4 files changed, 68 insertions(+), 41 deletions(-) diff --git a/include/inertial_sense.h b/include/inertial_sense.h index ca4abd0..6ca45a7 100644 --- a/include/inertial_sense.h +++ b/include/inertial_sense.h @@ -20,6 +20,7 @@ #include "nav_msgs/Odometry.h" #include "std_srvs/Trigger.h" #include "std_msgs/Header.h" +#include "geometry_msgs/Vector3Stamped.h" # define GPS_UNIX_OFFSET 315964800 // GPS time started on 6/1/1980 while UNIX time started 1/1/1970 this is the difference between those in seconds # define LEAP_SECONDS 18 // GPS time does not have leap seconds, UNIX does (as of 1/1/2017 - next one is probably in 2020 sometime unless there is some crazy earthquake or nuclear blast) @@ -76,7 +77,8 @@ class InertialSenseROS //: SerialListener void IMU_callback(const dual_imu_t* const msg); ros_stream_t GPS_; - void GPS_callback(const gps_nav_t* const msg); + void GPS_Pos_callback(const gps_pos_t* const msg); + void GPS_Vel_callback(const gps_vel_t* const msg); ros_stream_t GPS_info_; void GPS_Info_callback(const gps_sat_t* const msg); @@ -102,6 +104,7 @@ class InertialSenseROS //: SerialListener bool perform_multi_mag_cal_srv_callback(std_srvs::Trigger::Request & req, std_srvs::Trigger::Response & res); bool update_firmware_srv_callback(inertial_sense::FirmwareUpdate::Request & req, inertial_sense::FirmwareUpdate::Response & res); + void publishGPS(); /** * @brief ros_time_from_week_and_tow @@ -137,6 +140,7 @@ class InertialSenseROS //: SerialListener sensor_msgs::Imu imu1_msg, imu2_msg; nav_msgs::Odometry odom_msg; inertial_sense::GPS gps_msg; + geometry_msgs::Vector3Stamped gps_velEcef; inertial_sense::GPSInfo gps_info_msg; ros::NodeHandle nh_; diff --git a/lib/InertialSenseSDK b/lib/InertialSenseSDK index c02331f..c1affd3 160000 --- a/lib/InertialSenseSDK +++ b/lib/InertialSenseSDK @@ -1 +1 @@ -Subproject commit c02331fab7299c6df004e28b1bc603aaaba9cb8e +Subproject commit c1affd3a9d0acf04cb415647589ac34ffa408c7e diff --git a/msg/GPS.msg b/msg/GPS.msg index 86e6beb..8840729 100644 --- a/msg/GPS.msg +++ b/msg/GPS.msg @@ -17,7 +17,8 @@ int32 cno # mean carrier noise ratio (dBHz) float64 latitude # latitude (degrees) float64 longitude # longitude (degrees) float64 altitude # height above ellipsoid (not MSL) (m) -geometry_msgs/Vector3 linear_velocity # Velocity (m/s) in NED +geometry_msgs/Vector3 posEcef # Position (m) in ECEF +geometry_msgs/Vector3 velEcef # Velocity (m/s) in ECEF float32 hMSL # height above MSL float32 hAcc # horizontal accuracy float32 vAcc # vertical accuracy diff --git a/src/inertial_sense.cpp b/src/inertial_sense.cpp index 4919e5f..2235a05 100644 --- a/src/inertial_sense.cpp +++ b/src/inertial_sense.cpp @@ -15,7 +15,7 @@ InertialSenseROS::InertialSenseROS() : nh_private_.param("baudrate", baudrate_, 3000000); nh_private_.param("frame_id", frame_id_, "body"); - /// Connect to the uINS + /// Connect to the uINS ROS_INFO("Connecting to serial port \"%s\", at %d baud", port_.c_str(), baudrate_); if (! IS_.Open(port_.c_str(), baudrate_)) { @@ -68,7 +68,7 @@ InertialSenseROS::InertialSenseROS() : set_vector_flash_config("GPS_ant_xyz", 3, offsetof(nvm_flash_cfg_t, gps1AntOffset)); set_vector_flash_config("GPS_ref_lla", 3, offsetof(nvm_flash_cfg_t, refLla)); - set_flash_config("inclination", offsetof(nvm_flash_cfg_t, magInclination), 1.14878541071f); + set_flash_config("inclination", offsetof(nvm_flash_cfg_t, magInclination), 1.14878541071f); set_flash_config("declination", offsetof(nvm_flash_cfg_t, magDeclination), 0.20007290992f); set_flash_config("dynamic_model", offsetof(nvm_flash_cfg_t, insDynModel), 8); set_flash_config("ser1_baud_rate", offsetof(nvm_flash_cfg_t, ser1BaudRate), 115200); @@ -78,8 +78,9 @@ InertialSenseROS::InertialSenseROS() : /// DATA STREAMS CONFIGURATION ///////////////////////////////////////////////////////// - uint32_t rmcBits = RMC_BITS_GPS_NAV | RMC_BITS_STROBE_IN_TIME; - SET_CALLBACK(DID_GPS_NAV, flash_config_.startupGPSDtMs, gps_nav_t, GPS_callback); // we always need GPS for Fix status + uint32_t rmcBits = RMC_BITS_GPS1_POS | RMC_BITS_GPS1_VEL | RMC_BITS_STROBE_IN_TIME; + SET_CALLBACK(DID_GPS1_POS, flash_config_.startupGPSDtMs, gps_pos_t, GPS_Pos_callback); // we always need GPS for Fix status + SET_CALLBACK(DID_GPS1_VEL, flash_config_.startupGPSDtMs, gps_vel_t, GPS_Vel_callback); // we always need GPS for Fix status SET_CALLBACK(DID_STROBE_IN_TIME, 100, strobe_in_time_t, strobe_in_time_callback); // we always want the strobe nh_private_.param("stream_INS", INS_.enabled, true); if (INS_.enabled) @@ -107,7 +108,7 @@ InertialSenseROS::InertialSenseROS() : nh_private_.param("stream_GPS", GPS_.enabled, false); if (GPS_.enabled) { - GPS_.pub = nh_.advertise("gps", 1); + GPS_.pub = nh_.advertise("gps", 1); } // Set up the GPS info ROS stream @@ -124,7 +125,7 @@ InertialSenseROS::InertialSenseROS() : if (mag_.enabled) { mag_.pub = nh_.advertise("mag", 1); -// mag_.pub2 = nh_.advertise("mag2", 1); + // mag_.pub2 = nh_.advertise("mag2", 1); SET_CALLBACK(DID_MAGNETOMETER_1, nav_dt_ms, magnetometer_t, mag_callback); rmcBits |= RMC_BITS_MAGNETOMETER1; } @@ -152,7 +153,7 @@ InertialSenseROS::InertialSenseROS() : ///////////////////////////////////////////////////////// /// ASCII OUTPUT CONFIGURATION ///////////////////////////////////////////////////////// - + int NMEA_rate = nh_private_.param("NMEA_rate", 0); int NMEA_message_configuration = nh_private_.param("NMEA_configuration", 0x00); int NMEA_message_ports = nh_private_.param("NMEA_ports", 0x00); @@ -226,13 +227,13 @@ void InertialSenseROS::INS_variance_callback(const inl2_variance_t * const msg) } odom_msg.pose.covariance[7*(i+3)] = msg->PattNED[i]; odom_msg.twist.covariance[7*(i+3)] = msg->PWBias[i]; - } + } } void InertialSenseROS::INS2_callback(const ins_2_t * const msg) { - insStatus_ = msg->insStatus; + insStatus_ = msg->insStatus; odom_msg.header.stamp = ros_time_from_week_and_tow(msg->week, msg->timeOfWeek); odom_msg.header.frame_id = frame_id_; @@ -265,28 +266,28 @@ void InertialSenseROS::IMU_callback(const dual_imu_t* const msg) imu1_msg.linear_acceleration.y = msg->I[0].acc[1]; imu1_msg.linear_acceleration.z = msg->I[0].acc[2]; -// imu2_msg.angular_velocity.x = msg->I[1].pqr[0]; -// imu2_msg.angular_velocity.y = msg->I[1].pqr[1]; -// imu2_msg.angular_velocity.z = msg->I[1].pqr[2]; -// imu2_msg.linear_acceleration.x = msg->I[1].acc[0]; -// imu2_msg.linear_acceleration.y = msg->I[1].acc[1]; -// imu2_msg.linear_acceleration.z = msg->I[1].acc[2]; + // imu2_msg.angular_velocity.x = msg->I[1].pqr[0]; + // imu2_msg.angular_velocity.y = msg->I[1].pqr[1]; + // imu2_msg.angular_velocity.z = msg->I[1].pqr[2]; + // imu2_msg.linear_acceleration.x = msg->I[1].acc[0]; + // imu2_msg.linear_acceleration.y = msg->I[1].acc[1]; + // imu2_msg.linear_acceleration.z = msg->I[1].acc[2]; if (IMU_.enabled) { IMU_.pub.publish(imu1_msg); -// IMU_.pub2.publish(imu2_msg); + // IMU_.pub2.publish(imu2_msg); } } -void InertialSenseROS::GPS_callback(const gps_nav_t * const msg) +void InertialSenseROS::GPS_Pos_callback(const gps_pos_t * const msg) { GPS_week_ = msg->week; GPS_towOffset_ = msg->towOffset; if (GPS_.enabled) { - gps_msg.header.stamp = ros_time_from_week_and_tow(msg->week, msg->towOffset); + gps_msg.header.stamp = ros_time_from_week_and_tow(msg->week, msg->timeOfWeekMs/1e3); gps_msg.fix_type = msg->status & GPS_STATUS_FIX_MASK; gps_msg.header.frame_id =frame_id_; gps_msg.num_sat = (uint8_t)(msg->status & GPS_STATUS_NUM_SATS_USED_MASK); @@ -294,20 +295,41 @@ void InertialSenseROS::GPS_callback(const gps_nav_t * const msg) gps_msg.latitude = msg->lla[0]; gps_msg.longitude = msg->lla[1]; gps_msg.altitude = msg->lla[2]; + gps_msg.posEcef.x = msg->ecef[0]; + gps_msg.posEcef.y = msg->ecef[1]; + gps_msg.posEcef.z = msg->ecef[2]; gps_msg.hMSL = msg->hMSL; gps_msg.hAcc = msg->hAcc; gps_msg.vAcc = msg->vAcc; gps_msg.pDop = msg->pDop; - gps_msg.linear_velocity.x = msg->velNed[0]; - gps_msg.linear_velocity.y = msg->velNed[1]; - gps_msg.linear_velocity.z = msg->velNed[2]; - GPS_.pub.publish(gps_msg); + publishGPS(); } } +void InertialSenseROS::GPS_Vel_callback(const gps_vel_t * const msg) +{ + if (GPS_.enabled) + { + gps_velEcef.header.stamp = ros_time_from_week_and_tow(GPS_week_, msg->timeOfWeekMs/1e3); + gps_velEcef.vector.x = msg->velEcef[0]; + gps_velEcef.vector.y = msg->velEcef[1]; + gps_velEcef.vector.z = msg->velEcef[2]; + publishGPS(); + } +} + +void InertialSenseROS::publishGPS() +{ + if (gps_velEcef.header.stamp == gps_msg.header.stamp) + { + gps_msg.velEcef = gps_velEcef.vector; + GPS_.pub.publish(gps_msg); + } +} + void InertialSenseROS::update() { - IS_.Update(); + IS_.Update(); } void InertialSenseROS::strobe_in_time_callback(const strobe_in_time_t * const msg) @@ -318,7 +340,7 @@ void InertialSenseROS::strobe_in_time_callback(const strobe_in_time_t * const ms std_msgs::Header strobe_msg; strobe_msg.stamp = ros_time_from_week_and_tow(msg->week, msg->timeOfWeekMs * 1e-3); - strobe_pub_.publish(strobe_msg); + strobe_pub_.publish(strobe_msg); } @@ -360,7 +382,7 @@ void InertialSenseROS::baro_callback(const barometer_t * const msg) void InertialSenseROS::preint_IMU_callback(const preintegrated_imu_t * const msg) { - inertial_sense::PreIntIMU preintIMU_msg; + inertial_sense::PreIntIMU preintIMU_msg; preintIMU_msg.header.stamp = ros_time_from_start_time(msg->time); preintIMU_msg.header.frame_id = frame_id_; preintIMU_msg.dtheta.x = msg->theta1[0]; @@ -379,7 +401,7 @@ void InertialSenseROS::preint_IMU_callback(const preintegrated_imu_t * const msg bool InertialSenseROS::perform_mag_cal_srv_callback(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res) { (void)req; - res.success = true; + res.success = true; uint32_t single_axis_command = 1; IS_.SendData(DID_MAG_CAL, reinterpret_cast(&single_axis_command), sizeof(uint32_t), offsetof(mag_cal_t, enMagRecal)); } @@ -387,7 +409,7 @@ bool InertialSenseROS::perform_mag_cal_srv_callback(std_srvs::Trigger::Request & bool InertialSenseROS::perform_multi_mag_cal_srv_callback(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res) { (void)req; - res.success = true; + res.success = true; uint32_t multi_axis_command = 0; IS_.SendData(DID_MAG_CAL, reinterpret_cast(&multi_axis_command), sizeof(uint32_t), offsetof(mag_cal_t, enMagRecal)); } @@ -402,16 +424,16 @@ void InertialSenseROS::reset_device() bool InertialSenseROS::update_firmware_srv_callback(inertial_sense::FirmwareUpdate::Request &req, inertial_sense::FirmwareUpdate::Response &res) { - IS_.Close(); - vector results = IS_.BootloadFile("*", req.filename, 921600); - if (!results[0].error.empty()) - { - res.success = false; - res.message = results[0].error; - return false; - } - IS_.Open(port_.c_str(), baudrate_); - return true; + IS_.Close(); + vector results = IS_.BootloadFile("*", req.filename, 921600); + if (!results[0].error.empty()) + { + res.success = false; + res.message = results[0].error; + return false; + } + IS_.Open(port_.c_str(), baudrate_); + return true; } ros::Time InertialSenseROS::ros_time_from_week_and_tow(const uint32_t week, const double timeOfWeek) @@ -480,7 +502,7 @@ ros::Time InertialSenseROS::ros_time_from_tow(const double tow) int main(int argc, char**argv) - { +{ ros::init(argc, argv, "inertial_sense_node"); InertialSenseROS thing; while (ros::ok()) From 37b2f1330f5d3a2a2b21288fbd2c7b3d95d37690 Mon Sep 17 00:00:00 2001 From: James Jackson Date: Fri, 19 Oct 2018 15:58:06 -0600 Subject: [PATCH 02/13] got RTK base working --- CMakeLists.txt | 2 ++ include/inertial_sense.h | 12 ++++++++++++ msg/RTKCorrection.msg | 6 ++++++ msg/RTKInfo.msg | 10 ++++++++++ src/inertial_sense.cpp | 41 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 71 insertions(+) create mode 100644 msg/RTKCorrection.msg create mode 100644 msg/RTKInfo.msg diff --git a/CMakeLists.txt b/CMakeLists.txt index 639fa18..f1b289a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,8 @@ add_message_files( GPS.msg GPSInfo.msg PreIntIMU.msg + RTKInfo.msg + RTKCorrection.msg ) add_service_files( diff --git a/include/inertial_sense.h b/include/inertial_sense.h index 6ca45a7..08594af 100644 --- a/include/inertial_sense.h +++ b/include/inertial_sense.h @@ -17,6 +17,8 @@ #include "inertial_sense/GPSInfo.h" #include "inertial_sense/PreIntIMU.h" #include "inertial_sense/FirmwareUpdate.h" +#include "inertial_sense/RTKCorrection.h" +#include "inertial_sense/RTKInfo.h" #include "nav_msgs/Odometry.h" #include "std_srvs/Trigger.h" #include "std_msgs/Header.h" @@ -105,6 +107,16 @@ class InertialSenseROS //: SerialListener bool update_firmware_srv_callback(inertial_sense::FirmwareUpdate::Request & req, inertial_sense::FirmwareUpdate::Response & res); void publishGPS(); + + typedef enum + { + RTK_NONE, + RTK_ROVER, + RTK_BASE + } rtk_state_t; + rtk_state_t RTK_state_ = RTK_NONE; + ros_stream_t RTK_info_; + /** * @brief ros_time_from_week_and_tow diff --git a/msg/RTKCorrection.msg b/msg/RTKCorrection.msg new file mode 100644 index 0000000..3f6de95 --- /dev/null +++ b/msg/RTKCorrection.msg @@ -0,0 +1,6 @@ +uint32 RTK_CORRECTION_TYPE_UBLOX = 1 +uint32 RTK_CORRECTION_TYPE_RTCM3 = 2 + +Header header +uint32 correction_type +uint8[] data diff --git a/msg/RTKInfo.msg b/msg/RTKInfo.msg new file mode 100644 index 0000000..13c9c65 --- /dev/null +++ b/msg/RTKInfo.msg @@ -0,0 +1,10 @@ +Header header + +float32[3] BaseLLA # base position in lat-lon-altitude (deg, deg, m) +uint32 cycle_slip_count # number of cycle slips detected +uint32 roverObs # number of observations from rover (GPS, Glonass, Gallileo, Beidou, Qzs) +uint32 baseObs # number of observations from base (GPS, Glonass, Gallileo, Beidou, Qzs) +uint32 roverEph # number of ephemeris messages from rover (GPS, Glonass, Gallileo, Beidou, Qzs) +uint32 baseEph # number of ephemeris messages from rover (GPS, Glonass, Gallileo, Beidou, Qzs) +uint32 baseAntcount # number of base station antenna position measurements + diff --git a/src/inertial_sense.cpp b/src/inertial_sense.cpp index 2235a05..5c1d2c2 100644 --- a/src/inertial_sense.cpp +++ b/src/inertial_sense.cpp @@ -73,6 +73,47 @@ InertialSenseROS::InertialSenseROS() : set_flash_config("dynamic_model", offsetof(nvm_flash_cfg_t, insDynModel), 8); set_flash_config("ser1_baud_rate", offsetof(nvm_flash_cfg_t, ser1BaudRate), 115200); + ///////////////////////////////////////////////////////// + /// RTK Configuration + ///////////////////////////////////////////////////////// + bool RTK_rover, RTK_base; + nh_private_.param("RTK_rover", RTK_rover, false); + nh_private_.param("RTK_base", RTK_base, false); + std::string RTK_server_IP, RTK_correction_type; + int RTK_server_port; + nh_private_.param("RTK_server_IP", RTK_server_IP, "127.0.0.1"); + nh_private_.param("RTK_server_IP", RTK_server_port, 12503); + nh_private_.param("RTK_correction_type", RTK_correction_type, "UBLOX"); + std::string RTK_connection = RTK_server_IP + ":" + std::to_string(RTK_server_port) + ":" + RTK_correction_type; + ROS_ERROR_COND(RTK_rover && RTK_base, "unable to configure uINS to be both RTK rover and base - default to rover"); + + if (RTK_rover) + { + ROS_INFO("InertialSense: Configured as RTK Rover"); + RTK_state_ = RTK_ROVER; + uint32_t RTKCfgBits = RTK_CFG_BITS_GPS1_RTK_ROVER; + IS_.SendData(DID_FLASH_CONFIG, reinterpret_cast(&RTKCfgBits), sizeof(RTKCfgBits), offsetof(nvm_flash_cfg_t, RTKCfgBits)); + + if (IS_.OpenServerConnection(RTK_connection)) + ROS_INFO_STREAM("Successfully connected to " << RTK_connection << " as RTK server"); + else + ROS_ERROR_STREAM("Failed to connect to base server at " << RTK_connection); + RTK_info_.pub = nh_.advertise("RTK_info", 10); + } + + else if (RTK_base) + { + ROS_INFO("InertialSense: Configured as RTK Base"); + RTK_state_ = RTK_BASE; + uint32_t RTKCfgBits = RTK_CFG_BITS_BASE_OUTPUT_GPS1_UBLOX_SER0; + IS_.SendData(DID_FLASH_CONFIG, reinterpret_cast(&RTKCfgBits), sizeof(RTKCfgBits), offsetof(nvm_flash_cfg_t, RTKCfgBits)); + + if (IS_.CreateHost(RTK_connection)) + ROS_INFO_STREAM("Successfully created " << RTK_connection << " as RTK server"); + else + ROS_ERROR_STREAM("Failed to create base server at " << RTK_connection); + } + ///////////////////////////////////////////////////////// /// DATA STREAMS CONFIGURATION From dc4b05678ffdb566c9770110aad9de7314f5d84c Mon Sep 17 00:00:00 2001 From: James Jackson Date: Fri, 19 Oct 2018 16:01:14 -0600 Subject: [PATCH 03/13] turn off other messages when operating as a base --- src/inertial_sense.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/inertial_sense.cpp b/src/inertial_sense.cpp index 5c1d2c2..779f138 100644 --- a/src/inertial_sense.cpp +++ b/src/inertial_sense.cpp @@ -109,7 +109,11 @@ InertialSenseROS::InertialSenseROS() : IS_.SendData(DID_FLASH_CONFIG, reinterpret_cast(&RTKCfgBits), sizeof(RTKCfgBits), offsetof(nvm_flash_cfg_t, RTKCfgBits)); if (IS_.CreateHost(RTK_connection)) + { ROS_INFO_STREAM("Successfully created " << RTK_connection << " as RTK server"); + initialized_ = true; + return; + } else ROS_ERROR_STREAM("Failed to create base server at " << RTK_connection); } From 5192992c5806762dbdc92acd4fe69b9310a7329a Mon Sep 17 00:00:00 2001 From: James Jackson Date: Fri, 19 Oct 2018 16:31:41 -0600 Subject: [PATCH 04/13] got most of the plumbing working, but RTK isn't working --- CMakeLists.txt | 2 +- include/inertial_sense.h | 9 ++++-- msg/RTKCorrection.msg | 6 ---- msg/RTKRel.msg | 6 ++++ src/inertial_sense.cpp | 65 ++++++++++++++++++++++++++++++++++++++-- 5 files changed, 76 insertions(+), 12 deletions(-) delete mode 100644 msg/RTKCorrection.msg create mode 100644 msg/RTKRel.msg diff --git a/CMakeLists.txt b/CMakeLists.txt index f1b289a..826123b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ add_message_files( GPSInfo.msg PreIntIMU.msg RTKInfo.msg - RTKCorrection.msg + RTKRel.msg ) add_service_files( diff --git a/include/inertial_sense.h b/include/inertial_sense.h index 08594af..51f8b2c 100644 --- a/include/inertial_sense.h +++ b/include/inertial_sense.h @@ -17,7 +17,7 @@ #include "inertial_sense/GPSInfo.h" #include "inertial_sense/PreIntIMU.h" #include "inertial_sense/FirmwareUpdate.h" -#include "inertial_sense/RTKCorrection.h" +#include "inertial_sense/RTKRel.h" #include "inertial_sense/RTKInfo.h" #include "nav_msgs/Odometry.h" #include "std_srvs/Trigger.h" @@ -102,6 +102,8 @@ class InertialSenseROS //: SerialListener ros::ServiceServer mag_cal_srv_; ros::ServiceServer multi_mag_cal_srv_; ros::ServiceServer firmware_update_srv_; + ros::ServiceServer refLLA_set_srv_; + bool set_current_position_as_refLLA(std_srvs::Trigger::Request& req, std_srvs::Trigger::Response & res); bool perform_mag_cal_srv_callback(std_srvs::Trigger::Request & req, std_srvs::Trigger::Response & res); bool perform_multi_mag_cal_srv_callback(std_srvs::Trigger::Request & req, std_srvs::Trigger::Response & res); bool update_firmware_srv_callback(inertial_sense::FirmwareUpdate::Request & req, inertial_sense::FirmwareUpdate::Response & res); @@ -115,7 +117,9 @@ class InertialSenseROS //: SerialListener RTK_BASE } rtk_state_t; rtk_state_t RTK_state_ = RTK_NONE; - ros_stream_t RTK_info_; + ros_stream_t RTK_; + void RTK_Misc_callback(const gps_rtk_misc_t* const msg); + void RTK_Rel_callback(const gps_rtk_rel_t* const msg); /** @@ -149,6 +153,7 @@ class InertialSenseROS //: SerialListener bool got_first_message_ = false; // Flag to capture first uINS start time guess // Data to hold on to in between callbacks + double lla_[3]; sensor_msgs::Imu imu1_msg, imu2_msg; nav_msgs::Odometry odom_msg; inertial_sense::GPS gps_msg; diff --git a/msg/RTKCorrection.msg b/msg/RTKCorrection.msg deleted file mode 100644 index 3f6de95..0000000 --- a/msg/RTKCorrection.msg +++ /dev/null @@ -1,6 +0,0 @@ -uint32 RTK_CORRECTION_TYPE_UBLOX = 1 -uint32 RTK_CORRECTION_TYPE_RTCM3 = 2 - -Header header -uint32 correction_type -uint8[] data diff --git a/msg/RTKRel.msg b/msg/RTKRel.msg new file mode 100644 index 0000000..f40e41d --- /dev/null +++ b/msg/RTKRel.msg @@ -0,0 +1,6 @@ +Header header +float32 differential_age # Age of differential (seconds) +float32 ar_ratio # Ambiguity resolution ratio factor for validation +geometry_msgs/Vector3 vector_to_base # Vector to base (m) in ECEF - If Compassing enabled, this is the 3-vector from antenna 2 to antenna 1 +float32 distance_to_base # Distance to Base (m) +float32 heading_to_base # Angle from north to vectorToBase in local tangent plane. (rad) \ No newline at end of file diff --git a/src/inertial_sense.cpp b/src/inertial_sense.cpp index 779f138..75d7ac7 100644 --- a/src/inertial_sense.cpp +++ b/src/inertial_sense.cpp @@ -53,6 +53,7 @@ InertialSenseROS::InertialSenseROS() : } /// Start Up ROS service servers + refLLA_set_srv_ = nh_.advertiseService("set_refLLA", &InertialSenseROS::set_current_position_as_refLLA, this); mag_cal_srv_ = nh_.advertiseService("single_axis_mag_cal", &InertialSenseROS::perform_mag_cal_srv_callback, this); multi_mag_cal_srv_ = nh_.advertiseService("multi_axis_mag_cal", &InertialSenseROS::perform_multi_mag_cal_srv_callback, this); firmware_update_srv_ = nh_.advertiseService("firmware_update", &InertialSenseROS::update_firmware_srv_callback, this); @@ -82,7 +83,7 @@ InertialSenseROS::InertialSenseROS() : std::string RTK_server_IP, RTK_correction_type; int RTK_server_port; nh_private_.param("RTK_server_IP", RTK_server_IP, "127.0.0.1"); - nh_private_.param("RTK_server_IP", RTK_server_port, 12503); + nh_private_.param("RTK_server_port", RTK_server_port, 12503); nh_private_.param("RTK_correction_type", RTK_correction_type, "UBLOX"); std::string RTK_connection = RTK_server_IP + ":" + std::to_string(RTK_server_port) + ":" + RTK_correction_type; ROS_ERROR_COND(RTK_rover && RTK_base, "unable to configure uINS to be both RTK rover and base - default to rover"); @@ -95,10 +96,14 @@ InertialSenseROS::InertialSenseROS() : IS_.SendData(DID_FLASH_CONFIG, reinterpret_cast(&RTKCfgBits), sizeof(RTKCfgBits), offsetof(nvm_flash_cfg_t, RTKCfgBits)); if (IS_.OpenServerConnection(RTK_connection)) - ROS_INFO_STREAM("Successfully connected to " << RTK_connection << " as RTK server"); + ROS_INFO_STREAM("Successfully connected to " << RTK_connection << " RTK server"); else ROS_ERROR_STREAM("Failed to connect to base server at " << RTK_connection); - RTK_info_.pub = nh_.advertise("RTK_info", 10); + + SET_CALLBACK(DID_GPS1_RTK_MISC, nav_dt_ms, gps_rtk_misc_t, RTK_Misc_callback); + SET_CALLBACK(DID_GPS1_RTK_REL, nav_dt_ms, gps_rtk_rel_t, RTK_Rel_callback); + RTK_.pub = nh_.advertise("RTK_info", 10); + RTK_.pub2 = nh_.advertise("RTK_rel", 10); } else if (RTK_base) @@ -291,6 +296,10 @@ void InertialSenseROS::INS2_callback(const ins_2_t * const msg) odom_msg.twist.twist.linear.y = msg->uvw[1]; odom_msg.twist.twist.linear.z = msg->uvw[2]; + lla_[0] = msg->lla[0]; + lla_[1] = msg->lla[1]; + lla_[2] = msg->lla[2]; + odom_msg.twist.twist.angular.x = imu1_msg.angular_velocity.x; odom_msg.twist.twist.angular.y = imu1_msg.angular_velocity.y; odom_msg.twist.twist.angular.z = imu1_msg.angular_velocity.z; @@ -443,6 +452,56 @@ void InertialSenseROS::preint_IMU_callback(const preintegrated_imu_t * const msg dt_vel_.pub.publish(preintIMU_msg); } +void InertialSenseROS::RTK_Misc_callback(const gps_rtk_misc_t* const msg) +{ + if (RTK_.enabled) + { + inertial_sense::RTKInfo rtk_info; + rtk_info.header.stamp = ros_time_from_week_and_tow(GPS_week_, msg->timeOfWeekMs/1000.0); + rtk_info.baseAntcount = msg->baseAntennaCount; + rtk_info.baseEph = msg->baseBeidouEphemerisCount + msg->baseGalileoEphemerisCount + msg->baseGlonassEphemerisCount + + msg->baseGpsEphemerisCount; + rtk_info.baseObs = msg->baseBeidouObservationCount + msg->baseGalileoObservationCount + msg->baseGlonassObservationCount + + msg->baseGpsObservationCount; + rtk_info.BaseLLA[0] = msg->baseLla[0]; + rtk_info.BaseLLA[1] = msg->baseLla[1]; + rtk_info.BaseLLA[2] = msg->baseLla[2]; + + rtk_info.roverEph = msg->roverBeidouEphemerisCount + msg->roverGalileoEphemerisCount + msg->roverGlonassEphemerisCount + + msg->roverGpsEphemerisCount; + rtk_info.roverObs = msg->roverBeidouObservationCount + msg->roverGalileoObservationCount + msg->roverGlonassObservationCount + + msg->roverGpsObservationCount; + rtk_info.cycle_slip_count = msg->cycleSlipCount; + RTK_.pub.publish(rtk_info); + } +} + + +void InertialSenseROS::RTK_Rel_callback(const gps_rtk_rel_t* const msg) +{ + if (RTK_.enabled) + { + inertial_sense::RTKRel rtk_rel; + rtk_rel.header.stamp = ros_time_from_week_and_tow(GPS_week_, msg->timeOfWeekMs/1000.0); + rtk_rel.differential_age = msg->differentialAge; + rtk_rel.ar_ratio = msg->arRatio; + rtk_rel.vector_to_base.x = msg->vectorToBase[0]; + rtk_rel.vector_to_base.y = msg->vectorToBase[1]; + rtk_rel.vector_to_base.z = msg->vectorToBase[2]; + rtk_rel.differential_age = msg->distanceToBase; + rtk_rel.heading_to_base = msg->headingToBase; + RTK_.pub2.publish(rtk_rel); + } + +} + +bool InertialSenseROS::set_current_position_as_refLLA(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res) +{ + (void)req; + res.success = true; + IS_.SendData(DID_FLASH_CONFIG, reinterpret_cast(&lla_), sizeof(lla_), offsetof(nvm_flash_cfg_t, refLla)); +} + bool InertialSenseROS::perform_mag_cal_srv_callback(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res) { (void)req; From 0ee8bdd3715303ce3d7c263985dba3f8ca3329a2 Mon Sep 17 00:00:00 2001 From: James Jackson Date: Fri, 19 Oct 2018 16:38:50 -0600 Subject: [PATCH 05/13] publishing RTK information, but corrections aren't being passed --- src/inertial_sense.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/inertial_sense.cpp b/src/inertial_sense.cpp index 75d7ac7..7e15cf3 100644 --- a/src/inertial_sense.cpp +++ b/src/inertial_sense.cpp @@ -102,12 +102,14 @@ InertialSenseROS::InertialSenseROS() : SET_CALLBACK(DID_GPS1_RTK_MISC, nav_dt_ms, gps_rtk_misc_t, RTK_Misc_callback); SET_CALLBACK(DID_GPS1_RTK_REL, nav_dt_ms, gps_rtk_rel_t, RTK_Rel_callback); + RTK_.enabled = true; RTK_.pub = nh_.advertise("RTK_info", 10); RTK_.pub2 = nh_.advertise("RTK_rel", 10); } else if (RTK_base) { + RTK_.enabled = true; ROS_INFO("InertialSense: Configured as RTK Base"); RTK_state_ = RTK_BASE; uint32_t RTKCfgBits = RTK_CFG_BITS_BASE_OUTPUT_GPS1_UBLOX_SER0; @@ -197,6 +199,8 @@ InertialSenseROS::InertialSenseROS() : SET_CALLBACK(DID_PREINTEGRATED_IMU, nav_dt_ms, preintegrated_imu_t, preint_IMU_callback); rmcBits |= RMC_BITS_PREINTEGRATED_IMU; } + if (RTK_state_ != RTK_NONE) + rmcBits |= RMC_BITS_GPS1_RTK_REL | RMC_BITS_GPS1_RTK_POS | RMC_BITS_GPS1_RTK_MISC; IS_.BroadcastBinaryDataRmcPreset(rmcBits); From 3645e6763dfe8bed2f6b609690147073b28fa3c2 Mon Sep 17 00:00:00 2001 From: James Jackson Date: Fri, 19 Oct 2018 16:45:02 -0600 Subject: [PATCH 06/13] rover is working --- src/inertial_sense.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/inertial_sense.cpp b/src/inertial_sense.cpp index 7e15cf3..089694d 100644 --- a/src/inertial_sense.cpp +++ b/src/inertial_sense.cpp @@ -85,7 +85,7 @@ InertialSenseROS::InertialSenseROS() : nh_private_.param("RTK_server_IP", RTK_server_IP, "127.0.0.1"); nh_private_.param("RTK_server_port", RTK_server_port, 12503); nh_private_.param("RTK_correction_type", RTK_correction_type, "UBLOX"); - std::string RTK_connection = RTK_server_IP + ":" + std::to_string(RTK_server_port) + ":" + RTK_correction_type; + std::string RTK_connection = RTK_correction_type + ":" + RTK_server_IP + ":" + std::to_string(RTK_server_port); ROS_ERROR_COND(RTK_rover && RTK_base, "unable to configure uINS to be both RTK rover and base - default to rover"); if (RTK_rover) @@ -492,7 +492,7 @@ void InertialSenseROS::RTK_Rel_callback(const gps_rtk_rel_t* const msg) rtk_rel.vector_to_base.x = msg->vectorToBase[0]; rtk_rel.vector_to_base.y = msg->vectorToBase[1]; rtk_rel.vector_to_base.z = msg->vectorToBase[2]; - rtk_rel.differential_age = msg->distanceToBase; + rtk_rel.distance_to_base = msg->distanceToBase; rtk_rel.heading_to_base = msg->headingToBase; RTK_.pub2.publish(rtk_rel); } From 00386cc96579e357b8010e99979aea96d5288b19 Mon Sep 17 00:00:00 2001 From: James Jackson Date: Wed, 24 Oct 2018 16:33:07 -0600 Subject: [PATCH 07/13] added raw data publishers --- CMakeLists.txt | 5 ++ include/inertial_sense.h | 15 ++++- msg/GNSSEphemeris.msg | 35 ++++++++++ msg/GNSSObservation.msg | 12 ++++ msg/GTime.msg | 2 + msg/GlonassEphemeris.msg | 14 ++++ src/inertial_sense.cpp | 142 ++++++++++++++++++++++++++++++++++++--- 7 files changed, 213 insertions(+), 12 deletions(-) create mode 100644 msg/GNSSEphemeris.msg create mode 100644 msg/GNSSObservation.msg create mode 100644 msg/GTime.msg create mode 100644 msg/GlonassEphemeris.msg diff --git a/CMakeLists.txt b/CMakeLists.txt index 826123b..fe14185 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,7 @@ project(inertial_sense) find_package(catkin REQUIRED COMPONENTS roscpp rospy + std_msgs sensor_msgs geometry_msgs message_generation @@ -15,12 +16,16 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11 -fms-extensions -Wl,--no-as add_message_files( FILES + GTime.msg SatInfo.msg GPS.msg GPSInfo.msg PreIntIMU.msg RTKInfo.msg RTKRel.msg + GlonassEphemeris.msg + GNSSEphemeris.msg + GNSSObservation.msg ) add_service_files( diff --git a/include/inertial_sense.h b/include/inertial_sense.h index 51f8b2c..95ca8b0 100644 --- a/include/inertial_sense.h +++ b/include/inertial_sense.h @@ -19,6 +19,9 @@ #include "inertial_sense/FirmwareUpdate.h" #include "inertial_sense/RTKRel.h" #include "inertial_sense/RTKInfo.h" +#include "inertial_sense/GNSSEphemeris.h" +#include "inertial_sense/GlonassEphemeris.h" +#include "inertial_sense/GNSSObservation.h" #include "nav_msgs/Odometry.h" #include "std_srvs/Trigger.h" #include "std_msgs/Header.h" @@ -79,11 +82,17 @@ class InertialSenseROS //: SerialListener void IMU_callback(const dual_imu_t* const msg); ros_stream_t GPS_; - void GPS_Pos_callback(const gps_pos_t* const msg); - void GPS_Vel_callback(const gps_vel_t* const msg); + ros_stream_t GPS_obs_; + ros_stream_t GPS_eph_; + void GPS_pos_callback(const gps_pos_t* const msg); + void GPS_vel_callback(const gps_vel_t* const msg); + void GPS_raw_callback(const gps_raw_t* const msg); + void GPS_obs_callback(const obsd_t* const msg); + void GPS_eph_callback(const eph_t* const msg); + void GPS_geph_callback(const geph_t* const msg); ros_stream_t GPS_info_; - void GPS_Info_callback(const gps_sat_t* const msg); + void GPS_info_callback(const gps_sat_t* const msg); ros_stream_t mag_; void mag_callback(const magnetometer_t* const msg); diff --git a/msg/GNSSEphemeris.msg b/msg/GNSSEphemeris.msg new file mode 100644 index 0000000..fed1846 --- /dev/null +++ b/msg/GNSSEphemeris.msg @@ -0,0 +1,35 @@ +Header header +int32 sat # satellite number +int32 iode # IODE Issue of Data, Ephemeris (ephemeris version) +int32 iodc # IODC Issue of Data, Clock (clock version) +int32 sva # SV accuracy (URA index) IRN-IS-200H p.97 +int32 svh # SV health GPS/QZS (0:ok) +int32 week # GPS/QZS: gps week, GAL: galileo week +int32 code # GPS/QZS: code on L2 * (00=Invalid, 01 = P Code ON, 11 = C/A code ON, 11 = Invalid) * GAL/CMP: data sources +int32 flag # GPS/QZS: L2 P data flag (indicates that the NAV data stream was commanded OFF on the P-code of the in-phase component of the L2 channel) * CMP: nav type +GTime toe # Toe +GTime toc # clock data reference time (s) (20.3.4.5) +GTime ttr # T_trans +float64 A # Semi-Major Axis m +float64 e # Eccentricity (no units) +float64 i0 # Inclination Angle at Reference Time (rad) +float64 OMG0 # Longitude of Ascending Node of Orbit Plane at Weekly Epoch (rad) +float64 omg # Argument of Perigee (rad) +float64 M0 # Mean Anomaly at Reference Time (rad) +float64 deln # Mean Motion Difference From Computed Value (rad) +float64 OMGd # Rate of Right Ascension (rad/s) +float64 idot # Rate of Inclination Angle (rad/s) +float64 crc # Amplitude of the Cosine Harmonic Correction Term to the Orbit Radius +float64 crs # Amplitude of the Sine Harmonic Correction Term to the Orbit Radius (m) +float64 cuc # Amplitude of the Cosine Harmonic Correction Term to the Argument of Latitude (rad) +float64 cus # Amplitude of the Sine Harmonic Correction Term to the Argument of Latitude (rad) +float64 cic # Amplitude of the Cosine Harmonic Correction Term to the Angle of Inclination (rad) +float64 cis # Amplitude of the Sine Harmonic Correction Term to the Angle of Inclination (rad) +float64 toes # Reference Time Ephemeris in week (s) +float64 fit # fit interval (h) (0: 4 hours, 1:greater than 4 hours) +float64 f0 # SV clock parameters - af0 +float64 f1 # SV clock parameters - af1 +float64 f2 # SV clock parameters - af2 +float64[4] tgd # group delay parameters: GPS/QZS:tgd[0]=TGD (IRN-IS-200H p.103) * GAL:tgd[0]=BGD E5a/E1,tgd[1]=BGD E5b/E1 * CMP :tgd[0]=BGD1,tgd[1]=BGD2 +float64 Adot # Adot for CNAV +float64 ndot # ndot for CNAV \ No newline at end of file diff --git a/msg/GNSSObservation.msg b/msg/GNSSObservation.msg new file mode 100644 index 0000000..fc813b4 --- /dev/null +++ b/msg/GNSSObservation.msg @@ -0,0 +1,12 @@ +std_msgs/Header header +GTime time # time of observation +uint8 sat # satellite number +uint8 rcv # receiver number +uint8 SNR # Signal Strength (0.25 dBHz) +uint8 LLI # Loss-of-Lock Indicator (bit1=loss-of-lock, bit2=half-cycle-invalid) +uint8 code # code indicator (BeiDou: CODE_L1I, Other: CODE_L1C ) +uint8 qualL # Estimated carrier phase measurement standard deviation (0.004 cycles) +uint8 qualP # Estimated pseudorange measurement standard deviation (0.01 m) +float64 L # observation data carrier-phase (cycle) +float64 P # observation data pseudorange (m) +float32 D # observation data doppler frequency (0.002 Hz) \ No newline at end of file diff --git a/msg/GTime.msg b/msg/GTime.msg new file mode 100644 index 0000000..3135c4c --- /dev/null +++ b/msg/GTime.msg @@ -0,0 +1,2 @@ +int64 time +float64 sec \ No newline at end of file diff --git a/msg/GlonassEphemeris.msg b/msg/GlonassEphemeris.msg new file mode 100644 index 0000000..db28f6e --- /dev/null +++ b/msg/GlonassEphemeris.msg @@ -0,0 +1,14 @@ +int32 sat # satellite number +int32 iode # IODE (0-6 bit of tb field) +int32 frq # satellite frequency number +int32 svh # satellite health +int32 sva # satellite accuracy +int32 age # satellite age of operation +GTime toe # epoch of epherides (gpst) +GTime tof # message frame time (gpst) +float64[3] pos # satellite position (ecef) (m) +float64[3] vel # satellite velocity (ecef) (m/s) +float64[3] acc # satellite acceleration (ecef) (m/s^2) +float64 taun # SV clock bias (s) +float64 gamn # relative freq bias +float64 dtaun # delay between L1 and L2 (s) \ No newline at end of file diff --git a/src/inertial_sense.cpp b/src/inertial_sense.cpp index 089694d..a0073ad 100644 --- a/src/inertial_sense.cpp +++ b/src/inertial_sense.cpp @@ -83,13 +83,13 @@ InertialSenseROS::InertialSenseROS() : std::string RTK_server_IP, RTK_correction_type; int RTK_server_port; nh_private_.param("RTK_server_IP", RTK_server_IP, "127.0.0.1"); - nh_private_.param("RTK_server_port", RTK_server_port, 12503); + nh_private_.param("RTK_server_port", RTK_server_port, 7777); nh_private_.param("RTK_correction_type", RTK_correction_type, "UBLOX"); - std::string RTK_connection = RTK_correction_type + ":" + RTK_server_IP + ":" + std::to_string(RTK_server_port); ROS_ERROR_COND(RTK_rover && RTK_base, "unable to configure uINS to be both RTK rover and base - default to rover"); if (RTK_rover) { + std::string RTK_connection = RTK_correction_type + ":" + RTK_server_IP + ":" + std::to_string(RTK_server_port); ROS_INFO("InertialSense: Configured as RTK Rover"); RTK_state_ = RTK_ROVER; uint32_t RTKCfgBits = RTK_CFG_BITS_GPS1_RTK_ROVER; @@ -109,6 +109,7 @@ InertialSenseROS::InertialSenseROS() : else if (RTK_base) { + std::string RTK_connection = RTK_server_IP + ":" + std::to_string(RTK_server_port); RTK_.enabled = true; ROS_INFO("InertialSense: Configured as RTK Base"); RTK_state_ = RTK_BASE; @@ -131,8 +132,8 @@ InertialSenseROS::InertialSenseROS() : ///////////////////////////////////////////////////////// uint32_t rmcBits = RMC_BITS_GPS1_POS | RMC_BITS_GPS1_VEL | RMC_BITS_STROBE_IN_TIME; - SET_CALLBACK(DID_GPS1_POS, flash_config_.startupGPSDtMs, gps_pos_t, GPS_Pos_callback); // we always need GPS for Fix status - SET_CALLBACK(DID_GPS1_VEL, flash_config_.startupGPSDtMs, gps_vel_t, GPS_Vel_callback); // we always need GPS for Fix status + SET_CALLBACK(DID_GPS1_POS, flash_config_.startupGPSDtMs, gps_pos_t, GPS_pos_callback); // we always need GPS for Fix status + SET_CALLBACK(DID_GPS1_VEL, flash_config_.startupGPSDtMs, gps_vel_t, GPS_vel_callback); // we always need GPS for Fix status SET_CALLBACK(DID_STROBE_IN_TIME, 100, strobe_in_time_t, strobe_in_time_callback); // we always want the strobe nh_private_.param("stream_INS", INS_.enabled, true); if (INS_.enabled) @@ -159,8 +160,18 @@ InertialSenseROS::InertialSenseROS() : // Set up the GPS ROS stream - we always need GPS information for time sync, just don't always need to publish it nh_private_.param("stream_GPS", GPS_.enabled, false); if (GPS_.enabled) - { GPS_.pub = nh_.advertise("gps", 1); + + nh_private_.param("stream_GPS_raw", GPS_obs_.enabled, false); + nh_private_.param("stream_GPS_raw", GPS_eph_.enabled, false); + if (GPS_obs_.enabled) + { + GPS_obs_.pub = nh_.advertise("gps_raw/obs", 50); + GPS_obs_.pub = nh_.advertise("gps_raw/eph", 50); + GPS_obs_.pub = nh_.advertise("gps_raw/geph", 50); + SET_CALLBACK(DID_GPS1_RAW, flash_config_.startupGPSDtMs, gps_raw_t, GPS_raw_callback); + SET_CALLBACK(DID_GPS_BASE_RAW, flash_config_.startupGPSDtMs, gps_raw_t, GPS_raw_callback); + SET_CALLBACK(DID_GPS2_RAW, flash_config_.startupGPSDtMs, gps_raw_t, GPS_raw_callback); } // Set up the GPS info ROS stream @@ -168,7 +179,7 @@ InertialSenseROS::InertialSenseROS() : if (GPS_info_.enabled) { GPS_info_.pub = nh_.advertise("gps/info", 1); - SET_CALLBACK(DID_GPS1_SAT, flash_config_.startupGPSDtMs, gps_sat_t, GPS_Info_callback); + SET_CALLBACK(DID_GPS1_SAT, flash_config_.startupGPSDtMs, gps_sat_t, GPS_info_callback); rmcBits |= RMC_BITS_GPS1_SAT; } @@ -339,7 +350,7 @@ void InertialSenseROS::IMU_callback(const dual_imu_t* const msg) } -void InertialSenseROS::GPS_Pos_callback(const gps_pos_t * const msg) +void InertialSenseROS::GPS_pos_callback(const gps_pos_t * const msg) { GPS_week_ = msg->week; GPS_towOffset_ = msg->towOffset; @@ -364,7 +375,7 @@ void InertialSenseROS::GPS_Pos_callback(const gps_pos_t * const msg) } } -void InertialSenseROS::GPS_Vel_callback(const gps_vel_t * const msg) +void InertialSenseROS::GPS_vel_callback(const gps_vel_t * const msg) { if (GPS_.enabled) { @@ -402,7 +413,7 @@ void InertialSenseROS::strobe_in_time_callback(const strobe_in_time_t * const ms } -void InertialSenseROS::GPS_Info_callback(const gps_sat_t* const msg) +void InertialSenseROS::GPS_info_callback(const gps_sat_t* const msg) { gps_info_msg.header.stamp =ros_time_from_tow(msg->timeOfWeekMs/1e3); gps_info_msg.header.frame_id = frame_id_; @@ -496,7 +507,120 @@ void InertialSenseROS::RTK_Rel_callback(const gps_rtk_rel_t* const msg) rtk_rel.heading_to_base = msg->headingToBase; RTK_.pub2.publish(rtk_rel); } +} + +void InertialSenseROS::GPS_raw_callback(const gps_raw_t * const msg) +{ + switch(msg->dataType) + { + case raw_data_type_observation: + for (int i = 0; i < msg->obsCount; i++) + GPS_obs_callback((obsd_t*)&msg->data.obs[i]); + break; + + case raw_data_type_ephemeris: + GPS_eph_callback((eph_t*)&msg->data.eph); + break; + case raw_data_type_glonass_ephemeris: + GPS_geph_callback((geph_t*)&msg->data.gloEph); + break; + + default: + break; + } +} + +void InertialSenseROS::GPS_obs_callback(const obsd_t * const msg) +{ + inertial_sense::GNSSObservation obs; + obs.time.time = msg->time.time; + obs.time.sec = msg->time.sec; + obs.sat = msg->sat; + obs.rcv = msg->rcv; + obs.SNR = msg->SNR[0]; + obs.LLI = msg->LLI[0]; + obs.code = msg->code[0]; + obs.qualL = msg->qualL[0]; + obs.qualP = msg->qualP[0]; + obs.L = msg->L[0]; + obs.P = msg->P[0]; + obs.D = msg->D[0]; + GPS_obs_.pub.publish(obs); +} + +void InertialSenseROS::GPS_eph_callback(const eph_t * const msg) +{ + inertial_sense::GNSSEphemeris eph; + eph.sat = msg->sat; + eph.iode = msg->iode; + eph.iodc = msg->iodc; + eph.sva = msg->sva; + eph.svh = msg->svh; + eph.week = msg->week; + eph.code = msg->code; + eph.flag = msg->flag; + eph.toe.time = msg->toe.time; + eph.toc.time = msg->toc.time; + eph.ttr.time = msg->ttr.time; + eph.toe.sec = msg->toe.sec; + eph.toc.sec = msg->toc.sec; + eph.ttr.sec = msg->ttr.sec; + eph.A = msg->A; + eph.e = msg->e; + eph.i0 = msg->i0; + eph.OMG0 = msg->OMG0; + eph.omg = msg->omg; + eph.M0 = msg->M0; + eph.deln = msg->deln; + eph.OMGd = msg->OMGd; + eph.idot = msg->idot; + eph.crc = msg->crc; + eph.crs = msg->crs; + eph.cuc = msg->cuc; + eph.cus = msg->cus; + eph.cic = msg->cic; + eph.cis = msg->cis; + eph.toes = msg->toes; + eph.fit = msg->fit; + eph.f0 = msg->f0; + eph.f1 = msg->f1; + eph.f2 = msg->f2; + eph.tgd[0] = msg->tgd[0]; + eph.tgd[1] = msg->tgd[1]; + eph.tgd[2] = msg->tgd[2]; + eph.tgd[3] = msg->tgd[3]; + eph.Adot = msg->Adot; + eph.ndot = msg->ndot; + GPS_eph_.pub.publish(eph); +} + +void InertialSenseROS::GPS_geph_callback(const geph_t * const msg) +{ + inertial_sense::GlonassEphemeris geph; + geph.sat = msg->sat; + geph.iode = msg->iode; + geph.frq = msg->frq; + geph.svh = msg->svh; + geph.sva = msg->sva; + geph.age = msg->age; + geph.toe.time = msg->toe.time; + geph.tof.time = msg->tof.time; + geph.toe.sec = msg->toe.sec; + geph.tof.sec = msg->tof.sec; + geph.pos[0] = msg->pos[0]; + geph.pos[1] = msg->pos[1]; + geph.pos[2] = msg->pos[2]; + geph.vel[0] = msg->vel[0]; + geph.vel[1] = msg->vel[1]; + geph.vel[2] = msg->vel[2]; + geph.acc[0] = msg->acc[0]; + geph.acc[1] = msg->acc[1]; + geph.acc[2] = msg->acc[2]; + geph.taun = msg->taun; + geph.gamn = msg->gamn; + geph.dtaun = msg->dtaun; + GPS_eph_.pub2.publish(geph); } bool InertialSenseROS::set_current_position_as_refLLA(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res) From ba1c5e4bcd06420219272ad38d91b98ef3beee9f Mon Sep 17 00:00:00 2001 From: James Jackson Date: Wed, 24 Oct 2018 16:48:26 -0600 Subject: [PATCH 08/13] updated readme --- README.md | 36 +++++++++++++++++++++++++++++++----- src/inertial_sense.cpp | 10 +++++----- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index e0d85fb..6329f18 100644 --- a/README.md +++ b/README.md @@ -49,12 +49,12 @@ In an ideal setting, there should be no jump in timestamps when GPS is first acq ## Topics -Topics are enabled and disabled using parameters. By default, only the `ins/` topic is published to save processor time in serializing unecessary messages. -- `ins/`(nav_msgs/Odometry) +Topics are enabled and disabled using parameters. By default, only the `ins` topic is published to save processor time in serializing unecessary messages. +- `ins`(nav_msgs/Odometry) - full 12-DOF measurements from onboard estimator (pose portion is from inertial to body, twist portion is in body frame) -- `imu/`(sensor_msgs/Imu) +- `imu`(sensor_msgs/Imu) - Raw Imu measurements from IMU1 (NED frame) -- `gps/`(inertial_sense/GPS) +- `gps`(inertial_sense/GPS) - unfiltered GPS measurements from onboard GPS unit - `gps/info`(inertial_sense/GPSInfo) - sattelite information and carrier noise ratio array for each sattelite @@ -64,6 +64,16 @@ Topics are enabled and disabled using parameters. By default, only the `ins/` t - Raw barometer measurements in kPa - `preint_imu` (inertial_sense/DThetaVel) - preintegrated coning and sculling integrals of IMU measurements +- `RTK/info` (inertial_sense/RTKInfo) + - information about RTK status +- `RTK/rel` (inertial_sense/RTKRel) + * Relative measurement between RTK base and rover +- `gps/obs` (inertial_sense/GNSSObservation) + * Raw satellite observation (psuedorange and carrier phase) +- `gps/eph` (inertial_sense/GNSSEphemeris) + * Satellite Ephemeris for GPS and Galileo GNSS constellations +- `gps/geph` + * Satellite Ephemeris for Glonass GNSS constellation ## Parameters @@ -91,6 +101,20 @@ Topics are enabled and disabled using parameters. By default, only the `ins/` t - Flag to stream GPS * `~stream_GPS_info`(bool, default: false) - Flag to stream GPS info messages +- `stream_GPS_raw` (bool, default: false) + - Flag to stream GPS raw messages + +**RTK Configuration** +* `~RTK_Rover` (bool, default: false) + - Enables RTK rover mode (requires base corrections from an RTK base) +* `~RTK_base` (bool, default: false) + - Makes the connected uINS a RTK base station and enables the publishing of corrections +* `~RTK_server_IP` (string, default: 172.0.0.1) + - If operating as base, attempts to create a TCP port on this IP for base corrections, if rover, connects to this IP for corrections. +* `~RTK_server_port` (int, default: 7777) + - If operating as base, creates a TCP connection at this port for base corrections, if rover, connects to this port for corrections. +* `~RTK_correction_type` (string, default: UBLOX) + - If operating with limited bandwidth, choose RTCM3 for a lower bandwidth, but less accurate base corrections, rover and base must match **Sensor Configuration** * `~INS_rpy` (vector(3), default: {0, 0, 0}) @@ -139,4 +163,6 @@ Topics are enabled and disabled using parameters. By default, only the `ins/` t - `multi_axis_mag_cal` (std_srvs/Trigger) - Put INS into multi axis magnetometer calibration mode. This is typically used if the uINS is not mounted to a vehicle, or a lightweight vehicle such as a drone. Simply rotate the uINS around all axes until the light on the uINS turns blue [more info](http://docs.inertialsense.com/user-manual/Setup_Integration/magnetometer_calibration/) - `firmware_update` (inertial_sense/FirmwareUpdate) - - Updates firmware to the `.hex` file supplied (use absolute filenames) \ No newline at end of file + - Updates firmware to the `.hex` file supplied (use absolute filenames) +* `set_refLLA` (std_srvs/Trigger) + - Takes the current estimated position and sets it as the `refLLA`. Use this to set a base position after a survey, or to zero out the `ins` topic. \ No newline at end of file diff --git a/src/inertial_sense.cpp b/src/inertial_sense.cpp index a0073ad..1f504bf 100644 --- a/src/inertial_sense.cpp +++ b/src/inertial_sense.cpp @@ -103,8 +103,8 @@ InertialSenseROS::InertialSenseROS() : SET_CALLBACK(DID_GPS1_RTK_MISC, nav_dt_ms, gps_rtk_misc_t, RTK_Misc_callback); SET_CALLBACK(DID_GPS1_RTK_REL, nav_dt_ms, gps_rtk_rel_t, RTK_Rel_callback); RTK_.enabled = true; - RTK_.pub = nh_.advertise("RTK_info", 10); - RTK_.pub2 = nh_.advertise("RTK_rel", 10); + RTK_.pub = nh_.advertise("RTK/info", 10); + RTK_.pub2 = nh_.advertise("RTK/rel", 10); } else if (RTK_base) @@ -166,9 +166,9 @@ InertialSenseROS::InertialSenseROS() : nh_private_.param("stream_GPS_raw", GPS_eph_.enabled, false); if (GPS_obs_.enabled) { - GPS_obs_.pub = nh_.advertise("gps_raw/obs", 50); - GPS_obs_.pub = nh_.advertise("gps_raw/eph", 50); - GPS_obs_.pub = nh_.advertise("gps_raw/geph", 50); + GPS_obs_.pub = nh_.advertise("gps/obs", 50); + GPS_obs_.pub = nh_.advertise("gps/eph", 50); + GPS_obs_.pub = nh_.advertise("gps/geph", 50); SET_CALLBACK(DID_GPS1_RAW, flash_config_.startupGPSDtMs, gps_raw_t, GPS_raw_callback); SET_CALLBACK(DID_GPS_BASE_RAW, flash_config_.startupGPSDtMs, gps_raw_t, GPS_raw_callback); SET_CALLBACK(DID_GPS2_RAW, flash_config_.startupGPSDtMs, gps_raw_t, GPS_raw_callback); From 625cabb194fdaeebd88276ca95ea212fcc8968da Mon Sep 17 00:00:00 2001 From: James Jackson Date: Wed, 24 Oct 2018 16:49:49 -0600 Subject: [PATCH 09/13] added set ref LLA note --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6329f18..1de84d6 100644 --- a/README.md +++ b/README.md @@ -124,7 +124,7 @@ Topics are enabled and disabled using parameters. By default, only the `ins` to * `~GPS_ant_xyz` (vector(3), default: {0, 0, 0}) - The NED translation vector between the INS frame and the GPS antenna (wrt INS frame) * `~GPS_ref_lla` (vector(3), default: {0, 0, 0}) - - The Reference longitude, latitude and altitude for NED calculation in degrees, degrees and meters + - The Reference longitude, latitude and altitude for NED calculation in degrees, degrees and meters (use the `set_refLLA` service to update this automatically) * `~inclination` (float, default: 1.14878541071) - The inclination of earth's magnetic field (radians) * `~declination` (float, default: 0.20007290992) @@ -165,4 +165,4 @@ Topics are enabled and disabled using parameters. By default, only the `ins` to - `firmware_update` (inertial_sense/FirmwareUpdate) - Updates firmware to the `.hex` file supplied (use absolute filenames) * `set_refLLA` (std_srvs/Trigger) - - Takes the current estimated position and sets it as the `refLLA`. Use this to set a base position after a survey, or to zero out the `ins` topic. \ No newline at end of file + - Takes the current estimated position and sets it as the `refLLA`. Use this to set a base position after a survey, or to zero out the `ins` topic.1 \ No newline at end of file From fddfba598b6b9c94d1f18353e2ea9c711ae37f2e Mon Sep 17 00:00:00 2001 From: James Jackson Date: Wed, 24 Oct 2018 16:52:51 -0600 Subject: [PATCH 10/13] version notice --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1de84d6..e6909c7 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,10 @@ A ROS wrapper for the InertialSense uINS2 GPS-INS sensor ## NOTICE: -To use this node, you will likely need to update firmware on your uINS [release page](https://github.com/inertialsense/InertialSenseSDK/releases). Download the appropriate `.hex` file and use the `firmware_update` ROS service to update the firmware +To use this node, you will need to update firmware on your uINS to _at least_ v1.7.0 [release page](https://github.com/inertialsense/InertialSenseSDK/releases). Download the appropriate `.hex` file and use the `firmware_update` ROS service to update the firmware ``` -rosservice call /firmware_update /home/superjax/Download/IS_uINS-3_v1.6.6.0_b2781_2018-06-29_175015.hex +rosservice call /firmware_update /home/superjax/Download/IS_uINS-3_v1.7.0<...>.hex ``` ## Installation From 29cdbb98f75be43d1ca559f41d4ceb7d464d6d10 Mon Sep 17 00:00:00 2001 From: James Jackson Date: Fri, 26 Oct 2018 11:08:18 -0600 Subject: [PATCH 11/13] RTK notes --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e6909c7..32971b1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # inertial_sense -A ROS wrapper for the InertialSense uINS2 GPS-INS sensor +A ROS wrapper for the InertialSense uINS2 RTK-GPS-INS sensor. + ## NOTICE: @@ -41,6 +42,14 @@ rosrun inertial_sense inertial_sense_node For setting parameters and topic remappings from a launch file, refer to the [Roslaunch for Larger Projects](http://wiki.ros.org/roslaunch/Tutorials/Roslaunch%20tips%20for%20larger%20projects) page, or the sample `launch/test.launch` file in this repository. +## RTK +RTK (Realtime Kinematic) GPS requires two gps receivers, a _base_ and a _rover_. The GPS observations from the base GPS are sent to the rover and the rover is able to calculate a much more accurate (+/- 3cm) relative position to the base. This requires a surveyed base position and a relatively high-bandwidth connection to the rover. The RTK functionality in this node is performed by setting parameters shown below. + +It is important that the base position be accurate. There are two primary methods for getting a surveyed base position + 1. Find the location of the base on Google Maps (quick and easy, not as accurate) + 2. Put the base into rover mode with a 3rd-party base station such as a NTRIP caster. Once the base has RTK fix, the absolute position of the base is accurate to within 3 cm. Averaging this position over time is usually the most accurate way to get a base position, but takes more effort. +Once the base position has been identified, set the `refLLA` of the base uINS to your surveyed position to indicate a surveyed base position. + ## Time Stamps If GPS is available, all header timestamps are calculated with respect to the GPS clock but are translated into UNIX time to be consistent with the other topics in a ROS network. If GPS is unvailable, then a constant offset between uINS time and system time is estimated during operation and is applied to IMU and INS message timestamps as they arrive. There is often a small drift in these timestamps (on the order of a microsecond per second), due to variance in measurement streams and difference between uINS and system clocks, however this is more accurate than stamping the measurements with ROS time as they arrive. From a23549fdcb59dd71be8d197d102909d80a466508 Mon Sep 17 00:00:00 2001 From: James Jackson Date: Fri, 26 Oct 2018 11:09:43 -0600 Subject: [PATCH 12/13] readme formatting --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 32971b1..31a7414 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ RTK (Realtime Kinematic) GPS requires two gps receivers, a _base_ and a _rover_. It is important that the base position be accurate. There are two primary methods for getting a surveyed base position 1. Find the location of the base on Google Maps (quick and easy, not as accurate) 2. Put the base into rover mode with a 3rd-party base station such as a NTRIP caster. Once the base has RTK fix, the absolute position of the base is accurate to within 3 cm. Averaging this position over time is usually the most accurate way to get a base position, but takes more effort. + Once the base position has been identified, set the `refLLA` of the base uINS to your surveyed position to indicate a surveyed base position. ## Time Stamps From 0ae7198e68e10351f8826fe5c9c88622b6239dc2 Mon Sep 17 00:00:00 2001 From: James Jackson Date: Fri, 26 Oct 2018 11:10:26 -0600 Subject: [PATCH 13/13] readme formatting --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 31a7414..a7d61e7 100644 --- a/README.md +++ b/README.md @@ -45,10 +45,12 @@ For setting parameters and topic remappings from a launch file, refer to the [Ro ## RTK RTK (Realtime Kinematic) GPS requires two gps receivers, a _base_ and a _rover_. The GPS observations from the base GPS are sent to the rover and the rover is able to calculate a much more accurate (+/- 3cm) relative position to the base. This requires a surveyed base position and a relatively high-bandwidth connection to the rover. The RTK functionality in this node is performed by setting parameters shown below. -It is important that the base position be accurate. There are two primary methods for getting a surveyed base position +It is important that the base position be accurate. There are two primary methods for getting a surveyed base position. + 1. Find the location of the base on Google Maps (quick and easy, not as accurate) 2. Put the base into rover mode with a 3rd-party base station such as a NTRIP caster. Once the base has RTK fix, the absolute position of the base is accurate to within 3 cm. Averaging this position over time is usually the most accurate way to get a base position, but takes more effort. + Once the base position has been identified, set the `refLLA` of the base uINS to your surveyed position to indicate a surveyed base position. ## Time Stamps