diff --git a/auntisara/ioc.py b/auntisara/ioc.py index 0d61b08..e55b395 100644 --- a/auntisara/ioc.py +++ b/auntisara/ioc.py @@ -338,7 +338,9 @@ def __init__(self, device_name, address, command_port=1000, status_port=10000, p self.status_received = None def load_positions(self): - # Load most recent file if one exists + """ + Load most recent file if one exists. Returns a dictionary of named robot positions. + """ data_files = glob.glob(os.path.join(self.app_directory, '{}*.dat'.format(self.positions_name))) if not data_files: return {} @@ -352,6 +354,10 @@ def load_positions(self): return positions def save_positions(self): + """ + Save current positions to a file. If previous file was older than today, create a new one with todays's date + as a suffix. + """ logger.debug('Saving positions ...') positions_file = '{}-{}.dat'.format(self.positions_name, datetime.today().strftime('%Y%m%d')) with open(os.path.join(self.app_directory, positions_file), 'w') as fobj: @@ -361,6 +367,10 @@ def ready_for_commands(self): return self.ready and self.ioc.enabled.get() and self.ioc.connected.get() def sender(self): + """ + Main method which sends commands to the robot from the outbox queue. New commands are placed in the queue + to be sent through this method. This method is called within the sender thread. + """ self.send_on = True epics.threads_init() while self.send_on: @@ -373,6 +383,11 @@ def sender(self): time.sleep(0) def receiver(self): + """ + Main method which receives messages from the robot from the inbox queue. Messages from the robot are placed in + the queue to be processed by this method. It is called within the receiver thread. + """ + self.recv_on = True epics.threads_init() while self.recv_on: @@ -387,6 +402,10 @@ def receiver(self): time.sleep(0) def status_monitor(self): + """ + Main monitor method which sends monior commands to the robot. + """ + epics.threads_init() self.recv_on = True cmd_index = 0 @@ -435,6 +454,40 @@ def shutdown(self): self.send_on = False self.ioc.shutdown() + def wait_for_position(self, *positions): + timeout = 30 + while timeout > 0 and self.ioc.position_fbk.get() not in positions: + timeout -= 0.01 + time.sleep(0.01) + if timeout > 0: + return True + else: + logger.warn('Timeout waiting for positions "{}"'.format(states)) + return False + + def wait_for_state(self, *states): + timeout = 30 + state_values = [s.value for s in states] + while timeout > 0 and self.ioc.status.get() not in state_values: + timeout -= 0.01 + time.sleep(0.01) + if timeout > 0: + return True + else: + logger.warn('Timeout waiting for states "{}"'.format(states)) + return False + + def wait_in_state(self, state): + timeout = 30 + while timeout > 0 and self.ioc.status.get() == state.value: + timeout -= 0.01 + time.sleep(0.01) + if timeout > 0: + return True + else: + logger.warn('Timeout in state "{}"'.format(state)) + return False + @staticmethod def make_args(tool=0, puck=0, sample=0, puck_type=PuckType.UNIPUCK.value, x_off=0, y_off=0, z_off=0, **kwargs): return (tool, puck, sample) + (0,) * 4 + (puck_type, 0, 0) + (x_off, y_off, z_off) @@ -496,14 +549,12 @@ def parse_outputs(self, bitstring): def calc_position(self): cur = numpy.array([ self.ioc.xpos_fbk.get(), self.ioc.ypos_fbk.get(), self.ioc.zpos_fbk.get(), - #self.ioc.rxpos_fbk.get(), self.ioc.rypos_fbk.get(), self.ioc.rzpos_fbk.get() ]) found = False name = "" for name, info in self.positions.items(): pos = numpy.array([ info['x'], info['y'], info['z'], - #info['rx'], info['ry'], info['rz'], ]) dist = numpy.linalg.norm(cur-pos) if dist <= info['tol']: @@ -521,7 +572,7 @@ def calc_position(self): def require_position(self, *allowed): if not self.positions.keys(): self.warn('No positions have been defined') - self.ioc.help.put('Please save position named ` {} `'.format(' | '.join(allowed))) + self.ioc.help.put('Please move the robot manually and save positions named `{}`'.format(' | '.join(allowed))) return False current = self.ioc.position_fbk.get() diff --git a/auntisara/msgs.py b/auntisara/msgs.py index 730459f..834684f 100644 --- a/auntisara/msgs.py +++ b/auntisara/msgs.py @@ -110,18 +110,18 @@ class StatusType(Enum): 17: { "error": "high level alarm", "description": "LN2 level in the Dewar is too high", - "help": "Close the main valve of the LN2 supply and contact IRELEC support" + "help": "Close the main valve of the LN2 supply" }, 18: { "error": "No LN2 available, regulation stopped", "description": "No LN2 available, autofill stopped", - "help": "Check LN2 main supply, check phase sensor, and contact IRELEC support", + "help": "Check LN2 main supply, check phase sensor", "state": StatusType.FAULT, }, 19: { "error": "FillingUp Timeout", "description": "Maximum time for filling up was exceeded", - "help": "Check LN2 main supply, check level sensor, and contact IRELEC support", + "help": "Check LN2 main supply, check level sensor", }, 20: { "error": "collision at the gonio",