teleop.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 import sys
3 import termios
4 import tty
5 import commands
6 import subprocess as sp
7 import time
8 import rospy
9 import actionlib
10 
11 from geometry_msgs.msg import Vector3
12 from pioneer_mrs.msg import *
13 
14 class Teleop:
15  def __init__(self):
16  # prompt message to user
17  self._welcome_message = """
18 Welcome to the commander of this multi-robot system.
19  Press number 1-5 to switch the robot.
20  Press 9 to select all and 0 to select none.
21 For selected robots:
22  Press 'arrow keys' to move the robot.
23  Press 'space bar' to stop the robot.
24  Press 'm' to start a multi-robot algorithm action.
25  Press 's' to stop the action.
26 """
27  # none, robot1 - robot5, all
28  self._robot_list = ('0', '1', '2', '3', '4', '5', '9')
29 
30  # control status for give robots
31  self._robot_switch = [False, False, False, False, False]
32 
33  # up, down, right, left, stop
34  self._movement_list = {'\x1b[A':(1,0), '\x1b[B':(-1,0), '\x1b[C':(0,-1), '\x1b[D':(0,1), ' ':(0,0)}
35 
36  # multi-robot algorithm, stop action
37  self._mission_list = ('m', 's')
38 
39  # position info for five robots
40  self._robot_position = [0, [0,0], [0,0], [0,0], [0,0], [0,0]]
41 
42  # run main loop
43  self.teleoperation()
44 
45 
46  def get_key(self):
47  """ get one character from the terminal """
48  fd = sys.stdin.fileno() # file descriptor of stdin
49  old_settings = termios.tcgetattr(fd) # get attributes of terminal
50  try:
51  tty.setraw(fd) # set terminal mode to raw
52  key = sys.stdin.read(1) # read one character
53  finally:
54  termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) # set to old settings
55  return key
56 
57 
58  def redirect_screen_output(self, status):
59  if status:
60  # redirect screen output to an xterm terminal
61  old_tty = commands.getoutput("ls /dev/pts").split('\n')
62  self.xterm = sp.Popen(["xterm"])
63  time.sleep(1)
64  new_tty = commands.getoutput("ls /dev/pts").split('\n')
65  num = list(set(new_tty).difference(set(old_tty)))[0]
66  self.old_stdout = sys.stdout
67  self.fd = open("/dev/pts/"+str(num), 'w')
68  sys.stdout = self.fd
69  print "\n"
70  else:
71  # restore stdout
72  self.xterm.kill()
73  sys.stdout = self.old_stdout
74  self.fd.close()
75 
76 
77  def teleoperation(self):
78  """ get commmands from the keyboard and send to robots """
79  pub_vel_1 = rospy.Publisher('/robot1/cmd_vel_hp', Vector3, queue_size=1)
80  pub_vel_2 = rospy.Publisher('/robot2/cmd_vel_hp', Vector3, queue_size=1)
81  pub_vel_3 = rospy.Publisher('/robot3/cmd_vel_hp', Vector3, queue_size=1)
82  pub_vel_4 = rospy.Publisher('/robot4/cmd_vel_hp', Vector3, queue_size=1)
83  pub_vel_5 = rospy.Publisher('/robot5/cmd_vel_hp', Vector3, queue_size=1)
84  pub_vel = (pub_vel_1, pub_vel_2, pub_vel_3, pub_vel_4, pub_vel_5)
85 
86  client_1 = actionlib.SimpleActionClient('/robot1/Formation', pioneer_mrs.msg.FormationAction)
87  client_2 = actionlib.SimpleActionClient('/robot2/Formation', pioneer_mrs.msg.FormationAction)
88  client_3 = actionlib.SimpleActionClient('/robot3/Formation', pioneer_mrs.msg.FormationAction)
89  client_4 = actionlib.SimpleActionClient('/robot4/Formation', pioneer_mrs.msg.FormationAction)
90  client_5 = actionlib.SimpleActionClient('/robot5/Formation', pioneer_mrs.msg.FormationAction)
91  client = (client_1, client_2, client_3, client_4, client_5)
92 
93  goal = pioneer_mrs.msg.FormationGoal(order=100)
94 
95  self.plot_x = rospy.Publisher('plot/x', PointArray, queue_size=10)
96  self.plot_y = rospy.Publisher('plot/y', PointArray, queue_size=10)
97 
98  for i in range(5):
99  client[i].wait_for_server()
100 
101  print self._welcome_message
102 
103  #self.redirect_screen_output(True)
104 
105  # main loop
106  while not rospy.is_shutdown():
107  key = self.get_key()
108  if key == '\x1b': # arrow key has three char
109  key += self.get_key()
110  key += self.get_key()
111 
112  if key in self._robot_list:
113  if key == '0':
114  for i in range(5):
115  self._robot_switch[i] = False
116  elif key == '9':
117  for i in range(5):
118  self._robot_switch[i] = True
119  else:
120  self._robot_switch[int(key)-1] = not self._robot_switch[int(key)-1]
121  rospy.loginfo("robots:" + str(self._robot_switch))
122 
123  elif key in self._movement_list:
124  vel = Vector3() # default zero
125  vel.x = self._movement_list[key][0] * 0.4 # set vel to 0.4 m/s
126  vel.y = self._movement_list[key][1] * 0.4
127  for i in range(5):
128  if self._robot_switch[i]:
129  pub_vel[i].publish(vel)
130 
131  elif key in self._mission_list:
132  if key == 'm':
133  for i in range(5):
134  client[i].send_goal(goal, feedback_cb=self.action_feedback_cb, \
135  done_cb=self.action_done_cb)
136  rospy.loginfo("start a multi-robot algorithm action")
137  for i in range(5):
138  client[i].wait_for_result()
139  time.sleep(1)
140  print self._welcome_message
141  else:
142  for i in range(5):
143  client[i].cancel_all_goals()
144  rospy.loginfo("stop the action")
145  time.sleep(1)
146  print self._welcome_message
147 
148  elif key == '\x03':
149  break
150 
151  #self.redirect_screen_output(False)
152 
153 
154  def action_feedback_cb(self, feedback):
155  index = int(feedback.name[-1])
156  self._robot_position[index][0] = feedback.x
157  self._robot_position[index][1] = feedback.y
158  self._robot_position[0] += 1
159  if self._robot_position[0] == 5: # wait for msgs from all five robots
160  self._robot_position[0] = 0 # and log them in order
161  for i in range(1,6):
162  rospy.loginfo("robot" + str(i) + " (% .4f,% .4f) ", \
163  self._robot_position[i][0], self._robot_position[i][1])
164  rospy.loginfo("--------------------------------")
165  position_x = PointArray()
166  position_y = PointArray()
167  for i in range(1,6):
168  position_x.point.append(self._robot_position[i][0])
169  position_y.point.append(self._robot_position[i][1])
170  self.plot_x.publish(position_x)
171  self.plot_y.publish(position_y)
172 
173 
174  def action_done_cb(self, success, result):
175  if(success==3): # no idea why this flag has to be 3 when success
176  index = int(result.name[-1])
177  self._robot_position[index][0] = result.x
178  self._robot_position[index][1] = result.y
179  self._robot_position[0] += 1
180  if self._robot_position[0] == 5: # wait for msgs from all five robots
181  self._robot_position[0] = 0 # and log them in order
182  for i in range(1,6):
183  rospy.loginfo("robot" + str(i) + " (% .4f,% .4f) ", \
184  self._robot_position[i][0], self._robot_position[i][1])
185  rospy.loginfo("action succeeded")
186  else:
187  rospy.loginfo("action failed")
188 
189 
190 if __name__ == "__main__":
191  rospy.init_node('teleop')
192  try:
193  teleop = Teleop()
194  except rospy.ROSInterruptException:
195  pass
def teleoperation(self)
Definition: teleop.py:77
def action_done_cb(self, success, result)
Definition: teleop.py:174
def redirect_screen_output(self, status)
Definition: teleop.py:58
def action_feedback_cb(self, feedback)
Definition: teleop.py:154
def __init__(self)
Definition: teleop.py:15
_welcome_message
Definition: teleop.py:17
def get_key(self)
Definition: teleop.py:46


pioneer_mrs
Author(s): Hanzhe Teng
autogenerated on Thu Mar 5 2020 03:17:35