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/setpoint_mixin.h>
00030 #include <pluginlib/class_list_macros.h>
00031
00032 #include <geometry_msgs/PoseStamped.h>
00033 #include <geometry_msgs/PoseWithCovarianceStamped.h>
00034
00035 namespace mavplugin {
00036
00044 class VisionPoseEstimatePlugin : public MavRosPlugin,
00045 private TFListenerMixin<VisionPoseEstimatePlugin> {
00046 public:
00047 VisionPoseEstimatePlugin() :
00048 uas(nullptr),
00049 tf_rate(10.0)
00050 { };
00051
00052 void initialize(UAS &uas_,
00053 ros::NodeHandle &nh,
00054 diagnostic_updater::Updater &diag_updater)
00055 {
00056 bool pose_with_covariance;
00057 bool listen_tf;
00058
00059 uas = &uas_;
00060 sp_nh = ros::NodeHandle(nh, "position");
00061
00062 sp_nh.param("vision/pose_with_covariance", pose_with_covariance, false);
00063 sp_nh.param("vision/listen_tf", listen_tf, false);
00064 sp_nh.param<std::string>("vision/frame_id", frame_id, "local_origin");
00065 sp_nh.param<std::string>("vision/child_frame_id", child_frame_id, "vision");
00066 sp_nh.param("vision/tf_rate_limit", tf_rate, 50.0);
00067
00068 ROS_DEBUG_STREAM_NAMED("position", "Vision pose topic type: " <<
00069 ((pose_with_covariance)? "PoseWithCovarianceStamped" : "PoseStamped"));
00070
00071 if (listen_tf) {
00072 ROS_INFO_STREAM_NAMED("position", "Listen to vision transform " << frame_id
00073 << " -> " << child_frame_id);
00074 tf_start("VisionTF", &VisionPoseEstimatePlugin::send_vision_transform);
00075 }
00076 else if (pose_with_covariance)
00077 vision_sub = sp_nh.subscribe("vision", 10, &VisionPoseEstimatePlugin::vision_cov_cb, this);
00078 else
00079 vision_sub = sp_nh.subscribe("vision", 10, &VisionPoseEstimatePlugin::vision_cb, this);
00080 }
00081
00082 const std::string get_name() const {
00083 return "VisionPoseEstimate";
00084 }
00085
00086 const message_map get_rx_handlers() {
00087 return { };
00088 }
00089
00090 private:
00091 friend class TFListenerMixin;
00092 UAS *uas;
00093
00094 ros::NodeHandle sp_nh;
00095 ros::Subscriber vision_sub;
00096
00097 std::string frame_id;
00098 std::string child_frame_id;
00099
00100 double tf_rate;
00101 ros::Time last_transform_stamp;
00102
00103
00104
00105 void vision_position_estimate(uint64_t usec,
00106 float x, float y, float z,
00107 float roll, float pitch, float yaw) {
00108 mavlink_message_t msg;
00109 mavlink_msg_vision_position_estimate_pack_chan(UAS_PACK_CHAN(uas), &msg,
00110 usec,
00111 x,
00112 y,
00113 z,
00114 roll,
00115 pitch,
00116 yaw);
00117 UAS_FCU(uas)->send_message(&msg);
00118 }
00119
00120
00121
00125 void send_vision_transform(const tf::Transform &transform, const ros::Time &stamp) {
00126
00127 tf::Vector3 position = transform.getOrigin();
00128 double roll, pitch, yaw;
00129 tf::Matrix3x3 orientation(transform.getBasis());
00130 orientation.getRPY(roll, pitch, yaw);
00131
00132
00133
00134
00135 if (last_transform_stamp == stamp) {
00136 ROS_DEBUG_THROTTLE_NAMED(10, "position", "Vision: Same transform as last one, dropped.");
00137 return;
00138 }
00139 last_transform_stamp = stamp;
00140
00141
00142 vision_position_estimate(stamp.toNSec() / 1000,
00143 position.y(), position.x(), -position.z(),
00144 roll, -pitch, -yaw);
00145 }
00146
00147
00148
00149
00150
00151 void vision_cov_cb(const geometry_msgs::PoseWithCovarianceStamped::ConstPtr &req) {
00152 tf::Transform transform;
00153 poseMsgToTF(req->pose.pose, transform);
00154 send_vision_transform(transform, req->header.stamp);
00155 }
00156
00157 void vision_cb(const geometry_msgs::PoseStamped::ConstPtr &req) {
00158 tf::Transform transform;
00159 poseMsgToTF(req->pose, transform);
00160 send_vision_transform(transform, req->header.stamp);
00161 }
00162 };
00163
00164 };
00165
00166 PLUGINLIB_EXPORT_CLASS(mavplugin::VisionPoseEstimatePlugin, mavplugin::MavRosPlugin)