vpe_publisher.cpp
Go to the documentation of this file.
1 /*
2  * VPE publisher node
3  * Copyright (C) 2018 Copter Express Technologies
4  *
5  * Author: Oleg Kalachev <okalachev@gmail.com>
6  *
7  * Distributed under MIT License (available at https://opensource.org/licenses/MIT).
8  * The above copyright notice and this permission notice shall be included in all
9  * copies or substantial portions of the Software.
10  */
11 
12 #include <string>
13 #include <ros/ros.h>
15 #include <tf2_ros/buffer.h>
19 #include <geometry_msgs/TransformStamped.h>
20 #include <geometry_msgs/PoseStamped.h>
21 #include <geometry_msgs/PoseWithCovarianceStamped.h>
22 #include <std_srvs/Trigger.h>
23 // #include <aruco_pose/MarkerArray.h>
24 
25 using std::string;
26 using namespace geometry_msgs;
27 
28 bool reset_flag = false;
34 PoseStamped vpe, pose;
37 TransformStamped offset;
38 
40 {
41  if (e.current_real - vpe.header.stamp < publish_zero_timout) return; // have vpe
42 
43  if (e.current_real - pose.header.stamp < publish_zero_timout) { // have local position
44  if (got_local_pos.isZero()) {
45  ROS_INFO("got local position");
47  }
48 
49  if (e.current_real - got_local_pos > publish_zero_duration) return; // stop publishing zero
50  } else {
51  // lost local position
53  }
54 
55  ROS_INFO_THROTTLE(10, "publish zero");
56  static geometry_msgs::PoseStamped zero;
57  zero.header.frame_id = local_frame_id;
58  zero.header.stamp = e.current_real;
59  zero.pose.orientation.w = 1;
60  vpe_pub.publish(zero);
61 }
62 
63 void localPositionCallback(const PoseStamped& msg) { pose = msg; }
64 
65 inline Pose getPose(const PoseStampedConstPtr& pose) { return pose->pose; }
66 
67 inline Pose getPose(const PoseWithCovarianceStampedConstPtr& pose) { return pose->pose.pose; }
68 
69 template <typename T>
70 void callback(const T& msg)
71 {
73 
74  try {
75  if (!frame_id.empty()) {
76  // get VPE transform from TF
78  msg->header.stamp, ros::Duration(0.02));
79  vpe.pose.position.x = transform.transform.translation.x;
80  vpe.pose.position.y = transform.transform.translation.y;
81  vpe.pose.position.z = transform.transform.translation.z;
82  vpe.pose.orientation = transform.transform.rotation;
83  } else {
84  vpe.pose = getPose(msg);
85  }
86 
87  // offset
88  if (!offset_frame_id.empty()) {
89  if (reset_flag || msg->header.stamp - vpe.header.stamp > offset_timeout) {
90  // calculate the offset
92  msg->header.stamp, ros::Duration(0.02));
93  // offset.header.frame_id = vpe.header.frame_id;
94  offset.child_frame_id = offset_frame_id;
96  reset_flag = false;
97  ROS_INFO("offset reset");
98  }
99  // apply the offset
101  }
102 
103  vpe.header.frame_id = local_frame_id;
104  vpe.header.stamp = msg->header.stamp;
105  vpe_pub.publish(vpe);
106 
107  } catch (const tf2::TransformException& e) {
108  ROS_WARN_THROTTLE(5, "%s", e.what());
109  }
110 }
111 
112 bool reset(std_srvs::Trigger::Request& req, std_srvs::Trigger::Response& res)
113 {
114  reset_flag = true;
115  res.success = true;
116  return true;
117 }
118 
119 int main(int argc, char **argv) {
120  ros::init(argc, argv, "vpe_publisher");
121  ros::NodeHandle nh, nh_priv("~");
122 
124 
125  nh_priv.param<string>("frame_id", frame_id, "");
126  nh_priv.param<string>("offset_frame_id", offset_frame_id, "");
127  nh_priv.param<string>("mavros/local_position/frame_id", local_frame_id, "map");
128  nh_priv.param<string>("mavros/local_position/tf/child_frame_id", child_frame_id, "base_link");
129  offset_timeout = ros::Duration(nh_priv.param("offset_timeout", 3.0));
130 
131  if (!frame_id.empty()) {
132  ROS_INFO("using data from TF");
133  } else {
134  ROS_INFO("using data topic");
135  }
136 
137  auto pose_sub = nh_priv.subscribe<PoseStamped>("pose", 1, &callback);
138  auto pose_cov_sub = nh_priv.subscribe<PoseWithCovarianceStamped>("pose_cov", 1, &callback);
139  //auto markers_sub = nh_priv.subscribe<aruco_pose::MarkerArray>("markers", 1, &callback);
140 
141  vpe_pub = nh_priv.advertise<PoseStamped>("vpe", 1);
142  //vpe_cov_pub = nh_priv_.advertise<PoseStamped>("pose_cov_pub", 1);
143 
144  if (nh_priv.param("publish_zero", false)) {
145  // publish zero to initialize the local position
146  zero_timer = nh.createTimer(ros::Duration(0.1), &publishZero);
147  publish_zero_timout = ros::Duration(nh_priv.param("publish_zero_timout", 5.0));
148  publish_zero_duration = ros::Duration(nh_priv.param("publish_zero_duration", 5.0));
149  local_position_sub = nh.subscribe("mavros/local_position/pose", 1, &localPositionCallback);
150  }
151 
152  auto reset_serv = nh_priv.advertiseService("reset", &reset);
153 
154  ROS_INFO("ready");
155  ros::spin();
156 }
PoseStamped vpe
ros::Duration publish_zero_timout
message_filters::Subscriber< geometry_msgs::PoseStamped > pose_sub
ros::NodeHandle nh
void localPositionCallback(const PoseStamped &msg)
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
int main(int argc, char **argv)
TransformStamped offset
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
ros::Time got_local_pos(0)
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
void doTransform(const T &data_in, T &data_out, const geometry_msgs::TransformStamped &transform)
ros::Duration offset_timeout
string child_frame_id
bool param(const std::string &param_name, T &param_val, const T &default_val) const
virtual geometry_msgs::TransformStamped lookupTransform(const std::string &target_frame, const std::string &source_frame, const ros::Time &time, const ros::Duration timeout) const
void publish(const boost::shared_ptr< M > &message) const
bool reset_flag
#define ROS_INFO_THROTTLE(period,...)
ros::Publisher vpe_pub
tf2_ros::Buffer tf_buffer
#define ROS_WARN_THROTTLE(period,...)
#define ROS_INFO(...)
void callback(const T &msg)
Pose getPose(const PoseStampedConstPtr &pose)
string frame_id
ros::Subscriber local_position_sub
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
ROSCPP_DECL void spin()
string offset_frame_id
br
ros::Duration publish_zero_duration
ros::Timer zero_timer
ftf::StaticTF transform
PoseStamped pose
string local_frame_id
void sendTransform(const geometry_msgs::TransformStamped &transform)
void publishZero(const ros::TimerEvent &e)
bool reset(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)


clover
Author(s): Oleg Kalachev , Artem Smirnov
autogenerated on Mon Feb 28 2022 22:08:29