00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 import rospy
00016 from ros_glass_tools.srv import *
00017 from std_msgs.msg import Empty
00018
00019 class VoiceCommandControl:
00020 '''Node to translate a voice/text command into a ROS message command
00021 This node takes in a list of robots prefixes, a list of global commands and topics, and a list of robot
00022 commands and topics.
00023
00024 When a global command is received in a request it publishes a blank message on that topic.
00025
00026 When a robot command is received which means robot #, or all. It will publish a command on that topic
00027 with the robot prefex added to the namespace.
00028 and example launch file to set this up is shown below.
00029
00030 <node name="voice_commands" type="voice_command.py" pkg="ros_glass_tools">
00031 <rosparam param="global_commands">
00032 [ [stop, stop],[go, go] ]
00033
00034 </rosparam>
00035 <rosparam param="robots">
00036 [a, b]
00037 </rosparam>
00038 <rosparam param="robot_commands">
00039 [
00040 [forward, forward],
00041 [backward, backward]
00042 ]
00043 </rosparam>
00044 </node>
00045 '''
00046
00047
00048
00049 def __init__(self):
00050
00051 rospy.init_node("voice_command_trans")
00052 self.serv = rospy.Service("glass_voice_command", Command, self.command)
00053
00054
00055 input_global_commands = rospy.get_param('~global_commands', None)
00056 input_robots = rospy.get_param('~robots', None)
00057 input_robot_commands= rospy.get_param('~robot_commands', None)
00058
00059
00060 self.global_commands = create_command_dict(input_global_commands)
00061 self.robot_commands = create_robot_commands(input_robot_commands, input_robots)
00062
00063
00064
00065
00066 def command(self, request):
00067 '''
00068 Handle a service request at the moment handles requests of the following syntax for one word commands
00069 execute `command` -> Publish to the global command topic if defined
00070 all `command` -> Publsih the command on all robots topics if defined
00071 robot # `command` -> Publsih the command on the # robot topics if robot exists and command defined
00072 Returns the warning message or success string
00073 '''
00074 robot_number = 'All'
00075 command_arr = request.command.split(' ')
00076 result = 'Fail'
00077
00078 if command_arr[0] == 'robot':
00079 try:
00080
00081 robot_number = int(command_arr[1])
00082 except:
00083
00084 number = command_arr[1]
00085
00086 if number == 'to' or number == 'too':
00087 number = 'two'
00088 if number == 'for':
00089 number = 'four'
00090 robot_number = text2int(number)
00091 cmd = command_arr[2]
00092
00093 result = send_robot_command(robot_number, cmd, self.robot_commands)
00094
00095
00096 elif command_arr[0] == 'all':
00097 cmd = command_arr[1]
00098 result = send_robot_command(robot_number, cmd, self.robot_commands)
00099
00100
00101 elif command_arr[0] == 'execute':
00102 cmd = command_arr[1]
00103 result = send_command(cmd, self.global_commands)
00104
00105
00106 else:
00107 result = "INVALID COMMAND MUST BEGIN WITH All, Robot #, or execute"
00108
00109 rospy.logerr(result)
00110 return CommandResponse(result)
00111
00112 def send_command(cmd, cmd_dict):
00113 '''publish an Empty message on the cmd if defined in the dictonary of command topics or
00114 just return that we don't have a defined command
00115 '''
00116 if cmd not in cmd_dict:
00117 return "Command %s Not Defined"%cmd
00118 else:
00119 msg = Empty()
00120 cmd_dict[cmd].publish(msg)
00121 return "Sent Command: " + cmd
00122
00123 def send_robot_command(robot_number, cmd, robot_list):
00124 '''publish the command on the specific robot
00125 If all is selected it will publish it on every robot on the list
00126 otherwise it is based on which robot number is defined
00127 '''
00128 cmd = cmd.lower()
00129 if robot_number == 'All':
00130 results = []
00131
00132 for rob in robot_list:
00133 res = send_command(cmd, rob)
00134 results.append(res)
00135 return '\n'.join(results)
00136
00137 else:
00138
00139 if robot_number > len(robot_list):
00140 return "Robot Number invalid"
00141 else:
00142 return send_command(cmd, robot_list[robot_number-1])
00143
00144
00145
00146
00147 def create_command_dict(command_arr, prefix = ''):
00148 '''create a dictonary that maps command word to a publisher that will get
00149 an empty message when the command is received
00150 '''
00151 command_dict = {}
00152 for pair in command_arr:
00153 topic_name = prefix + pair[1]
00154 publisher = rospy.Publisher(topic_name, Empty)
00155 command_dict[pair[0]] = publisher
00156 return command_dict
00157
00158 def create_robot_commands(commands, robots):
00159 '''with the list of commands and the list of robots make the robot array so
00160 we can publish to specific robots
00161 '''
00162 robot_list = []
00163 for prefix in robots:
00164
00165 robot_list.append(create_command_dict(commands, prefix + '/'))
00166 return robot_list
00167
00168
00169 def text2int(textnum):
00170 '''simple text number represnetation to integer value'''
00171 nums = [
00172 "zero", "one", "two", "three", "four", "five", "six", "seven", "eight",
00173 "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen",
00174 "sixteen", "seventeen", "eighteen", "nineteen"
00175 ]
00176 val = nums.index(textnum.lower())
00177 return val
00178
00179
00180
00181
00182 if __name__ == '__main__':
00183 vcc = VoiceCommandControl()
00184 rospy.spin()