00001
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <mavros/mavros_plugin.h>
00029 #include <mavros/gps_conversions.h>
00030 #include <pluginlib/class_list_macros.h>
00031
00032 #include <tf/transform_broadcaster.h>
00033 #include <tf/transform_datatypes.h>
00034 #include <geometry_msgs/PoseWithCovarianceStamped.h>
00035 #include <sensor_msgs/NavSatFix.h>
00036 #include <sensor_msgs/NavSatStatus.h>
00037 #include <geometry_msgs/Vector3Stamped.h>
00038 #include <geometry_msgs/Quaternion.h>
00039 #include <std_msgs/Float64.h>
00040 #include <std_msgs/Header.h>
00041
00042 namespace mavplugin {
00043
00051 class GlobalPositionPlugin : public MavRosPlugin {
00052 public:
00053 GlobalPositionPlugin() :
00054 uas(nullptr),
00055 send_tf(false),
00056 rot_cov(99999.0)
00057 { };
00058
00059 void initialize(UAS &uas_,
00060 ros::NodeHandle &nh,
00061 diagnostic_updater::Updater &diag_updater)
00062 {
00063 uas = &uas_;
00064
00065 gp_nh = ros::NodeHandle(nh, "global_position");
00066
00067 gp_nh.param("send_tf", send_tf, true);
00068 gp_nh.param<std::string>("frame_id", frame_id, "local_origin");
00069 gp_nh.param<std::string>("child_frame_id", child_frame_id, "fcu");
00070 gp_nh.param<double>("rot_covariance", rot_cov, 99999.0);
00071
00072 fix_pub = gp_nh.advertise<sensor_msgs::NavSatFix>("global", 10);
00073 pos_pub = gp_nh.advertise<geometry_msgs::PoseWithCovarianceStamped>("local", 10);
00074 vel_pub = gp_nh.advertise<geometry_msgs::Vector3Stamped>("gps_vel", 10);
00075 rel_alt_pub = gp_nh.advertise<std_msgs::Float64>("rel_alt", 10);
00076 hdg_pub = gp_nh.advertise<std_msgs::Float64>("compass_hdg", 10);
00077 }
00078
00079 std::string const get_name() const {
00080 return "GlobalPosition";
00081 }
00082
00083 const message_map get_rx_handlers() {
00084 return {
00085 MESSAGE_HANDLER(MAVLINK_MSG_ID_GLOBAL_POSITION_INT, &GlobalPositionPlugin::handle_global_position_int)
00086 };
00087 }
00088
00089 private:
00090 UAS *uas;
00091
00092 ros::NodeHandle gp_nh;
00093 ros::Publisher fix_pub;
00094 ros::Publisher pos_pub;
00095 ros::Publisher vel_pub;
00096 ros::Publisher hdg_pub;
00097 ros::Publisher rel_alt_pub;
00098
00099 tf::TransformBroadcaster tf_broadcaster;
00100
00101 std::string frame_id;
00102 std::string child_frame_id;
00103 bool send_tf;
00104 double rot_cov;
00105
00110 void handle_global_position_int(const mavlink_message_t *msg, uint8_t sysid, uint8_t compid) {
00111 mavlink_global_position_int_t gp_pos;
00112 mavlink_msg_global_position_int_decode(msg, &gp_pos);
00113
00114 ROS_DEBUG_THROTTLE_NAMED(10, "global", "Global position: boot_ms:%06d "
00115 "lat/lon/alt:(%d %d %d) relative_alt: (%d) gps_vel:(%d %d %d) compass_heading: (%d)",
00116 gp_pos.time_boot_ms,
00117 gp_pos.lat, gp_pos.lon, gp_pos.alt, gp_pos.relative_alt,
00118 gp_pos.vx, gp_pos.vy, gp_pos.vz, gp_pos.hdg);
00119
00120 geometry_msgs::PoseWithCovarianceStampedPtr pose_cov =
00121 boost::make_shared<geometry_msgs::PoseWithCovarianceStamped>();
00122
00123 std_msgs::Header header;
00124 header.frame_id = frame_id;
00125 header.stamp = ros::Time::now();
00126
00127 sensor_msgs::NavSatFixPtr gps_cord =
00128 boost::make_shared<sensor_msgs::NavSatFix>();
00129 geometry_msgs::Vector3StampedPtr gps_vel =
00130 boost::make_shared<geometry_msgs::Vector3Stamped>();
00131 std_msgs::Float64Ptr relative_alt = boost::make_shared<std_msgs::Float64>();
00132 std_msgs::Float64Ptr compass_heading = boost::make_shared<std_msgs::Float64>();
00133
00134 gps_cord->header = header;
00135 gps_cord->latitude = gp_pos.lat / 1E7;
00136 gps_cord->longitude = gp_pos.lon / 1E7;
00137 gps_cord->altitude = gp_pos.alt / 1E3;
00138
00139
00140 gps_cord->status.service = sensor_msgs::NavSatStatus::SERVICE_GPS;
00141 if (uas->get_gps_status())
00142 gps_cord->status.status = sensor_msgs::NavSatStatus::STATUS_FIX;
00143 else
00144 gps_cord->status.status = sensor_msgs::NavSatStatus::STATUS_NO_FIX;
00145
00146
00147 double hdop = uas->get_gps_eph();
00148 if (!isnan(hdop)) {
00149 double hdop2 = std::pow(hdop, 2);
00150
00151
00152 gps_cord->position_covariance[0] = hdop2;
00153 gps_cord->position_covariance[4] = hdop2;
00154 gps_cord->position_covariance[8] = std::pow(2 * hdop, 2);
00155 gps_cord->position_covariance_type =
00156 sensor_msgs::NavSatFix::COVARIANCE_TYPE_APPROXIMATED;
00157 }
00158 else {
00159 gps_cord->position_covariance_type =
00160 sensor_msgs::NavSatFix::COVARIANCE_TYPE_UNKNOWN;
00161 }
00162
00163 gps_vel->header = header;
00164 gps_vel->vector.x = gp_pos.vx / 1E2;
00165 gps_vel->vector.y = gp_pos.vy / 1E2;
00166 gps_vel->vector.z = gp_pos.vz / 1E2;
00167
00168 relative_alt->data = gp_pos.relative_alt / 1E3;
00169 if (gp_pos.hdg != UINT16_MAX)
00170 compass_heading->data = gp_pos.hdg / 1E2;
00171
00172 double northing, easting;
00173 std::string zone;
00174
00178 UTM::LLtoUTM(gps_cord->latitude, gps_cord->longitude, northing, easting, zone);
00179
00180 pose_cov->header = header;
00181 pose_cov->pose.pose.position.x = easting;
00182 pose_cov->pose.pose.position.y = northing;
00183 pose_cov->pose.pose.position.z = gp_pos.relative_alt / 1E3;
00184
00185 geometry_msgs::Quaternion q_aux;
00186 tf::Quaternion q(uas->get_attitude_orientation());
00187 tf::quaternionTFToMsg(q, q_aux);
00188 pose_cov->pose.pose.orientation = q_aux;
00189
00190
00191 boost::array<double, 36> covariance = {
00192 gps_cord->position_covariance[0],
00193 gps_cord->position_covariance[1],
00194 gps_cord->position_covariance[2],
00195 0, 0, 0,
00196 gps_cord->position_covariance[3],
00197 gps_cord->position_covariance[4],
00198 gps_cord->position_covariance[5],
00199 0, 0, 0,
00200 gps_cord->position_covariance[6],
00201 gps_cord->position_covariance[7],
00202 gps_cord->position_covariance[8],
00203 0, 0, 0,
00204 0, 0, 0, rot_cov, 0, 0,
00205 0, 0, 0, 0, rot_cov, 0,
00206 0, 0, 0, 0, 0, rot_cov
00207 };
00208
00209 pose_cov->pose.covariance = covariance;
00210
00211 fix_pub.publish(gps_cord);
00212 pos_pub.publish(pose_cov);
00213 vel_pub.publish(gps_vel);
00214 rel_alt_pub.publish(relative_alt);
00215 if (gp_pos.hdg != UINT16_MAX)
00216 hdg_pub.publish(compass_heading);
00217
00218 if (send_tf) {
00219 tf::Transform transform;
00220
00221 transform.setOrigin(tf::Vector3(pose_cov->pose.pose.position.y,
00222 pose_cov->pose.pose.position.x,
00223 -pose_cov->pose.pose.position.z));
00224
00225 transform.setRotation(uas->get_attitude_orientation());
00226
00227 tf_broadcaster.sendTransform(
00228 tf::StampedTransform(
00229 transform,
00230 pose_cov->header.stamp,
00231 frame_id, child_frame_id));
00232 }
00233 }
00234 };
00235
00236 };
00237
00238 PLUGINLIB_EXPORT_CLASS(mavplugin::GlobalPositionPlugin, mavplugin::MavRosPlugin)