22 #include <GeographicLib/Geocentric.hpp> 24 #include <std_msgs/Float64.h> 25 #include <std_msgs/UInt32.h> 26 #include <nav_msgs/Odometry.h> 27 #include <sensor_msgs/NavSatFix.h> 28 #include <sensor_msgs/NavSatStatus.h> 29 #include <geometry_msgs/PoseStamped.h> 30 #include <geometry_msgs/TwistStamped.h> 31 #include <geometry_msgs/TransformStamped.h> 32 #include <geographic_msgs/GeoPointStamped.h> 34 #include <mavros_msgs/HomePosition.h> 37 namespace std_plugins {
47 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
50 gp_nh(
"~global_position"),
59 PluginBase::initialize(uas_);
142 template<
typename MsgT>
145 fix->latitude = msg.lat / 1E7;
146 fix->longitude = msg.lon / 1E7;
152 fix->position_covariance.fill(0.0);
153 fix->position_covariance[0] = -1.0;
154 fix->position_covariance_type = sensor_msgs::NavSatFix::COVARIANCE_TYPE_UNKNOWN;
159 void handle_gps_raw_int(
const mavlink::mavlink_message_t *msg, mavlink::common::msg::GPS_RAW_INT &raw_gps)
161 auto fix = boost::make_shared<sensor_msgs::NavSatFix>();
165 fix->status.service = sensor_msgs::NavSatStatus::SERVICE_GPS;
166 if (raw_gps.fix_type > 2)
167 fix->status.status = sensor_msgs::NavSatStatus::STATUS_FIX;
170 fix->status.status = sensor_msgs::NavSatStatus::STATUS_NO_FIX;
175 float eph = (raw_gps.eph != UINT16_MAX) ? raw_gps.eph / 1E2F : NAN;
176 float epv = (raw_gps.epv != UINT16_MAX) ? raw_gps.epv / 1E2F : NAN;
182 raw_gps.h_acc > 0 && raw_gps.v_acc > 0) {
183 gps_cov.diagonal() << std::pow(raw_gps.h_acc / 1E3, 2), std::pow(raw_gps.h_acc / 1E3, 2), std::pow(raw_gps.v_acc / 1E3, 2);
184 fix->position_covariance_type = sensor_msgs::NavSatFix::COVARIANCE_TYPE_DIAGONAL_KNOWN;
187 else if (!std::isnan(eph) && !std::isnan(epv)) {
188 gps_cov.diagonal() << std::pow(eph * gps_uere, 2), std::pow(eph * gps_uere, 2), std::pow(epv * gps_uere, 2);
189 fix->position_covariance_type = sensor_msgs::NavSatFix::COVARIANCE_TYPE_APPROXIMATED;
199 if (raw_gps.vel != UINT16_MAX &&
200 raw_gps.cog != UINT16_MAX) {
201 double speed = raw_gps.vel / 1E2;
204 auto vel = boost::make_shared<geometry_msgs::TwistStamped>();
206 vel->header.stamp = fix->header.stamp;
210 vel->twist.linear.x = speed * std::sin(course);
211 vel->twist.linear.y = speed * std::cos(course);
217 auto sat_cnt = boost::make_shared<std_msgs::UInt32>();
218 sat_cnt->data = raw_gps.satellites_visible;
224 auto g_origin = boost::make_shared<geographic_msgs::GeoPointStamped>();
230 g_origin->position.latitude = glob_orig.latitude / 1E7;
231 g_origin->position.longitude = glob_orig.longitude / 1E7;
239 GeographicLib::Geocentric earth(GeographicLib::Constants::WGS84_a(),
240 GeographicLib::Constants::WGS84_f());
242 earth.Forward(g_origin->position.latitude, g_origin->position.longitude, g_origin->position.altitude,
243 g_origin->position.latitude, g_origin->position.longitude, g_origin->position.altitude);
245 gp_global_origin_pub.
publish(g_origin);
247 catch (
const std::exception&
e) {
256 auto odom = boost::make_shared<nav_msgs::Odometry>();
257 auto fix = boost::make_shared<sensor_msgs::NavSatFix>();
258 auto relative_alt = boost::make_shared<std_msgs::Float64>();
259 auto compass_heading = boost::make_shared<std_msgs::Float64>();
264 fix->header = header;
271 fix->status.service = raw_fix->status.service;
272 fix->status.status = raw_fix->status.status;
273 fix->position_covariance = raw_fix->position_covariance;
274 fix->position_covariance_type = raw_fix->position_covariance_type;
278 fix->status.service = sensor_msgs::NavSatStatus::SERVICE_GPS;
279 fix->status.status = sensor_msgs::NavSatStatus::STATUS_NO_FIX;
285 relative_alt->data = gpos.relative_alt / 1E3;
286 compass_heading->data = (gpos.hdg != UINT16_MAX) ? gpos.hdg / 1E2 : NAN;
301 odom->header.stamp = header.stamp;
302 odom->header.frame_id = frame_id;
303 odom->child_frame_id = child_frame_id;
307 odom->twist.twist.linear);
311 vel_cov_out.fill(0.0);
312 vel_cov_out(0) = -1.0;
315 Eigen::Vector3d map_point;
325 GeographicLib::Geocentric
map(GeographicLib::Constants::WGS84_a(),
326 GeographicLib::Constants::WGS84_f());
336 map.Forward(fix->latitude, fix->longitude, fix->altitude,
337 map_point.x(), map_point.y(), map_point.z());
340 if (!is_map_init && fix->status.status >= sensor_msgs::NavSatStatus::STATUS_FIX) {
349 catch (
const std::exception&
e) {
362 if (use_relative_alt)
363 odom->pose.pose.position.z = relative_alt->data;
370 pos_cov_out.setZero();
371 pos_cov_out.block<3, 3>(0, 0) = gps_cov;
372 pos_cov_out.block<3, 3>(3, 3).diagonal() <<
380 gp_rel_alt_pub.
publish(relative_alt);
381 gp_hdg_pub.
publish(compass_heading);
385 geometry_msgs::TransformStamped
transform;
387 transform.header.stamp = odom->header.stamp;
392 transform.transform.rotation = odom->pose.pose.orientation;
395 transform.transform.translation.x = odom->pose.pose.position.x;
396 transform.transform.translation.y = odom->pose.pose.position.y;
397 transform.transform.translation.z = odom->pose.pose.position.z;
405 auto global_offset = boost::make_shared<geometry_msgs::PoseStamped>();
416 gp_global_offset_pub.
publish(global_offset);
420 geometry_msgs::TransformStamped
transform;
422 transform.header.stamp = global_offset->header.stamp;
427 transform.transform.rotation = global_offset->pose.orientation;
430 transform.transform.translation.x = global_offset->pose.position.x;
431 transform.transform.translation.y = global_offset->pose.position.y;
432 transform.transform.translation.z = global_offset->pose.position.z;
441 int fix_type, satellites_visible;
446 if (satellites_visible <= 0)
447 stat.
summary(2,
"No satellites");
448 else if (fix_type < 2)
450 else if (fix_type == 2)
452 else if (fix_type >= 3)
455 stat.
addf(
"Satellites visible",
"%zd", satellites_visible);
456 stat.
addf(
"Fix type",
"%d", fix_type);
458 if (!std::isnan(eph))
459 stat.
addf(
"EPH (m)",
"%.2f", eph);
461 stat.
add(
"EPH (m)",
"Unknown");
463 if (!std::isnan(epv))
464 stat.
addf(
"EPV (m)",
"%.2f", epv);
466 stat.
add(
"EPV (m)",
"Unknown");
481 GeographicLib::Geocentric
map(GeographicLib::Constants::WGS84_a(),
482 GeographicLib::Constants::WGS84_f());
488 catch (
const std::exception&
e) {
497 mavlink::common::msg::SET_GPS_GLOBAL_ORIGIN gpo = {};
499 Eigen::Vector3d global_position;
504 gpo.latitude = req->position.latitude * 1E7;
505 gpo.longitude = req->position.longitude * 1E7;
std::string frame_id
origin frame for topic headers
MAVROS Plugin base class.
Eigen::Vector3d ecef_origin
geocentric origin of map frame [m]
std::shared_ptr< MAVConnInterface const > ConstPtr
std_msgs::Header synchronized_header(const std::string &frame_id, const T time_stamp)
Create message header from time_boot_ms or time_usec stamps and frame_id.
void fill_lla(MsgT &msg, sensor_msgs::NavSatFix::Ptr fix)
#define ROS_WARN_THROTTLE_NAMED(rate, name,...)
double ellipsoid_to_geoid_height(T lla)
Conversion from height above ellipsoid (WGS-84) to height above geoid (AMSL)
void publish(const boost::shared_ptr< M > &message) const
geometry_msgs::Quaternion get_attitude_orientation_enu()
Get Attitude orientation quaternion.
void summary(unsigned char lvl, const std::string s)
void quaternionEigenToMsg(const Eigen::Quaterniond &e, geometry_msgs::Quaternion &m)
void handle_lpned_system_global_offset(const mavlink::mavlink_message_t *msg, mavlink::common::msg::LOCAL_POSITION_NED_SYSTEM_GLOBAL_OFFSET &offset)
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
void fill_unknown_cov(sensor_msgs::NavSatFix::Ptr fix)
std::string tf_global_frame_id
global origin for TF
void handle_global_position_int(const mavlink::mavlink_message_t *msg, mavlink::common::msg::GLOBAL_POSITION_INT &gpos)
HandlerInfo make_handler(const mavlink::msgid_t id, void(_C::*fn)(const mavlink::mavlink_message_t *msg, const mavconn::Framing framing))
ros::Publisher gp_odom_pub
Eigen::Map< Eigen::Matrix< double, 6, 6, Eigen::RowMajor > > EigenMapCovariance6d
Eigen::Map for Covariance6d.
Eigen::Map< const Eigen::Matrix< double, 3, 3, Eigen::RowMajor > > EigenMapConstCovariance3d
#define UAS_DIAG(uasobjptr)
helper accessor to diagnostic updater
void set_gp_origin_cb(const geographic_msgs::GeoPointStamped::ConstPtr &req)
void addf(const std::string &key, const char *format,...)
ros::Publisher raw_fix_pub
void gps_diag_run(diagnostic_updater::DiagnosticStatusWrapper &stat)
tf2_ros::TransformBroadcaster tf2_broadcaster
Eigen::Vector3d local_ecef
local ECEF coordinates on map frame [m]
PluginBase()
Plugin constructor Should not do anything before initialize()
void home_position_cb(const mavros_msgs::HomePosition::ConstPtr &req)
uint8_t get_tgt_system()
Return communication target system.
ros::Subscriber gp_set_global_origin_sub
std::string tf_frame_id
origin for TF
ros::Publisher raw_vel_pub
static double from_degrees(double degrees)
void vectorEigenToMsg(const Eigen::Vector3d &e, geometry_msgs::Vector3 &m)
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
#define UAS_FCU(uasobjptr)
helper accessor to FCU link interface
std::string tf_child_frame_id
frame for TF and Pose
ros::Publisher raw_sat_pub
ros::Publisher gp_rel_alt_pub
ros::Publisher gp_global_offset_pub
T transform_frame_ned_enu(const T &in)
Transform data expressed in NED to ENU frame.
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
void handle_gps_global_origin(const mavlink::mavlink_message_t *msg, mavlink::common::msg::GPS_GLOBAL_ORIGIN &glob_orig)
EIGEN_MAKE_ALIGNED_OPERATOR_NEW GlobalPositionPlugin()
Eigen::Map< Eigen::Matrix< double, 3, 3, Eigen::RowMajor > > EigenMapCovariance3d
Eigen::Map for Covariance3d.
void pointEigenToMsg(const Eigen::Vector3d &e, geometry_msgs::Point &m)
ros::Publisher gp_hdg_pub
Eigen::Quaterniond quaternion_from_rpy(const Eigen::Vector3d &rpy)
Convert euler angles to quaternion.
void initialize(UAS &uas_) override
Plugin initializer.
std::string child_frame_id
body-fixed frame for topic headers
#define ROS_INFO_STREAM(args)
Subscriptions get_subscriptions() override
Return vector of MAVLink message subscriptions (handlers)
std::vector< HandlerInfo > Subscriptions
Subscriptions vector.
sensor_msgs::NavSatFix::Ptr get_gps_fix()
Retunrs last GPS RAW message.
T transform_frame_ecef_enu(const T &in, const T &map_origin)
Transform data expressed in ECEF frame to ENU frame.
T transform_orientation_ned_enu(const T &in)
Transform from attitude represented WRT NED frame to attitude represented WRT ENU frame...
ros::Publisher gp_global_origin_pub
void handle_gps_raw_int(const mavlink::mavlink_message_t *msg, mavlink::common::msg::GPS_RAW_INT &raw_gps)
Eigen::Vector3d map_origin
geodetic origin of map frame [lla]
void add(const std::string &key, const T &val)
T transform_orientation_aircraft_baselink(const T &in)
Transform from attitude represented WRT aircraft frame to attitude represented WRT base_link frame...
ros::Publisher gp_fix_pub
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
void update_gps_fix_epts(sensor_msgs::NavSatFix::Ptr &fix, float eph, float epv, int fix_type, int satellites_visible)
Store GPS RAW data.
double geoid_to_ellipsoid_height(T lla)
Conversion from height above geoid (AMSL) to height above ellipsoid (WGS-84)
void get_gps_epts(float &eph, float &epv, int &fix_type, int &satellites_visible)
Returns EPH, EPV, Fix type and satellites visible.
std::shared_ptr< MAVConnInterface > Ptr