cmd_vel_smoother.cpp
Go to the documentation of this file.
1 #include <cmath>
2 #include <boost/shared_ptr.hpp>
3 #include <ros/ros.h>
4 #include <dynamic_reconfigure/server.h>
5 #include <cmd_vel_smoother/CmdVelSmootherConfig.h>
6 #include <geometry_msgs/Twist.h>
7 
8 template<class T> inline T sgn(T val) { return val > 0 ? 1.0 : -1.0; }
9 
10 namespace dyn = dynamic_reconfigure;
11 
13 {
18 
19  boost::mutex cfg_mutex_;
20  typedef cmd_vel_smoother::CmdVelSmootherConfig Config;
22 
24  double desired_rate_;
27  geometry_msgs::Twist::ConstPtr latest_vel_;
28  geometry_msgs::Twist::Ptr pub_vel_;
29 
30 public:
32  return ros::Duration(1./(desired_rate_ * 2.2));
33  }
34 
35  void dynConfigCallback(Config &cfg, uint32_t level) {
36  boost::mutex::scoped_lock lock(cfg_mutex_);
37  x_acc_lim_ = cfg.x_acc_lim;
38  y_acc_lim_ = cfg.y_acc_lim;
39  yaw_acc_lim_ = cfg.yaw_acc_lim;
40  interpolate_max_frame_ = cfg.interpolate_max_frame;
41 
42  if(desired_rate_ != cfg.desired_rate) {
43  desired_rate_ = cfg.desired_rate;
44  if (timer_.isValid()) {
46  timer_.setPeriod(d);
47  ROS_INFO_STREAM("timer loop rate is changed to " << 1.0 / d.toSec() << "[Hz]");
48  }
49  }
50  }
51 
52  void velCallback(const geometry_msgs::Twist::ConstPtr &msg){
53  latest_time_ = ros::Time::now();
54  latest_vel_ = msg;
55  count_ = 0;
56  pub_.publish(msg);
57  }
58 
59  void timerCallback(const ros::TimerEvent& event){
60  if (count_ > interpolate_max_frame_) return;
61  if (latest_vel_ == NULL) return;
62 
63  double past_sec = (event.current_real - latest_time_).toSec();
64  if (past_sec < 1.0 / desired_rate_) return;
65 
66  double g_x = std::abs(latest_vel_->linear.x / past_sec);
67  double g_y = std::abs(latest_vel_->linear.y / past_sec);
68  double g_yaw = std::abs(latest_vel_->angular.z / past_sec);
69 
70  ROS_DEBUG_STREAM("G: (" << g_x << ", " << g_y << ", " << g_yaw << ") detected");
71 
72  bool need_publish = false;
73  if (g_x > x_acc_lim_) {
74  pub_vel_->linear.x = (g_x - x_acc_lim_) * past_sec * sgn(latest_vel_->linear.x);
75  need_publish = true;
76  }
77 
78  if (g_y > y_acc_lim_) {
79  pub_vel_->linear.y = (g_y - y_acc_lim_) * past_sec * sgn(latest_vel_->linear.y);
80  need_publish = true;
81  }
82 
83  if (g_yaw > yaw_acc_lim_) {
84  pub_vel_->angular.z = (g_yaw - yaw_acc_lim_) * past_sec * sgn(latest_vel_->angular.z);
85  need_publish = true;
86  }
87 
88  if (need_publish)
89  pub_.publish(*pub_vel_);
90  count_++;
91  }
92 
93  VelocitySmootherNode(): nh_(), pnh_("~") {
94  latest_time_ = ros::Time::now();
95 
96  dyn_srv_ = boost::make_shared<dyn::Server<Config> >(pnh_);
97  dyn::Server<Config>::CallbackType f = boost::bind(&VelocitySmootherNode::dynConfigCallback, this, _1, _2);
98  dyn_srv_->setCallback(f);
99 
100  pub_vel_ = boost::shared_ptr<geometry_msgs::Twist>(new geometry_msgs::Twist());
101  pub_ = nh_.advertise<geometry_msgs::Twist>("output", 100);
102  sub_ = nh_.subscribe("input", 1, &VelocitySmootherNode::velCallback, this);
104  };
106 
107 };
108 
109 int main(int argc, char** argv) {
110  ros::init(argc, argv, "cmd_vel_smoother");
112  ros::spin();
113 
114  return 0;
115 }
116 
d
T sgn(T val)
void publish(const boost::shared_ptr< M > &message) const
f
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
void setPeriod(const Duration &period, bool reset=true)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
void timerCallback(const ros::TimerEvent &event)
geometry_msgs::Twist::ConstPtr latest_vel_
boost::shared_ptr< dyn::Server< Config > > dyn_srv_
ros::Duration timerDuration()
void velCallback(const geometry_msgs::Twist::ConstPtr &msg)
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
ROSCPP_DECL void spin()
#define ROS_DEBUG_STREAM(args)
geometry_msgs::Twist::Ptr pub_vel_
bool isValid()
int main(int argc, char **argv)
#define ROS_INFO_STREAM(args)
cmd_vel_smoother::CmdVelSmootherConfig Config
static Time now()
void dynConfigCallback(Config &cfg, uint32_t level)


cmd_vel_smoother
Author(s): Yuki Furuta
autogenerated on Fri May 14 2021 02:51:38