Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 import roslib ; roslib.load_manifest('pipette_driver')
00036 import rospy
00037 import pipette_driver
00038 from pipette_driver.srv import PipetteAction, PipetteActionRequest, PipetteActionResponse
00039 from diagnostic_msgs.msg import DiagnosticStatus, DiagnosticArray, KeyValue
00040
00041 import sys
00042 import getopt
00043 import threading
00044 from collections import defaultdict
00045
00046 _default_bd_addr = "00:80:98:e6:2b:30"
00047
00048 """
00049 usage: %(progname)s [-h] [-a <bd_address]
00050 Driver node for Viaflo Vision Pipette.
00051 Will proform actions based on service calls.
00052
00053 Options:
00054 -h : show this help
00055 -a : bluetooth address of pipette. Uses %(default_bd_addr)s as default
00056 """
00057
00058 def usage():
00059 global default_bd_address
00060 doc_args = {'progname':sys.argv[0], 'default_bd_addr':_default_bd_addr}
00061 print __doc__ % doc_args
00062
00063
00064 class PipetteNode(object):
00065 def __init__(self, bd_addr):
00066 print 'Opening pipette'
00067 port = 1
00068 pipette = pipette_driver.ViafloPipette()
00069 pipette.open(bd_addr, port)
00070 print 'Requesting info'
00071 cmd = pipette_driver.ViafloInfoCommand()
00072 self.pipette_info = pipette.send_msg(cmd)
00073 print 'Requesting version'
00074 cmd = pipette_driver.ViafloVersionCommand()
00075 self.pipette_version = pipette.send_msg(cmd)
00076 print 'Requesting position'
00077 cmd = pipette_driver.ViafloPositionQueryCommand()
00078 self.pipette_position = resp = pipette.send_msg(cmd).pipette_stop
00079 self.last_action = PipetteActionRequest.QUERY
00080
00081 self.diag_pub = rospy.Publisher('/diagnostics', DiagnosticArray)
00082 self.level = DiagnosticStatus.OK
00083 self.message = "OK"
00084 self.bd_addr = bd_addr
00085 self.pipette = pipette
00086 self.quit = False
00087
00088
00089 self.lock = threading.Lock()
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 self.diagnostic_thread = threading.Thread(None, self.publish_diagnostics)
00103 self.diagnostic_thread.start()
00104 srv = rospy.Service('pipette_action', PipetteAction, self.pipette_action_callback)
00105
00106 def stop(self):
00107 print "Stopping diagnostics"
00108 self.quit = True
00109 self.diagnostic_thread.join()
00110
00111 def publish_diagnostics(self):
00112 print "Diagnostics start"
00113 r = rospy.Rate(1)
00114 action_dict = defaultdict(lambda : "???", {1:'Query', 2:'Purge', 3:'Aspirate', 4:'Dispense'})
00115 while not self.quit and not rospy.is_shutdown():
00116 with self.lock:
00117 pipette_position = self.pipette_position
00118 level = self.level
00119 message = self.message
00120 last_action = self.last_action
00121 kv = []
00122 kv.append( KeyValue('Position (uL)', str(pipette_position)))
00123 kv.append( KeyValue('Last Action', "%s (%d)" % (action_dict[last_action], last_action)))
00124 name = "Viaflo Pipette (%s)" % self.bd_addr
00125 hardware_id = self.pipette_info.serial
00126 d = DiagnosticStatus(level, name, message, hardware_id, kv)
00127 h = roslib.msg.Header()
00128 h.stamp = rospy.Time.now()
00129 s = DiagnosticArray(h, [d])
00130 self.diag_pub.publish(s)
00131 r.sleep()
00132 print "Diagnostics stop"
00133
00134 def pipette_action_callback(self, req):
00135 print "Action callback"
00136 action = req.action
00137 if action==req.PURGE:
00138 cmd = pipette_driver.ViafloPurgeCommand(req.speed,req.bells)
00139 elif action==req.DISPENSE:
00140 cmd = pipette_driver.ViafloDispenseCommand(req.speed,req.amount,req.bells)
00141 elif action==req.ASPIRATE:
00142 cmd = pipette_driver.ViafloAspirateCommand(req.speed,req.amount,req.bells)
00143 else:
00144 raise RuntimeError("Invalid action (%d)" % action)
00145
00146 try:
00147 pipette_position = self.pipette.send_msg(cmd).pipette_stop
00148 except Exception,e:
00149 with self.lock:
00150 self.level = DiagnosticStatus.ERROR
00151 self.message = str(e)
00152 raise
00153
00154
00155 with self.lock:
00156 self.level = DiagnosticStatus.OK
00157 self.messge = "OK"
00158 self.pipette_position = pipette_position
00159 self.last_action = action
00160
00161 return PipetteActionResponse(pipette_position)
00162
00163
00164 def main():
00165 rospy.init_node('pipette_node')
00166 argv = rospy.myargv(argv=sys.argv)
00167
00168
00169 port = 1
00170 bd_addr = _default_bd_addr
00171
00172 progname = argv[0]
00173 optlist, args = getopt.getopt(argv[1:], "ha:", ["help","address="])
00174 for opt,val in optlist:
00175 if opt=='--help' or opt=='-h':
00176 usage()
00177 return
00178 elif opt=='--address' or opt=='-a':
00179 bd_addr = val
00180 else:
00181 print "Invalid option '%s'"%field
00182 sys.exit(1)
00183
00184 print "Usage bluetooth address : %s" % bd_addr
00185 p = PipetteNode(bd_addr)
00186 rospy.spin()
00187 p.stop()
00188
00189
00190 if __name__ == "__main__":
00191 main()
00192
00193