teleop_twist_keyboard.cpp
Go to the documentation of this file.
1 #include <ros/ros.h>
2 #include <geometry_msgs/Twist.h>
3 
4 #include <stdio.h>
5 #include <unistd.h>
6 #include <termios.h>
7 
8 #include <map>
9 
10 // Map for movement keys
11 std::map<char, std::vector<float>> moveBindings
12 {
13  {'i', {1, 0, 0, 0}},
14  {'o', {1, 0, 0, -1}},
15  {'j', {0, 0, 0, 1}},
16  {'l', {0, 0, 0, -1}},
17  {'u', {1, 0, 0, 1}},
18  {',', {-1, 0, 0, 0}},
19  {'.', {-1, 0, 0, 1}},
20  {'m', {-1, 0, 0, -1}},
21  {'O', {1, -1, 0, 0}},
22  {'I', {1, 0, 0, 0}},
23  {'J', {0, 1, 0, 0}},
24  {'L', {0, -1, 0, 0}},
25  {'U', {1, 1, 0, 0}},
26  {'<', {-1, 0, 0, 0}},
27  {'>', {-1, -1, 0, 0}},
28  {'M', {-1, 1, 0, 0}},
29  {'t', {0, 0, 1, 0}},
30  {'b', {0, 0, -1, 0}},
31  {'k', {0, 0, 0, 0}},
32  {'K', {0, 0, 0, 0}}
33 };
34 
35 // Map for speed keys
36 std::map<char, std::vector<float>> speedBindings
37 {
38  {'q', {1.1, 1.1}},
39  {'z', {0.9, 0.9}},
40  {'w', {1.1, 1}},
41  {'x', {0.9, 1}},
42  {'e', {1, 1.1}},
43  {'c', {1, 0.9}}
44 };
45 
46 // Reminder message
47 const char* msg = R"(
48 
49 Reading from the keyboard and Publishing to Twist!
50 ---------------------------
51 Moving around:
52  u i o
53  j k l
54  m , .
55 
56 For Holonomic mode (strafing), hold down the shift key:
57 ---------------------------
58  U I O
59  J K L
60  M < >
61 
62 t : up (+z)
63 b : down (-z)
64 
65 anything else : stop
66 
67 q/z : increase/decrease max speeds by 10%
68 w/x : increase/decrease only linear speed by 10%
69 e/c : increase/decrease only angular speed by 10%
70 
71 CTRL-C to quit
72 
73 )";
74 
75 // Init variables
76 float speed(0.5); // Linear velocity (m/s)
77 float turn(1.0); // Angular velocity (rad/s)
78 float x(0), y(0), z(0), th(0); // Forward/backward/neutral direction vars
79 char key(' ');
80 
81 // For non-blocking keyboard inputs
82 int getch(void)
83 {
84  int ch;
85  struct termios oldt;
86  struct termios newt;
87 
88  // Store old settings, and copy to new settings
89  tcgetattr(STDIN_FILENO, &oldt);
90  newt = oldt;
91 
92  // Make required changes and apply the settings
93  newt.c_lflag &= ~(ICANON | ECHO);
94  newt.c_iflag |= IGNBRK;
95  newt.c_iflag &= ~(INLCR | ICRNL | IXON | IXOFF);
96  newt.c_lflag &= ~(ICANON | ECHO | ECHOK | ECHOE | ECHONL | ISIG | IEXTEN);
97  newt.c_cc[VMIN] = 1;
98  newt.c_cc[VTIME] = 0;
99  tcsetattr(fileno(stdin), TCSANOW, &newt);
100 
101  // Get the current character
102  ch = getchar();
103 
104  // Reapply old settings
105  tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
106 
107  return ch;
108 }
109 
110 int main(int argc, char** argv)
111 {
112  // Init ROS node
113  ros::init(argc, argv, "teleop_twist_keyboard");
114  ros::NodeHandle nh;
115 
116  // Init cmd_vel publisher
117  ros::Publisher pub = nh.advertise<geometry_msgs::Twist>("cmd_vel", 1);
118 
119  // Create Twist message
120  geometry_msgs::Twist twist;
121 
122  printf("%s", msg);
123  printf("\rCurrent: speed %f\tturn %f | Awaiting command...\r", speed, turn);
124 
125  while(true){
126 
127  // Get the pressed key
128  key = getch();
129 
130  // If the key corresponds to a key in moveBindings
131  if (moveBindings.count(key) == 1)
132  {
133  // Grab the direction data
134  x = moveBindings[key][0];
135  y = moveBindings[key][1];
136  z = moveBindings[key][2];
137  th = moveBindings[key][3];
138 
139  printf("\rCurrent: speed %f\tturn %f | Last command: %c ", speed, turn, key);
140  }
141 
142  // Otherwise if it corresponds to a key in speedBindings
143  else if (speedBindings.count(key) == 1)
144  {
145  // Grab the speed data
146  speed = speed * speedBindings[key][0];
147  turn = turn * speedBindings[key][1];
148 
149  printf("\rCurrent: speed %f\tturn %f | Last command: %c ", speed, turn, key);
150  }
151 
152  // Otherwise, set the robot to stop
153  else
154  {
155  x = 0;
156  y = 0;
157  z = 0;
158  th = 0;
159 
160  // If ctrl-C (^C) was pressed, terminate the program
161  if (key == '\x03')
162  {
163  printf("\n\n . .\n . |\\-^-/| . \n /| } O.=.O { |\\\n\n CH3EERS\n\n");
164  break;
165  }
166 
167  printf("\rCurrent: speed %f\tturn %f | Invalid command! %c", speed, turn, key);
168  }
169 
170  // Update the Twist message
171  twist.linear.x = x * speed;
172  twist.linear.y = y * speed;
173  twist.linear.z = z * speed;
174 
175  twist.angular.x = 0;
176  twist.angular.y = 0;
177  twist.angular.z = th * turn;
178 
179  // Publish it and resolve any remaining callbacks
180  pub.publish(twist);
181  ros::spinOnce();
182  }
183 
184  return 0;
185 }
const char * msg
void publish(const boost::shared_ptr< M > &message) const
std::map< char, std::vector< float > > speedBindings
float speed(0.5)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
float turn(1.0)
std::map< char, std::vector< float > > moveBindings
float z(0)
int main(int argc, char **argv)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
float x(0)
float th(0)
char key(' ')
ROSCPP_DECL void spinOnce()
float y(0)
int getch(void)


teleop_twist_keyboard_cpp
Author(s): methylDragon
autogenerated on Mon Jun 10 2019 15:26:54