glass_server_node.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 import rospy
00004 from bluetooth import *
00005 import select
00006 import base64
00007 from std_msgs.msg import String as StringMsg
00008 from glass_server.srv import RobotConfiguration
00009 from glass_server.msg import TextMessage
00010 from glass_server.msg import ImageMessage
00011 from PIL import Image
00012 import cStringIO as StringIO
00013 from threading import Lock, Event
00014 import itertools
00015 import logging
00016 
00017 class GlassServer():
00018 
00019     def __init__(self):
00020         #Global Variables
00021         self._server_sock = BluetoothSocket( RFCOMM )
00022         self._server_sock.bind(("",PORT_ANY))
00023         self._server_sock.listen(1)
00024 
00025         self._client_sock = None
00026         self._client_info = None
00027 
00028         self._uuid = "00001101-0000-1000-8000-00805F9B34FB"
00029 
00030         self._send_queue = ""
00031         self._config_success = False
00032 
00033         self._robotDict = {}
00034 
00035         self._lock = Lock()
00036         self._talkback_event = Event()
00037 
00038         #Subscribers
00039         self._text_sub = rospy.Subscriber("/glass_server/text_messages", TextMessage, self.textMessageCallback)
00040         self._image_sub = rospy.Subscriber("/glass_server/image_messages", ImageMessage, self.ImageMessageCallback)
00041 
00042         #Publishers
00043         self._voice_pub = rospy.Publisher("/recognizer/output", StringMsg)
00044 
00045         self.run()
00046 
00047     def run(self):
00048         port = self._server_sock.getsockname()[1]
00049 
00050         advertise_service( self._server_sock, "GlassServer",
00051            service_id = self._uuid,
00052            service_classes = [ self._uuid, SERIAL_PORT_CLASS ],
00053            profiles = [ SERIAL_PORT_PROFILE ], 
00054 #          protocols = [ OBEX_UUID ] 
00055                     )
00056 
00057         rospy.loginfo("Waiting for connection on RFCOMM channel %d" % port)
00058 
00059         self._client_sock, self._client_info = self._server_sock.accept()
00060         self._client_sock.setblocking(1)
00061 
00062         rospy.loginfo("Accepted connection from "  + str(self._client_info))
00063 
00064         try:
00065             #Make configuration service visible
00066             self._config_srv = rospy.Service("robot_configuration", RobotConfiguration, self.robotConfig)
00067 
00068             while not rospy.is_shutdown():
00069                 data = ""
00070 
00071                 #ready = select.select([self._client_sock], [], [], 0)
00072                 #if ready[0]:
00073                 data = self._client_sock.recv(1024)
00074 
00075                 if len(data) > 0:
00076                     rospy.loginfo("received: \"%s\"" % data)
00077 
00078                     if data == "end connection\n": 
00079                         break
00080                     elif data == "Confirm connection\n":
00081                         self._lock.acquire()
00082                         self._client_sock.send("Connection confirmed\n")
00083                         self._lock.release()
00084                     elif data == "configuration complete\n":
00085                     #   self._client_sock.send("Copy: %s\n" % data)
00086                         self._config_success = True
00087                     elif data == "Delivery failed":
00088                         pass
00089                     elif data == "_NEXT_\n":
00090                         self._talkback_event.set()
00091                     elif not data == "":
00092                     #   rospy.loginfo("Sending copy")
00093                     #   self._client_sock.send("Copy: %s" % data)
00094                         msg = StringMsg()
00095                         msg.data = data
00096                         self._voice_pub.publish(msg)
00097                         self.sendCommandToRobot(data)
00098                     
00099             #End the configuration service and close the connection
00100             self._config_srv = None
00101             rospy.loginfo("Disconnecting")
00102             self._client_sock.close()
00103             self._server_sock.close()
00104             rospy.loginfo("all done")
00105 
00106         except IOError, e:
00107             rospy.loginfo("Error")
00108             print e
00109 
00110 
00111     def writeToGlass(self, string_data):
00112         rospy.loginfo("Sending: " + string_data)
00113         success = False
00114         try:
00115             self._lock.acquire()
00116             #headerSize = 30 #bytes
00117             packetSize = 10000 #bytes
00118             numPackets = len(string_data) / packetSize + (1 if (len(string_data) % packetSize > 0) else 0)
00119 
00120             rospy.loginfo("Setting up header")
00121             first_msg = "<msg>" + str(numPackets) + "_DELIM_" + str(packetSize) + "</msg>"
00122             #slack = headerSize - len(first_msg)
00123             #first_msg += " " * slack
00124             rospy.loginfo("Sending header")
00125             self._client_sock.send(first_msg)
00126 
00127             rospy.loginfo("Creating groups")
00128             groups = self.grouper(string_data, packetSize)
00129             rospy.loginfo(groups)
00130             rospy.loginfo("Creating and sending packets")
00131             for i in range(len(groups)):
00132                 msg = "<pkt><index>" + str(i+1) + "</index>" + groups[i] + "</pkt>"
00133                 pkt_slack = packetSize - len(msg)
00134                 msg += " " * pkt_slack
00135                 rospy.loginfo("Sending")
00136                 self._client_sock.send(msg)
00137                 rospy.loginfo("Sent " + str(i+1) + " packets! Size=" + str(len(msg)))
00138                 self._talkback_event.wait()
00139                 self._talkback_event.clear()
00140 
00141             rospy.loginfo("Message sent")
00142             success = True
00143         except Exception, ex:# OSError:
00144             logging.exception("Error on send!")
00145             rospy.loginfo("Error on send!")
00146         finally:
00147             rospy.loginfo("Releasing write lock")
00148             self._lock.release()
00149 
00150     def robotConfig(self, msg):
00151         rospy.loginfo("Recieved configuration for " + msg.name)
00152         stringToSend = "robot_configuration" + "_DELIM_" + msg.name \
00153                                             + "_DELIM_" + msg.info \
00154                                             + "_DELIM_" + msg.vocab
00155         self.writeToGlass(stringToSend)
00156         self._robotDict[msg.name] = rospy.Publisher("/" + msg.name.lower().replace(" ", "_") + "/voice_command", StringMsg)
00157         rospy.loginfo("Configuration written to Glass. Waiting for response")
00158 
00159         while(not self._config_success):
00160             pass
00161         self._config_success = False
00162 
00163         rospy.loginfo("Sending service response")
00164         return True
00165 
00166     def sendCommandToRobot(self, data):
00167         splitData = data.split(":")
00168         targetRobot = splitData[0]
00169         command = splitData[1][1:]
00170 
00171         if targetRobot == "All":
00172             for (robot_name, publisher) in self._robotDict.iteritems():
00173                 msg = StringMsg()
00174                 msg.data = command
00175                 publisher.publish(msg)
00176         else:
00177             publisher = self._robotDict[targetRobot]
00178             msg = StringMsg()
00179             msg.data = command
00180             publisher.publish(msg)
00181 
00182     def textMessageCallback(self, msg):
00183         rospy.loginfo("Recieved text message from " + msg.sender)
00184         stringToSend = "text_message" + "_DELIM_" + msg.sender \
00185                                             + "_DELIM_" + msg.text \
00186                                             + "_DELIM_" + str(msg.priority)
00187         self.writeToGlass(stringToSend)
00188 
00189     def ImageMessageCallback(self, msg):
00190         rospy.loginfo("Received image message from " + msg.sender)
00191 
00192         image_str = msg.base64_image
00193         image_raw = base64.b64decode(image_str)
00194         stream = StringIO.StringIO(image_raw)
00195         image = Image.open(stream)      
00196         width, height = image.size
00197         if width > height:
00198             newW = 100
00199             newH = newW * height / width
00200         else:
00201             newH = 100
00202             newW = newH * width / height
00203         newSize = newW, newH
00204         image = image.resize(newSize)
00205 
00206         image_stream = StringIO.StringIO()
00207         image.save(image_stream, format="JPEG")
00208         image_str = base64.b64encode(image_stream.read())
00209 
00210         stringToSend = "image_message" + "_DELIM_" + msg.sender \
00211                                             + "_DELIM_" + msg.text \
00212                                             + "_DELIM_" + msg.base64_image \
00213                                             + "_DELIM_" + str(msg.priority)
00214         self.writeToGlass(stringToSend)
00215 
00216     def grouper(self, seq, size):
00217         return [seq[pos:pos + size] for pos in range(0, len(seq), size)]
00218 
00219 
00220 if __name__ == '__main__':
00221     try:
00222         rospy.init_node('glass_server')
00223         rospy.loginfo("Node Initialized")
00224         instance = GlassServer()
00225     except rospy.ROSInterruptException:
00226         pass


google_glass_driver
Author(s): Nicholas Otero
autogenerated on Fri Aug 28 2015 10:51:44