vehicle_keyboard_teleop.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # Copyright (c) 2016 The UUV Simulator Authors.
3 # All rights reserved.
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 from __future__ import print_function
17 import os
18 import time
19 import sys, select, termios, tty
20 import rospy
21 import numpy as np
22 from std_msgs.msg import Bool
23 from geometry_msgs.msg import Twist, Accel, Vector3
24 
26  def __init__(self):
27  # Class Variables
28  self.settings = termios.tcgetattr(sys.stdin)
29 
30  # Speed setting
31  self.speed = 1 # 1 = Slow, 2 = Fast
32  self.l = Vector3(0, 0, 0) # Linear Velocity for Publish
33  self.a = Vector3(0, 0, 0) # Angular Velocity for publishing
34  self.linear_increment = 0.05 # How much to increment linear velocities by, to avoid jerkyness
35  self.linear_limit = 1 # Linear velocity limit = self.linear_limit * self.speed
36  self.angular_increment = 0.05
37  self.angular_limit = 0.5
38  # User Interface
39  self.msg = """
40  Control Your Vehicle!
41  ---------------------------
42  Moving around:
43  W/S: X-Axis
44  A/D: Y-Axis
45  X/Z: Z-Axis
46 
47  Q/E: Yaw
48  I/K: Pitch
49  J/L: Roll
50 
51  Slow / Fast: 1 / 2
52 
53  CTRL-C to quit
54  """
55 
56  # Default message remains as twist
57  self._msg_type = 'twist'
58  if rospy.has_param('~type'):
59  self._msg_type = rospy.get_param('~type')
60  if self._msg_type not in ['twist', 'accel']:
61  raise rospy.ROSException('Teleoperation output must be either '
62  'twist or accel')
63  # Name Publisher topics accordingly
64  if self._msg_type == 'twist':
65  self._output_pub = rospy.Publisher('output', Twist, queue_size=1)
66  else:
67  self._output_pub = rospy.Publisher('output', Accel, queue_size=1)
68 
69  print(self.msg)
70 
71  # Ros Spin
72  rate = rospy.Rate(50) # 50hz
73  while not rospy.is_shutdown():
74  rate.sleep()
75  self._parse_keyboard()
76 
77  # Every spin this function will return the key being pressed
78  # Only works for one key per spin currently, thus limited control exploring alternative methods
79  def _get_key(self):
80  tty.setraw(sys.stdin.fileno())
81  rlist, _, _ = select.select([sys.stdin], [], [], 0.1)
82  if rlist:
83  key = sys.stdin.read(1)
84  else:
85  key = ''
86  termios.tcsetattr(sys.stdin, termios.TCSADRAIN, self.settings)
87 
88  return key
89 
90 
91  # Function to gradually build up the speed and avoid jerkyness #
92  def _speed_windup(self, speed, increment, limit, reverse):
93  if reverse == True:
94  speed -= increment * self.speed
95  if speed < -limit * self.speed:
96  speed = -limit * self.speed
97  else:
98  speed += increment * self.speed
99  if speed > limit * self.speed:
100  speed = limit * self.speed
101 
102  return speed
103 
104  def _parse_keyboard(self):
105  # Save key peing pressed
106  key_press = self._get_key()
107 
108  # Set Vehicle Speed #
109  if key_press == "1":
110  self.speed = 1
111  if key_press == "2":
112  self.speed = 2
113 
114  # Choose ros message accordingly
115  if self._msg_type == 'twist':
116  cmd = Twist()
117  else:
118  cmd = Accel()
119 
120  # If a key is pressed assign relevent linear / angular vel
121  if key_press!='':
122  # Linear velocities:
123  # Forward
124  if key_press == "w":
125  self.l.x = self._speed_windup(self.l.x, self.linear_increment, self.linear_limit, False)
126  # Backwards
127  if key_press == "s":
128  self.l.x = self._speed_windup(self.l.x, self.linear_increment, self.linear_limit, True)
129  # Left
130  if key_press == "a":
131  self.l.y = self._speed_windup(self.l.y, self.linear_increment, self.linear_limit, False)
132  # Right
133  if key_press == "d":
134  self.l.y = self._speed_windup(self.l.y, self.linear_increment, self.linear_limit, True)
135  # Up
136  if key_press == "x":
137  self.l.z = self._speed_windup(self.l.z, self.linear_increment, self.linear_limit*0.5, False)
138  # Down
139  if key_press == "z":
140  self.l.z = self._speed_windup(self.l.z, self.linear_increment, self.linear_limit*0.5, True)
141 
142  # Angular Velocities
143  # Roll Left
144  if key_press == "j":
145  self.a.x = self._speed_windup(self.a.x, self.linear_increment, self.linear_limit, True)
146  # Roll Right
147  if key_press == "l":
148  self.a.x = self._speed_windup(self.a.x, self.linear_increment, self.linear_limit, False)
149  # Pitch Down
150  if key_press == "i":
151  self.a.y = self._speed_windup(self.a.y, self.linear_increment, self.linear_limit, False)
152  # Pitch Up
153  if key_press == "k":
154  self.a.y = self._speed_windup(self.a.y, self.linear_increment, self.linear_limit, True)
155  # Yaw Left
156  if key_press == "q":
157  self.a.z = self._speed_windup(self.a.z, self.linear_increment, self.linear_limit, False)
158  # Yaw Right
159  if key_press == "e":
160  self.a.z = self._speed_windup(self.a.z, self.linear_increment, self.linear_limit, True)
161 
162  else:
163  # If no button is pressed reset velocities to 0
164  self.l = Vector3(0, 0, 0)
165  self.a = Vector3(0, 0, 0)
166 
167  # Store velocity message into Twist format
168  cmd.angular = self.a
169  cmd.linear = self.l
170 
171  # If ctrl+c kill node
172  if (key_press == '\x03'):
173  rospy.loginfo('Keyboard Interrupt Pressed')
174  rospy.loginfo('Shutting down [%s] node' % node_name)
175 
176  # Set twists to 0
177  cmd.angular = Vector3(0, 0, 0)
178  cmd.linear = Vector3(0, 0, 0)
179  self._output_pub.publish(cmd)
180 
181  exit(-1)
182 
183  # Publish message
184  self._output_pub.publish(cmd)
185 
186 if __name__ == '__main__':
187 
188  # Wait for 5 seconds, so the instructions are the last thing to print in terminal
189  time.sleep(5)
190  # Start the node
191  node_name = os.path.splitext(os.path.basename(__file__))[0]
192  rospy.init_node(node_name)
193  rospy.loginfo('Starting [%s] node' % node_name)
194 
196 
197  termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
198  rospy.loginfo('Shutting down [%s] node' % node_name)
def _speed_windup(self, speed, increment, limit, reverse)


uuv_teleop
Author(s): Musa Morena Marcusso Manhaes , Sebastian Scherer , Luiz Ricardo Douat
autogenerated on Thu Jun 18 2020 03:28:41