22 #include <GeographicLib/Geocentric.hpp> 24 #include <std_msgs/Float64.h> 25 #include <nav_msgs/Odometry.h> 26 #include <sensor_msgs/NavSatFix.h> 27 #include <sensor_msgs/NavSatStatus.h> 28 #include <geometry_msgs/PoseStamped.h> 29 #include <geometry_msgs/TwistStamped.h> 30 #include <geometry_msgs/TransformStamped.h> 31 #include <geographic_msgs/GeoPointStamped.h> 33 #include <mavros_msgs/HomePosition.h> 36 namespace std_plugins {
46 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
49 gp_nh(
"~global_position"),
58 PluginBase::initialize(uas_);
139 template<
typename MsgT>
142 fix->latitude = msg.lat / 1E7;
143 fix->longitude = msg.lon / 1E7;
149 fix->position_covariance.fill(0.0);
150 fix->position_covariance[0] = -1.0;
151 fix->position_covariance_type = sensor_msgs::NavSatFix::COVARIANCE_TYPE_UNKNOWN;
156 void handle_gps_raw_int(
const mavlink::mavlink_message_t *msg, mavlink::common::msg::GPS_RAW_INT &raw_gps)
158 auto fix = boost::make_shared<sensor_msgs::NavSatFix>();
162 fix->status.service = sensor_msgs::NavSatStatus::SERVICE_GPS;
163 if (raw_gps.fix_type > 2)
164 fix->status.status = sensor_msgs::NavSatStatus::STATUS_FIX;
167 fix->status.status = sensor_msgs::NavSatStatus::STATUS_NO_FIX;
172 float eph = (raw_gps.eph != UINT16_MAX) ? raw_gps.eph / 1E2F : NAN;
173 float epv = (raw_gps.epv != UINT16_MAX) ? raw_gps.epv / 1E2F : NAN;
179 raw_gps.h_acc > 0 && raw_gps.v_acc > 0) {
180 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);
181 fix->position_covariance_type = sensor_msgs::NavSatFix::COVARIANCE_TYPE_DIAGONAL_KNOWN;
184 else if (!std::isnan(eph) && !std::isnan(epv)) {
185 gps_cov.diagonal() << std::pow(eph * gps_uere, 2), std::pow(eph * gps_uere, 2), std::pow(epv * gps_uere, 2);
186 fix->position_covariance_type = sensor_msgs::NavSatFix::COVARIANCE_TYPE_APPROXIMATED;
196 if (raw_gps.vel != UINT16_MAX &&
197 raw_gps.cog != UINT16_MAX) {
198 double speed = raw_gps.vel / 1E2;
201 auto vel = boost::make_shared<geometry_msgs::TwistStamped>();
203 vel->header.stamp = fix->header.stamp;
207 vel->twist.linear.x = speed * std::sin(course);
208 vel->twist.linear.y = speed * std::cos(course);
216 auto g_origin = boost::make_shared<geographic_msgs::GeoPointStamped>();
227 GeographicLib::Geocentric earth(GeographicLib::Constants::WGS84_a(),
228 GeographicLib::Constants::WGS84_f());
230 earth.Forward(glob_orig.latitude / 1E7, glob_orig.longitude / 1E7, glob_orig.altitude / 1E3,
231 g_origin->position.latitude, g_origin->position.longitude, g_origin->position.altitude);
233 gp_global_origin_pub.
publish(g_origin);
235 catch (
const std::exception&
e) {
244 auto odom = boost::make_shared<nav_msgs::Odometry>();
245 auto fix = boost::make_shared<sensor_msgs::NavSatFix>();
246 auto relative_alt = boost::make_shared<std_msgs::Float64>();
247 auto compass_heading = boost::make_shared<std_msgs::Float64>();
252 fix->header = header;
259 fix->status.service = raw_fix->status.service;
260 fix->status.status = raw_fix->status.status;
261 fix->position_covariance = raw_fix->position_covariance;
262 fix->position_covariance_type = raw_fix->position_covariance_type;
266 fix->status.service = sensor_msgs::NavSatStatus::SERVICE_GPS;
267 fix->status.status = sensor_msgs::NavSatStatus::STATUS_NO_FIX;
273 relative_alt->data = gpos.relative_alt / 1E3;
274 compass_heading->data = (gpos.hdg != UINT16_MAX) ? gpos.hdg / 1E2 : NAN;
289 odom->header.stamp = header.stamp;
290 odom->header.frame_id = frame_id;
291 odom->child_frame_id = child_frame_id;
295 odom->twist.twist.linear);
299 vel_cov_out.fill(0.0);
300 vel_cov_out(0) = -1.0;
303 Eigen::Vector3d map_point;
313 GeographicLib::Geocentric
map(GeographicLib::Constants::WGS84_a(),
314 GeographicLib::Constants::WGS84_f());
324 map.Forward(fix->latitude, fix->longitude, fix->altitude,
325 map_point.x(), map_point.y(), map_point.z());
337 catch (
const std::exception&
e) {
350 if (use_relative_alt)
351 odom->pose.pose.position.z = relative_alt->data;
358 pos_cov_out.setZero();
359 pos_cov_out.block<3, 3>(0, 0) = gps_cov;
360 pos_cov_out.block<3, 3>(3, 3).diagonal() <<
368 gp_rel_alt_pub.
publish(relative_alt);
369 gp_hdg_pub.
publish(compass_heading);
373 geometry_msgs::TransformStamped
transform;
375 transform.header.stamp = odom->header.stamp;
380 transform.transform.rotation = odom->pose.pose.orientation;
383 transform.transform.translation.x = odom->pose.pose.position.x;
384 transform.transform.translation.y = odom->pose.pose.position.y;
385 transform.transform.translation.z = odom->pose.pose.position.z;
393 auto global_offset = boost::make_shared<geometry_msgs::PoseStamped>();
404 gp_global_offset_pub.
publish(global_offset);
408 geometry_msgs::TransformStamped
transform;
410 transform.header.stamp = global_offset->header.stamp;
415 transform.transform.rotation = global_offset->pose.orientation;
418 transform.transform.translation.x = global_offset->pose.position.x;
419 transform.transform.translation.y = global_offset->pose.position.y;
420 transform.transform.translation.z = global_offset->pose.position.z;
429 int fix_type, satellites_visible;
434 if (satellites_visible <= 0)
435 stat.
summary(2,
"No satellites");
436 else if (fix_type < 2)
438 else if (fix_type == 2)
440 else if (fix_type >= 3)
443 stat.
addf(
"Satellites visible",
"%zd", satellites_visible);
444 stat.
addf(
"Fix type",
"%d", fix_type);
446 if (!std::isnan(eph))
447 stat.
addf(
"EPH (m)",
"%.2f", eph);
449 stat.
add(
"EPH (m)",
"Unknown");
451 if (!std::isnan(epv))
452 stat.
addf(
"EPV (m)",
"%.2f", epv);
454 stat.
add(
"EPV (m)",
"Unknown");
469 GeographicLib::Geocentric
map(GeographicLib::Constants::WGS84_a(),
470 GeographicLib::Constants::WGS84_f());
476 catch (
const std::exception&
e) {
485 mavlink::common::msg::SET_GPS_GLOBAL_ORIGIN gpo;
487 Eigen::Vector3d global_position;
492 gpo.latitude = req->position.latitude * 1E7;
493 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)
double ellipsoid_to_geoid_height(T lla)
Conversion from height above ellipsoid (WGS-84) to height above geoid (AMSL)
#define ROS_WARN_THROTTLE_NAMED(period, name,...)
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.
Subscriptions get_subscriptions()
Return vector of MAVLink message subscriptions (handlers)
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 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 initialize(UAS &uas_)
Plugin initializer.
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.
std::string child_frame_id
body-fixed frame for topic headers
#define ROS_INFO_STREAM(args)
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