joyop.cpp
Go to the documentation of this file.
1 
6 #include <ecl/exceptions.hpp>
7 #include <ecl/time.hpp>
8 #include <geometry_msgs/Twist.h>
9 #include <ros/ros.h>
10 #include <sensor_msgs/Joy.h>
11 #include <std_msgs/String.h>
12 #include "boost/thread/mutex.hpp"
13 #include "boost/thread/thread.hpp"
14 
15 
16 namespace yocs_joyop
17 {
18 
19 class JoyOp
20 {
21 public:
22  JoyOp();
23 
24 private:
25  void joyCallback(const sensor_msgs::Joy::ConstPtr& joy);
26  void publish();
27 
29 
30  // states
32  // button ids
37 
38  geometry_msgs::Twist last_published_;
39  boost::mutex publish_mutex_;
40  // callback notifications (kept separate from current state)
44 
45 };
46 
48  ph_("~"),
49  linear_(1),
50  angular_(0),
51  deadman_button_(4),
52  enable_button_(0),
53  disable_button_(1),
54  l_scale_(0.3),
55  a_scale_(0.9),
56  spin_freq_(10),
58  enabled_(false),
59  enable_pressed_(false),
60  disable_pressed_(false),
61  deadman_pressed_(false),
63 {
64  ph_.param("linear_axis", linear_, linear_);
65  ph_.param("angular_axis", angular_, angular_);
66  ph_.param("deadman_button", deadman_button_, deadman_button_);
67  ph_.param("enable_button", enable_button_, enable_button_);
68  ph_.param("disable_button", disable_button_, disable_button_);
69  ph_.param("angular_scale", a_scale_, a_scale_);
70  ph_.param("linear_scale", l_scale_, l_scale_);
71  ph_.param("spin_frequency", spin_freq_, spin_freq_);
72  ph_.param("wait_for_connection", wait_for_connection_, wait_for_connection_);
73 
74  enable_pub_ = ph_.advertise<std_msgs::String>("enable", 1, true);
75  disable_pub_ = ph_.advertise<std_msgs::String>("disable", 1, true);
76  vel_pub_ = ph_.advertise<geometry_msgs::Twist>("cmd_vel", 1, true);
77  joy_sub_ = nh_.subscribe<sensor_msgs::Joy>("joy", 10, &JoyOp::joyCallback, this);
78 
79  timer_ = nh_.createTimer(ros::Duration(1/spin_freq_), boost::bind(&JoyOp::publish, this));
80 
81  /******************************************
82  ** Wait for connection
83  *******************************************/
84  // this is only waiting for the enable/disable connection and if connected
85  // it will send the 'all' message to enable the motors automatically
86  if (wait_for_connection_ <= 0)
87  {
88  return;
89  }
90  ecl::MilliSleep millisleep;
91  int count = 0;
92  bool connected = false;
93  while (!connected)
94  {
95  if ((enable_pub_.getNumSubscribers() > 0) &&
96  (disable_pub_.getNumSubscribers() > 0))
97  {
98  connected = true;
99  break;
100  }
101  if (count == 2*wait_for_connection_) // loop every 500ms
102  {
103  connected = false;
104  break;
105  }
106  else
107  {
108  ROS_WARN_STREAM("JoyOp: Could not connect, trying again after 500ms...");
109  try
110  {
111  millisleep(500);
112  }
113  catch (ecl::StandardException& e)
114  {
115  ROS_ERROR_STREAM("JoyOp: Waiting has been interrupted.");
116  ROS_DEBUG_STREAM(e.what());
117  return;
118  }
119  ++count;
120  }
121  }
122  if (!connected)
123  {
124  ROS_ERROR("JoyOp: Could not connect.");
125  ROS_ERROR("JoyOp: Check remappings for enable/disable topics.");
126  }
127  else
128  {
129  std_msgs::String msg;
130  msg.data = "all";
131  enable_pub_.publish(msg);
132  ROS_INFO("JoyOp: connected.");
133  }
134 }
135 
136 void JoyOp::joyCallback(const sensor_msgs::Joy::ConstPtr& joy)
137 {
138  geometry_msgs::Twist vel;
139  vel.angular.z = a_scale_*joy->axes[angular_];
140  vel.linear.x = l_scale_*joy->axes[linear_];
141  last_published_ = vel;
142  deadman_pressed_ = joy->buttons[deadman_button_];
143  enable_pressed_ = joy->buttons[enable_button_];
144  disable_pressed_ = joy->buttons[disable_button_];
145 }
146 
148 {
149  boost::mutex::scoped_lock lock(publish_mutex_);
150 
152  {
153  if(!enabled_)
154  {
155  ROS_INFO_STREAM("JoyOp: Enabling motors.");
156  std_msgs::String msg;
157  msg.data = "all";
158  enable_pub_.publish(msg);
159  enabled_ = true;
160  }
161  else
162  {
163  ROS_WARN_STREAM("JoyOp: Motors have already been enabled.");
164  }
165  }
166  else if (disable_pressed_)
167  {
168  if(enabled_)
169  {
170  ROS_INFO_STREAM("JoyOp: die, die, die (disabling motors).");
171  std_msgs::String msg;
172  msg.data = "all";
173  enable_pub_.publish(msg);
174  enabled_ = true;
175  }
176  else
177  {
178  ROS_WARN_STREAM("JoyOp: Motors have already been disabled.");
179  }
180  std_msgs::String msg;
181  msg.data = "all";
182  disable_pub_.publish(msg);
183  enabled_ = false;
184  }
185 
186  if (deadman_pressed_)
187  {
188  if (enabled_)
189  {
191  zero_twist_published_=false;
192  }
193  else
194  {
195  ROS_WARN_STREAM_THROTTLE(1.0, "JoyOp: Motor system disabled. Won't send velocity commands.");
196  }
197  }
199  {
200  vel_pub_.publish(*new geometry_msgs::Twist());
202  }
203 }
204 
205 } // namespace yocs_joyop
206 
207 int main(int argc, char** argv)
208 {
209  ros::init(argc, argv, "yocs_joyop");
210  yocs_joyop::JoyOp joyop;
211 
212  ros::spin();
213 }
msg
ros::NodeHandle nh_
Definition: joyop.cpp:28
int disable_button_
Definition: joyop.cpp:33
void publish(const boost::shared_ptr< M > &message) const
const char * what() const
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
ros::Subscriber joy_sub_
Definition: joyop.cpp:36
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
double spin_freq_
Definition: joyop.cpp:34
bool disable_pressed_
Definition: joyop.cpp:41
int wait_for_connection_
Definition: joyop.cpp:42
boost::mutex publish_mutex_
Definition: joyop.cpp:39
ros::Publisher enable_pub_
Definition: joyop.cpp:35
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
void publish()
Definition: joyop.cpp:147
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
int main(int argc, char **argv)
Definition: joyop.cpp:207
int deadman_button_
Definition: joyop.cpp:33
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
ROSCPP_DECL void spin()
#define ROS_WARN_STREAM(args)
#define ROS_DEBUG_STREAM(args)
bool deadman_pressed_
Definition: joyop.cpp:41
ros::Publisher disable_pub_
Definition: joyop.cpp:35
#define ROS_WARN_STREAM_THROTTLE(rate, args)
ros::NodeHandle ph_
Definition: joyop.cpp:28
double a_scale_
Definition: joyop.cpp:34
uint32_t getNumSubscribers() const
#define ROS_INFO_STREAM(args)
ros::Timer timer_
Definition: joyop.cpp:43
bool enable_pressed_
Definition: joyop.cpp:41
bool zero_twist_published_
Definition: joyop.cpp:41
geometry_msgs::Twist last_published_
Definition: joyop.cpp:38
ros::Publisher vel_pub_
Definition: joyop.cpp:35
#define ROS_ERROR_STREAM(args)
#define ROS_ERROR(...)
void joyCallback(const sensor_msgs::Joy::ConstPtr &joy)
Definition: joyop.cpp:136
double l_scale_
Definition: joyop.cpp:34
int enable_button_
Definition: joyop.cpp:33


yocs_joyop
Author(s): Marcus Liebhardt
autogenerated on Mon Jun 10 2019 15:53:33