Files
mxsc/script/RobotTCP.py
gac-S_Changer 6e981b86b7 Closedown
2017-03-01 15:31:44 +01:00

374 lines
13 KiB
Python

import threading
class RobotTCP(TcpDevice, Stoppable):
def __init__(self, name, server, timeout = 1000, retries = 1):
TcpDevice.__init__(self, name, server)
self.timeout = timeout
self.retries = retries
self.header = None
self.trailer = "\n"
self.array_separator = '|'
self.cmd_separator = ' '
self.msg_id = 0
self.working_mode = "invalid"
self.status = "invalid"
self.powered = None
self.settled = None
self.empty = None
self.working_mode = None
self.status = None
self.lock = threading.Lock()
self.joint_forces = None
def _sendReceive(self, msg_id, msg = "", timeout = None):
tx = self.header if (self.header != None) else ""
tx = tx + msg_id + " " + msg
if (len(tx)>127):
raise Exception("Exceeded maximum message size")
self.getLogger().finer("TX = '" + str(tx)+ "'")
if (self.trailer != None): tx = tx + self.trailer
rx = self.sendReceive(tx, msg_id, self.trailer , 0, self.timeout if timeout is None else timeout, self.retries)
rx=rx[:-1] #Remove 0A
self.getLogger().finer("RX = '" + str(rx) + "'")
if rx[:3] != msg_id:
if (time.time()-start) >= timeout:
raise Exception("Received invalid message id: " + str(rx[:3]) + " - expecting:" + msg_id )
if len(rx)<4:
raise Exception("Invalid message size: " + str(len(rx)) )
if rx[3] == "*":
raise Exception(rx[4:])
return rx[4:]
def call(self, msg, timeout = None):
self.lock.acquire()
try:
id = "%03d" % self.msg_id
self.msg_id = (self.msg_id+1)%1000
return self._sendReceive(id, msg, timeout)
finally:
self.lock.release()
def execute(self, command, *args, **kwargs):
timeout = None if (kwargs is None) or (not kwargs.has_key("timeout")) else kwargs["timeout"]
msg = str(command)
if len(args)>10:
raise Exception("Exceeded maximum number of parameters")
for i in range(len(args)):
msg += (self.cmd_separator if (i==0) else self.array_separator) + str(args[i])
rx = self.call(msg, timeout)
if rx.count(self.array_separator)>0:
return rx.split(self.array_separator)
return rx
def evaluate(self, cmd, timeout=None):
ret = self.execute('eval', cmd, timeout=timeout)
if type(ret) is str:
if ret.strip() != "": raise Exception(ret)
def get_var(self, name):
return self.execute('get_var', name)
#Makes app crash
#def get_str(self, name='s'):
# return self.execute('get_str', name)
def get_arr(self, name, size):
return self.execute('get_arr', name, size)
def get_bool(self, name = "b"):
return True if (self.execute('get_bool', name).strip() == '1') else False
def get_int(self, name ="n"):
return int(self.get_var(name))
def get_float(self, name ="n"):
return float(self.get_var(name))
def get_int_arr(self, size, name="arr"):
# not working. A Jython bug in PyUnicaode?
#return [int(x) for x in self.get_arr("arr", size)]
ret = []
a=self.get_arr(name, size)
for i in range(size):
ret.append(int(a[i]))
return ret
def get_float_arr(self, size, name="arr"):
#return [float(x) for x in self.get_arr("arr", size)]
a=self.get_arr(name, size)
ret = [];
for i in range(size): ret.append(float(a[i]));
return ret
def get_trf(self, name="t"):
a = self.execute('get_trf', name)
ret = []
for i in range(6): ret.append(float(a[i]))
return ret
def set_tr(self, l, name="t"):
self.evaluate(name + "={" + str(l[0]) + ","+ str(l[1]) + ","+ str(l[2]) + ","+ str(l[3]) + ","+ str(l[4]) + ","+ str(l[5]) + "}")
def get_jnt(self, name="j"):
a = self.execute('get_jnt', name)
ret = []
for i in range(6): ret.append(float(a[i]))
return ret
def set_jnt(self, l, name="j"):
self.evaluate(name + "={" + str(l[0]) + ","+ str(l[1]) + ","+ str(l[2]) + ","+ str(l[3]) + ","+ str(l[4]) + ","+ str(l[5]) + "}")
def get_pnt(self, name="p"):
a = self.execute('get_pnt', name)
ret = []
for i in range(6): ret.append(float(a[i]))
return ret
def eval_int(self, cmd):
self.evaluate("n=" + cmd)
return self.get_int()
def eval_float(self, cmd):
self.evaluate("n=" + cmd)
return self.get_float()
def eval_bool(self, cmd):
self.evaluate("b=" + cmd)
return self.get_bool()
#def eval_str(self, cmd):
# self.evaluate("s=" + cmd)
# return self.get_str()
def eval_jnt(self, cmd):
self.evaluate("j=" + cmd)
return self.get_jnt()
def eval_trf(self, cmd):
self.evaluate("t=" + cmd)
return self.get_trf()
def eval_pnt(self, cmd):
self.evaluate("p=" + cmd)
return self.get_pnt()
#Robot control
def is_powered(self):
self.powered = self.eval_bool("isPowered()")
return self.powered
def enable(self):
self.evaluate("enablePower()")
if not self.is_powered():
raise Exception("Cannot enable power")
#waits for power to be actually cut off
def disable(self):
self.evaluate("disablePower()", timeout=5000)
def get_monitor_speed(self):
self.speed = self.eval_int("getMonitorSpeed()")
def set_monitor_speed(self, speed):
ret = self.eval_int("setMonitorSpeed(" + str(speed) + ")")
if (ret==-1): raise Exception("The robot is not in remote working mode")
if (ret==-2): raise Exception("The monitor speed is under the control of the operator")
if (ret==-3): raise Exception("The specified speed is not supported")
def is_calibrated(self):
return self.eval_bool("isCalibrated()")
def _update_working_mode(self, mode, status):
if mode==1:
self.working_mode = "manual"
self.status = "hold" if status==6 else "move"
elif mode==2:
self.working_mode = "test"
self.status = "hold" if status==3 else "move"
elif mode==3:
self.working_mode = "local"
self.status = "hold" if status==2 else "move"
elif mode==4:
self.working_mode = "remote"
self.status = "hold" if status==2 else "move"
else:
self.working_mode = "invalid"
self.status = "invalid"
def read_working_mode(self):
try:
mode = self.eval_int("workingMode(arr)")
status = int(self.get_var("arr[0]"))
self._update_working_mode(mode, status)
self._update_state()
except:
self.working_mode = "invalid"
self.status = "invalid"
return self.working_mode
def get_emergency_stop_sts(self):
st = self.eval_int("esStatus()")
if (st== 1): return "active"
if (st== 2): return "activated"
return "off"
def get_safety_fault_signal(self):
fault = self.eval_bool("safetyFault(s)")
#if (fault):
# return get_str()
return fault
#Motion control
def stop(self):
self.evaluate("stopMove()")
def resume(self):
self.evaluate("restartMove()")
def resetMotion(self):
self.evaluate("resetMotion()")
def is_empty(self):
self.empty = self.eval_bool("isEmpty()")
self._update_state()
return self.empty
def is_settled(self):
self.settled = self.eval_bool("isSettled()")
self._update_state()
return self.powered
def get_move_id(self):
return self.eval_int("getMoveId()")
def set_move_id(self, id):
return self.evaluate("setMoveId(" + str(id) + " )")
def get_joint_forces(self):
try:
self.evaluate("getJointForce(arr)")
self.joint_forces = self.get_float_arr(6)
return self.joint_forces
except:
self.joint_forces = None
raise
def movej(self, joint_or_point, tool, desc):
return self.eval_int("movej(" + joint_or_point + ", " + tool + ", " + desc +")")
def movel(self, point, tool, desc):
return self.eval_int("movel(" + point + ", " + tool + ", " + desc +")")
def movec(self, point_interm, point_target, tool, desc):
return self.eval_int("movec(" + point_interm + ", " + point_target + ", " + tool + ", " + desc +")")
#Tool
#This function can timeout since it synchronizes move.
#Better check state before otherwise it can freeze the communication
def open_tool(self, tool):
return self.evaluate("open(" + tool + " )", timeout=3000)
#This function can timeout since it synchronizes move. Better check state before
#Better check state before otherwise it can freeze the communication
def close_tool(self, tool):
return self.evaluate("close(" + tool + " )", timeout=3000)
#Arm position
def herej(self):
return self.eval_jnt("herej()")
def distance_t(self, trsf1, trsf2):
return self.eval_float("distance(" + trsf1 + ", " + trsf2 + ")")
def distance_p(self, pnt1, pnt2):
return self.eval_float("distance(" + pnt1 + ", " + pnt2 + ")")
def compose(self, pnt, frame, trsf):
return self.eval_pnt("compose(" + pnt + ", " + frame + ", " + trsf + ")")
def here(self, tool, frame):
return self.eval_pnt("here(" + tool + ", " + frame + ")")
def joint_to_point(self, tool, frame, joint):
return self.eval_pnt("jointToPoint(" + tool + ", " + frame + ", " + joint +")")
def point_to_joint(self, tool, initial_joint, point):
if self.eval_bool("pointToJoint(" + tool + ", " + initial_joint + ", " + point +", j)"):
return self.get_jnt()
def position(self, point, frame):
return self.eval_trf("position(" + point + ", " + frame + ")")
#Task control
def task_create(self, program, *args, **kwargs):
program = str(program)
priority = 10 if (kwargs is None) or (not kwargs.has_key("priority")) else kwargs["priority"]
name = str(program if (kwargs is None) or (not kwargs.has_key("name")) else kwargs["name"])
if self.get_task_status(name)[0] != -1:
raise Exception("Task already exists: " + name)
#taskCreate "t1", 10, read(sMessage)
cmd = 'taskCreate "' + name + '", ' + str(priority) + ', ' + program + '('
for i in range(len(args)):
cmd += str(args[i]) + (',' if (i<(len(args)-1)) else '')
cmd+=')'
self.evaluate(cmd)
def task_suspend(self, name):
self.evaluate('taskSuspend("' + str(name)+ '")')
#waits until the task is ready for restart
def task_resume(self, name):
self.evaluate('taskResume("' + str(name)+ '",0)', timeout = 2000)
#waits for the task to be actually killed
def task_kill(self, name):
self.evaluate('taskKill("' + str(name)+ '")', timeout = 2000)
def get_task_status(self, name):
code = self.eval_int('taskStatus("' + str(name)+ '")')
#TODO: String assignments in $exec causes application to freeze
#status = self.eval_str('help(' + str(code)+ ')')
if code== -1: status = "Stopped"
elif code== 0: status = "Paused"
elif code== 1: status = "Running"
else: status = self.execute('get_help', code)
return (code,status)
def _update_state(self):
#self.setState(State.Busy if self.status=="move" else State.Ready)
if self.state==State.Offline:
print "Communication resumed"
if not self.settled: self.setState(State.Busy)
if not self.empty: self.setState(State.Paused)
else: self.setState(State.Ready)
def doUpdate(self):
try:
start = time.time()
#sts = self._sendReceive("EVT").strip().split(self.array_separator)
sts = self.execute("get_status")
self._update_working_mode(int(sts[0]), int(sts[1]))
self.powered = sts[2] == "1"
self.speed = int(sts[3])
self.empty = sts[4] == "1"
self.settled = sts[5] == "1"
ev = sts[6] if len(sts)>6 else ""
if len(ev.strip()) >0:
self.getLogger().info(ev)
self.on_event(ev)
self._update_state()
#print time.time() - start
except:
if self.state != State.Offline:
print >> sys.stderr, "Update error: " + str(sys.exc_info()[1])
self.setState(State.Offline)
def on_event(self,ev):
pass