teleop_turtle_key.cpp
Go to the documentation of this file.
1 #include <ros/ros.h>
2 #include <geometry_msgs/Twist.h>
3 #include <signal.h>
4 #include <stdio.h>
5 #ifndef _WIN32
6 # include <termios.h>
7 # include <unistd.h>
8 #else
9 # include <windows.h>
10 #endif
11 
12 #define KEYCODE_RIGHT 0x43
13 #define KEYCODE_LEFT 0x44
14 #define KEYCODE_UP 0x41
15 #define KEYCODE_DOWN 0x42
16 #define KEYCODE_B 0x62
17 #define KEYCODE_C 0x63
18 #define KEYCODE_D 0x64
19 #define KEYCODE_E 0x65
20 #define KEYCODE_F 0x66
21 #define KEYCODE_G 0x67
22 #define KEYCODE_Q 0x71
23 #define KEYCODE_R 0x72
24 #define KEYCODE_T 0x74
25 #define KEYCODE_V 0x76
26 
28 {
29 public:
31 #ifndef _WIN32
32  : kfd(0)
33 #endif
34  {
35 #ifndef _WIN32
36  // get the console in raw mode
37  tcgetattr(kfd, &cooked);
38  struct termios raw;
39  memcpy(&raw, &cooked, sizeof(struct termios));
40  raw.c_lflag &=~ (ICANON | ECHO);
41  // Setting a new line, then end of file
42  raw.c_cc[VEOL] = 1;
43  raw.c_cc[VEOF] = 2;
44  tcsetattr(kfd, TCSANOW, &raw);
45 #endif
46  }
47  void readOne(char * c)
48  {
49 #ifndef _WIN32
50  int rc = read(kfd, c, 1);
51  if (rc < 0)
52  {
53  throw std::runtime_error("read failed");
54  }
55 #else
56  for(;;)
57  {
58  HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
59  INPUT_RECORD buffer;
60  DWORD events;
61  PeekConsoleInput(handle, &buffer, 1, &events);
62  if(events > 0)
63  {
64  ReadConsoleInput(handle, &buffer, 1, &events);
65  if (buffer.Event.KeyEvent.wVirtualKeyCode == VK_LEFT)
66  {
67  *c = KEYCODE_LEFT;
68  return;
69  }
70  else if (buffer.Event.KeyEvent.wVirtualKeyCode == VK_UP)
71  {
72  *c = KEYCODE_UP;
73  return;
74  }
75  else if (buffer.Event.KeyEvent.wVirtualKeyCode == VK_RIGHT)
76  {
77  *c = KEYCODE_RIGHT;
78  return;
79  }
80  else if (buffer.Event.KeyEvent.wVirtualKeyCode == VK_DOWN)
81  {
82  *c = KEYCODE_DOWN;
83  return;
84  }
85  else if (buffer.Event.KeyEvent.wVirtualKeyCode == 0x42)
86  {
87  *c = KEYCODE_B;
88  return;
89  }
90  else if (buffer.Event.KeyEvent.wVirtualKeyCode == 0x43)
91  {
92  *c = KEYCODE_C;
93  return;
94  }
95  else if (buffer.Event.KeyEvent.wVirtualKeyCode == 0x44)
96  {
97  *c = KEYCODE_D;
98  return;
99  }
100  else if (buffer.Event.KeyEvent.wVirtualKeyCode == 0x45)
101  {
102  *c = KEYCODE_E;
103  return;
104  }
105  else if (buffer.Event.KeyEvent.wVirtualKeyCode == 0x46)
106  {
107  *c = KEYCODE_F;
108  return;
109  }
110  else if (buffer.Event.KeyEvent.wVirtualKeyCode == 0x47)
111  {
112  *c = KEYCODE_G;
113  return;
114  }
115  else if (buffer.Event.KeyEvent.wVirtualKeyCode == 0x51)
116  {
117  *c = KEYCODE_Q;
118  return;
119  }
120  else if (buffer.Event.KeyEvent.wVirtualKeyCode == 0x52)
121  {
122  *c = KEYCODE_R;
123  return;
124  }
125  else if (buffer.Event.KeyEvent.wVirtualKeyCode == 0x54)
126  {
127  *c = KEYCODE_T;
128  return;
129  }
130  else if (buffer.Event.KeyEvent.wVirtualKeyCode == 0x56)
131  {
132  *c = KEYCODE_V;
133  return;
134  }
135  }
136  }
137 #endif
138  }
139  void shutdown()
140  {
141 #ifndef _WIN32
142  tcsetattr(kfd, TCSANOW, &cooked);
143 #endif
144  }
145 private:
146 #ifndef _WIN32
147  int kfd;
148  struct termios cooked;
149 #endif
150 };
151 
153 
155 {
156 public:
157  TeleopTurtle();
158  void keyLoop();
159 
160 private:
161 
162 
164  double linear_, angular_, l_scale_, a_scale_;
166 
167 };
168 
170  linear_(0),
171  angular_(0),
172  l_scale_(2.0),
173  a_scale_(2.0)
174 {
175  nh_.param("scale_angular", a_scale_, a_scale_);
176  nh_.param("scale_linear", l_scale_, l_scale_);
177 
178  twist_pub_ = nh_.advertise<geometry_msgs::Twist>("turtle1/cmd_vel", 1);
179 }
180 
181 void quit(int sig)
182 {
183  (void)sig;
184  input.shutdown();
185  ros::shutdown();
186  exit(0);
187 }
188 
189 
190 int main(int argc, char** argv)
191 {
192  ros::init(argc, argv, "teleop_turtle");
193  TeleopTurtle teleop_turtle;
194 
195  signal(SIGINT,quit);
196 
197  teleop_turtle.keyLoop();
198  quit(0);
199 
200  return(0);
201 }
202 
203 
205 {
206  char c;
207  bool dirty=false;
208 
209  puts("Reading from keyboard");
210  puts("---------------------------");
211  puts("Use arrow keys to move the turtle. 'q' to quit.");
212 
213 
214  for(;;)
215  {
216  // get the next event from the keyboard
217  try
218  {
219  input.readOne(&c);
220  }
221  catch (const std::runtime_error &)
222  {
223  perror("read():");
224  return;
225  }
226 
227  linear_=angular_=0;
228  ROS_DEBUG("value: 0x%02X\n", c);
229 
230  switch(c)
231  {
232  case KEYCODE_LEFT:
233  ROS_DEBUG("LEFT");
234  angular_ = 1.0;
235  dirty = true;
236  break;
237  case KEYCODE_RIGHT:
238  ROS_DEBUG("RIGHT");
239  angular_ = -1.0;
240  dirty = true;
241  break;
242  case KEYCODE_UP:
243  ROS_DEBUG("UP");
244  linear_ = 1.0;
245  dirty = true;
246  break;
247  case KEYCODE_DOWN:
248  ROS_DEBUG("DOWN");
249  linear_ = -1.0;
250  dirty = true;
251  break;
252  case KEYCODE_Q:
253  ROS_DEBUG("quit");
254  return;
255  }
256 
257 
258  geometry_msgs::Twist twist;
259  twist.angular.z = a_scale_*angular_;
260  twist.linear.x = l_scale_*linear_;
261  if(dirty ==true)
262  {
263  twist_pub_.publish(twist);
264  dirty=false;
265  }
266  }
267 
268 
269  return;
270 }
271 
272 
273 
#define KEYCODE_DOWN
#define KEYCODE_RIGHT
#define KEYCODE_E
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
#define KEYCODE_D
struct termios cooked
ros::Publisher twist_pub_
ros::NodeHandle nh_
#define KEYCODE_LEFT
int main(int argc, char **argv)
#define KEYCODE_F
bool param(const std::string &param_name, T &param_val, const T &default_val) const
void publish(const boost::shared_ptr< M > &message) const
KeyboardReader input
#define KEYCODE_UP
#define KEYCODE_G
#define KEYCODE_R
#define KEYCODE_C
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
#define KEYCODE_Q
#define KEYCODE_T
void readOne(char *c)
void quit(int sig)
#define KEYCODE_B
ROSCPP_DECL void shutdown()
#define KEYCODE_V
#define ROS_DEBUG(...)


turtlesim
Author(s): Josh Faust, Dirk Thomas
autogenerated on Mon Feb 28 2022 23:31:12