PX4 Teleop
joy_publisher.cpp
Go to the documentation of this file.
1 
7 // C/C++ Libraries
8 #include <iostream>
9 #include <iomanip>
10 #include <vector>
11 #include <cstdio>
12 #include <string>
13 #include <stdexcept>
14 
15 #include <limits.h>
16 #include <fcntl.h>
17 #include <unistd.h>
18 #include <sys/ioctl.h>
19 #include <linux/joystick.h>
20 
21 // roscpp
22 #include <ros/ros.h>
23 #include <ros/package.h>
24 
25 // sensor_msgs
26 #include <sensor_msgs/Joy.h>
27 
28 
29 int main(int argc, char **argv){
30 
31  ros::init(argc, argv, "joy_publisher");
32  ros::NodeHandle nh("~");
33 
34  ros::Publisher joy_pub = nh.advertise<sensor_msgs::Joy>("joy", 100);
35 
36  ros::Rate rate(100);
37 
38  // Declare joystick file descriptor
39  std::string joy_dev;
40  nh.param<std::string>("joy_dev", joy_dev, "/dev/input/js0");
41 
42  ROS_INFO("Device: %s", joy_dev.c_str());
43 
44  // Set variables about joystick
45  int joy_fd = -1;
46  int num_of_axes = 0;
47  int num_of_buttons = 0;
48  char name_of_joystick[80];
49  std::vector<int32_t> joy_button;
50  std::vector<float> joy_axes;
51 
52  // Open joy_dev
53  if((joy_fd = open(joy_dev.c_str(), O_RDONLY)) < 0){
54  ROS_ERROR("Failed to open %s", joy_dev.c_str());
55  return -1;
56  }
57 
58  // Get info about joystick
59  ioctl(joy_fd, JSIOCGAXES, &num_of_axes);
60  ioctl(joy_fd, JSIOCGBUTTONS, &num_of_buttons);
61  ioctl(joy_fd, JSIOCGNAME(80), &name_of_joystick);
62 
63  // Resize vector
64  joy_button.resize(num_of_buttons,0);
65  joy_axes.resize(num_of_axes,0);
66 
67  ROS_INFO("Joystick: %s", name_of_joystick);
68  ROS_INFO("Axis: %d", num_of_axes);
69  ROS_INFO("Buttons: %d", num_of_buttons);
70 
71  // Use non-blocking mode
72  fcntl(joy_fd, F_SETFL, O_NONBLOCK);
73 
74  while(ros::ok()){
75 
76  // https://www.kernel.org/doc/Documentation/input/joystick-api.txt
77  //struct js_event{
78  // __u32 time; /* event timestamp in milliseconds */
79  // __s16 value; /* value */
80  // __u8 type; /* event type */
81  // __u8 number; /* axis/button number */
82  //}
83  js_event js;
84 
85  sensor_msgs::Joy joy_msg;
86 
87  auto _ = read(joy_fd, &js, sizeof(js_event));
88 
89  // the driver will issue synthetic JS_EVENT_INIT on open
90  // js.type will be like following if it is issuing INIT BUTTON event
91  // js.type = JS_EVENT_BUTTON | JS_EVENT_INIT
92  // So, js.type & ~JS_EVENT_INIT equals
93  // JS_EVENT_BUTTON or JS_EVENT_AXIS
94  switch(js.type & ~JS_EVENT_INIT){
95  case JS_EVENT_AXIS:
96  try{
97  joy_axes.at((int)js.number) = (float)(js.value)/SHRT_MAX;
98  }catch(std::out_of_range& e){
99  break;
100  }
101  break;
102 
103  case JS_EVENT_BUTTON:
104  try{
105  joy_button.at((int)js.number) = js.value;
106  }catch(std::out_of_range& e){
107  break;
108  }
109  break;
110  }
111 
112  joy_msg.axes = joy_axes;
113  joy_msg.buttons = joy_button;
114 
115  joy_pub.publish(joy_msg);
116 
117  ros::spinOnce();
118  rate.sleep();
119  }
120 
121  close(joy_fd);
122  return 0;
123 }
sensor_msgs::Joy joy_msg
Storage for joystick input.
int main(int argc, char **argv)