vehicle_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 rospy
19 import numpy as np
20 from std_msgs.msg import Bool
21 from geometry_msgs.msg import Twist, Accel, Vector3
22 from sensor_msgs.msg import Joy
23 
24 
26  def __init__(self):
27  # Load the mapping for each input
28  self._axes = dict(x=4, y=3, z=1,
29  roll=2, pitch=5, yaw=0,
30  xfast=-1, yfast=-1, zfast=-1,
31  rollfast=-1, pitchfast=-1, yawfast=-1)
32  # Load the gain for each joystick axis input
33  # (default values for the XBox 360 controller)
34  self._axes_gain = dict(x=3, y=3, z=0.5,
35  roll=0.5, pitch=0.5, yaw=0.5,
36  xfast=6, yfast=6, zfast=1,
37  rollfast=2, pitchfast=2, yawfast=2)
38 
39  if rospy.has_param('~mapping'):
40  mapping = rospy.get_param('~mapping')
41  for tag in self._axes:
42  if tag not in mapping:
43  rospy.loginfo('Tag not found in axes mapping, '
44  'tag=%s' % tag)
45  else:
46  if 'axis' in mapping[tag]:
47  self._axes[tag] = mapping[tag]['axis']
48  if 'gain' in mapping[tag]:
49  self._axes_gain[tag] = mapping[tag]['gain']
50 
51  # Dead zone: Force values close to 0 to 0
52  # (Recommended for imprecise controllers)
53  self._deadzone = 0.5
54  if rospy.has_param('~deadzone'):
55  self._deadzone = float(rospy.get_param('~deadzone'))
56 
57  # Default for the RB button of the XBox 360 controller
58  self._deadman_button = -1
59  if rospy.has_param('~deadman_button'):
60  self._deadman_button = int(rospy.get_param('~deadman_button'))
61 
62  # If these buttons are pressed, the arm will not move
63  if rospy.has_param('~exclusion_buttons'):
64  self._exclusion_buttons = rospy.get_param('~exclusion_buttons')
65  if type(self._exclusion_buttons) in [float, int]:
66  self._exclusion_buttons = [int(self._exclusion_buttons)]
67  elif type(self._exclusion_buttons) == list:
68  for n in self._exclusion_buttons:
69  if type(n) not in [float, int]:
70  raise rospy.ROSException(
71  'Exclusion buttons must be an integer index to '
72  'the joystick button')
73  else:
74  self._exclusion_buttons = list()
75 
76  # Default for the start button of the XBox 360 controller
77  self._home_button = 7
78  if rospy.has_param('~home_button'):
79  self._home_button = int(rospy.get_param('~home_button'))
80 
81  self._msg_type = 'twist'
82  if rospy.has_param('~type'):
83  self._msg_type = rospy.get_param('~type')
84  if self._msg_type not in ['twist', 'accel']:
85  raise rospy.ROSException('Teleoperation output must be either '
86  'twist or accel')
87 
88  if self._msg_type == 'twist':
89  self._output_pub = rospy.Publisher('output', Twist, queue_size=1)
90  else:
91  self._output_pub = rospy.Publisher('output', Accel, queue_size=1)
92 
93  self._home_pressed_pub = rospy.Publisher(
94  'home_pressed', Bool, queue_size=1)
95 
96  # Joystick topic subscriber
97  self._joy_sub = rospy.Subscriber('joy', Joy, self._joy_callback)
98 
99  rate = rospy.Rate(50)
100  while not rospy.is_shutdown():
101  rate.sleep()
102 
103  def _parse_joy(self, joy=None):
104  if self._msg_type == 'twist':
105  cmd = Twist()
106  else:
107  cmd = Accel()
108  if joy is not None:
109  # Linear velocities:
110  l = Vector3(0, 0, 0)
111 
112  if self._axes['x'] > -1 and abs(joy.axes[self._axes['x']]) > self._deadzone:
113  l.x += self._axes_gain['x'] * joy.axes[self._axes['x']]
114 
115  if self._axes['y'] > -1 and abs(joy.axes[self._axes['y']]) > self._deadzone:
116  l.y += self._axes_gain['y'] * joy.axes[self._axes['y']]
117 
118  if self._axes['z'] > -1 and abs(joy.axes[self._axes['z']]) > self._deadzone:
119  l.z += self._axes_gain['z'] * joy.axes[self._axes['z']]
120 
121  if self._axes['xfast'] > -1 and abs(joy.axes[self._axes['xfast']]) > self._deadzone:
122  l.x += self._axes_gain['xfast'] * joy.axes[self._axes['xfast']]
123 
124  if self._axes['yfast'] > -1 and abs(joy.axes[self._axes['yfast']]) > self._deadzone:
125  l.y += self._axes_gain['yfast'] * joy.axes[self._axes['yfast']]
126 
127  if self._axes['zfast'] > -1 and abs(joy.axes[self._axes['zfast']]) > self._deadzone:
128  l.z += self._axes_gain['zfast'] * joy.axes[self._axes['zfast']]
129 
130  # Angular velocities:
131  a = Vector3(0, 0, 0)
132 
133  if self._axes['roll'] > -1 and abs(joy.axes[self._axes['roll']]) > self._deadzone:
134  a.x += self._axes_gain['roll'] * joy.axes[self._axes['roll']]
135 
136  if self._axes['rollfast'] > -1 and abs(joy.axes[self._axes['rollfast']]) > self._deadzone:
137  a.x += self._axes_gain['rollfast'] * joy.axes[self._axes['rollfast']]
138 
139  if self._axes['pitch'] > -1 and abs(joy.axes[self._axes['pitch']]) > self._deadzone:
140  a.y += self._axes_gain['pitch'] * joy.axes[self._axes['pitch']]
141 
142  if self._axes['pitchfast'] > -1 and abs(joy.axes[self._axes['pitchfast']]) > self._deadzone:
143  a.y += self._axes_gain['pitchfast'] * joy.axes[self._axes['pitchfast']]
144 
145  if self._axes['yaw'] > -1 and abs(joy.axes[self._axes['yaw']]) > self._deadzone:
146  a.z += self._axes_gain['yaw'] * joy.axes[self._axes['yaw']]
147 
148  if self._axes['yawfast'] > -1 and abs(joy.axes[self._axes['yawfast']]) > self._deadzone:
149  a.z += self._axes_gain['yawfast'] * joy.axes[self._axes['yawfast']]
150 
151  cmd.linear = l
152  cmd.angular = a
153  else:
154  cmd.linear = Vector3(0, 0, 0)
155  cmd.angular = Vector3(0, 0, 0)
156  return cmd
157 
158  def _joy_callback(self, joy):
159  # If any exclusion buttons are pressed, do nothing
160  try:
161  for n in self._exclusion_buttons:
162  if joy.buttons[n] == 1:
163  cmd = self._parse_joy()
164  self._output_pub.publish(cmd)
165  return
166 
167  if self._deadman_button != -1:
168  if joy.buttons[self._deadman_button] == 1:
169  cmd = self._parse_joy(joy)
170  else:
171  cmd = self._parse_joy()
172  else:
173  cmd = self._parse_joy(joy)
174  self._output_pub.publish(cmd)
175  self._home_pressed_pub.publish(
176  Bool(bool(joy.buttons[self._home_button])))
177  except Exception as e:
178  print('Error occurred while parsing joystick input,'
179  ' check if the joy_id corresponds to the joystick '
180  'being used. message={}'.format(e))
181 
182 if __name__ == '__main__':
183  # Start the node
184  node_name = os.path.splitext(os.path.basename(__file__))[0]
185  rospy.init_node(node_name)
186  rospy.loginfo('Starting [%s] node' % node_name)
187 
188  teleop = VehicleTeleop()
189 
190  rospy.spin()
191  rospy.loginfo('Shutting down [%s] node' % node_name)
def _parse_joy(self, joy=None)


uuv_teleop
Author(s): Musa Morena Marcusso Manhaes , Sebastian Scherer , Luiz Ricardo Douat
autogenerated on Mon Jul 1 2019 19:39:27