keyboard_teleop.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2015, PickNik LLC
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of the PickNik LLC nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *********************************************************************/
34 
35 /* Author: Dave Coleman <dave@dav.ee>, Andy McEvoy
36  Desc: Tweak a TF transform using a keyboard
37 */
38 
39 #include <termios.h>
40 #include <signal.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 
44 #include <ros/ros.h>
45 #include <sensor_msgs/JointState.h>
46 #include <std_msgs/Float64MultiArray.h>
47 
48 #define KEYCODE_a 0x61
49 #define KEYCODE_b 0x62
50 #define KEYCODE_c 0x63
51 #define KEYCODE_d 0x64
52 #define KEYCODE_e 0x65
53 #define KEYCODE_f 0x66
54 #define KEYCODE_g 0x67
55 #define KEYCODE_h 0x68
56 #define KEYCODE_i 0x69
57 #define KEYCODE_j 0x6a
58 #define KEYCODE_k 0x6b
59 #define KEYCODE_l 0x6c
60 #define KEYCODE_m 0x6d
61 #define KEYCODE_n 0x6e
62 #define KEYCODE_o 0x6f
63 #define KEYCODE_p 0x70
64 #define KEYCODE_q 0x71
65 #define KEYCODE_r 0x72
66 #define KEYCODE_s 0x73
67 #define KEYCODE_t 0x74
68 #define KEYCODE_u 0x75
69 #define KEYCODE_v 0x76
70 #define KEYCODE_w 0x77
71 #define KEYCODE_x 0x78
72 #define KEYCODE_y 0x79
73 #define KEYCODE_z 0x7a
74 #define KEYCODE_ESCAPE 0x1B
75 
76 int kfd = 0;
77 struct termios cooked, raw;
78 
79 void quit(int sig)
80 {
81  tcsetattr(kfd, TCSANOW, &cooked);
82  exit(0);
83 }
84 
86 {
87 public:
89  {
90  std::cout << "init " << std::endl;
91  // TODO: make this robot agonistic
92  joints_sub_ = nh_.subscribe<sensor_msgs::JointState>("/iiwa_7_r800/joint_states", 1,
94  joints_pub_ = nh_.advertise<std_msgs::Float64MultiArray>("/iiwa_7_r800/joints_position_controller/command", 1);
95  cmd_.data.resize(7);
96  }
97 
99  {
100  }
101 
102  void stateCallback(const sensor_msgs::JointStateConstPtr& msg)
103  {
104  if (msg->position.size() != 7)
105  {
106  ROS_ERROR_STREAM("Not enough joints!");
107  exit(-1);
108  }
109 
110  // Copy latest joint positions to our output message
112  cmd_.data = msg->position;
113 
114  // Debug
115  // std::copy(cmd_.data.begin(), cmd_.data.end(), std::ostream_iterator<double>(std::cout, " "));
116  // std::cout << std::endl;
117 
118  // Important safety feature
119  has_recieved_joints_ = true;
120  }
121 
123  {
124  char c;
125  bool dirty = false;
126 
127  // get the console in raw mode
128  tcgetattr(kfd, &cooked);
129  memcpy(&raw, &cooked, sizeof(struct termios));
130  raw.c_lflag &= ~(ICANON | ECHO);
131  // Setting a new line, then end of file
132  raw.c_cc[VEOL] = 1;
133  raw.c_cc[VEOF] = 2;
134  tcsetattr(kfd, TCSANOW, &raw);
135 
136  puts("Reading from keyboard");
137  puts("---------------------------");
138  puts("Use 'QA' to for joint 1");
139  puts("Use 'WS' to for joint 2");
140  puts("Use 'ED' to for joint 3");
141  puts("Use 'RF' to for joint 4");
142  puts("Use 'TG' to for joint 5");
143  puts("Use 'YH' to for joint 6");
144  puts("Use 'UJ' to for joint 7");
145  puts("ESC to end");
146 
147  double delta_dist = 0.005;
148 
149  for (;;)
150  {
151  // get the next event from the keyboard
152  if (read(kfd, &c, 1) < 0)
153  {
154  perror("read():");
155  exit(-1);
156  }
157 
158  dirty = true;
159  switch (c)
160  {
161  case KEYCODE_q:
162  cmd_.data[0] = cmd_.data[0] + delta_dist; // radians
163  break;
164  case KEYCODE_a:
165  cmd_.data[0] = cmd_.data[0] - delta_dist; // radians
166  break;
167 
168  case KEYCODE_w:
169  cmd_.data[1] = cmd_.data[1] + delta_dist; // radians
170  break;
171  case KEYCODE_s:
172  cmd_.data[1] = cmd_.data[1] - delta_dist; // radians
173  break;
174 
175  case KEYCODE_e:
176  cmd_.data[2] = cmd_.data[2] + delta_dist; // radians
177  break;
178  case KEYCODE_d:
179  cmd_.data[2] = cmd_.data[2] - delta_dist; // radians
180  break;
181 
182  case KEYCODE_r:
183  cmd_.data[3] = cmd_.data[3] + delta_dist; // radians
184  break;
185  case KEYCODE_f:
186  cmd_.data[3] = cmd_.data[3] - delta_dist; // radians
187  break;
188 
189  case KEYCODE_t:
190  cmd_.data[4] = cmd_.data[4] + delta_dist; // radians
191  break;
192  case KEYCODE_g:
193  cmd_.data[4] = cmd_.data[4] - delta_dist; // radians
194  break;
195 
196  case KEYCODE_y:
197  cmd_.data[5] = cmd_.data[5] + delta_dist; // radians
198  break;
199  case KEYCODE_h:
200  cmd_.data[5] = cmd_.data[5] - delta_dist; // radians
201  break;
202 
203  case KEYCODE_u:
204  cmd_.data[6] = cmd_.data[6] + delta_dist; // radians
205  break;
206  case KEYCODE_j:
207  cmd_.data[6] = cmd_.data[6] - delta_dist; // radians
208  break;
209 
210  case KEYCODE_ESCAPE:
211  std::cout << std::endl;
212  std::cout << "Exiting " << std::endl;
213  quit(0);
214  break;
215 
216  default:
217  std::cout << "CODE: " << c << std::endl;
218  dirty = false;
219  }
220 
221  // Publish command
222  if (dirty)
223  {
224  // Important safety feature
226  {
227  ROS_ERROR_STREAM_NAMED("joint_teleop", "Unable to send joint commands because robot state is invalid");
228  }
229  else
230  {
231  std::cout << ".";
233  }
234  }
235  }
236  }
237 
238 private:
242  std_msgs::Float64MultiArray cmd_;
244 };
245 
246 int main(int argc, char** argv)
247 {
248  ros::init(argc, argv, "joints_teleop_keyboard");
249  signal(SIGINT, quit);
250 
251  // NOTE: We run the ROS loop in a separate thread as external calls such
252  // as service callbacks to load controllers can block the (main) control loop
254  spinner.start();
255 
256  TeleopJointsKeyboard teleop;
257  teleop.keyboardLoop();
258 
259  return (0);
260 }
#define KEYCODE_j
#define ROS_ERROR_STREAM_NAMED(name, args)
#define KEYCODE_u
#define KEYCODE_y
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
#define KEYCODE_t
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
std_msgs::Float64MultiArray cmd_
void spinner()
ros::Subscriber joints_sub_
void quit(int sig)
#define KEYCODE_q
void publish(const boost::shared_ptr< M > &message) const
#define KEYCODE_h
#define KEYCODE_s
#define KEYCODE_r
void stateCallback(const sensor_msgs::JointStateConstPtr &msg)
struct termios cooked raw
#define KEYCODE_g
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
#define KEYCODE_f
#define KEYCODE_d
#define KEYCODE_e
int kfd
#define KEYCODE_a
ros::Publisher joints_pub_
#define KEYCODE_w
#define KEYCODE_ESCAPE
#define ROS_ERROR_STREAM(args)
int main(int argc, char **argv)


ros_control_boilerplate
Author(s): Dave Coleman
autogenerated on Mon Feb 28 2022 23:27:26