예제 #1
0
    def __init__(self, path, state, config):
        self.path = path
        self.state = state
        self.config = config

        self.lines = sum(1 for line in open(path))

        self.planner = gplan.Planner()
        self.planner.set_resolver(self.get_var_cb)
        self.planner.set_logger(self._log_cb, 1, 'LinePlanner:3')
        self.planner.load(self.path, config)

        self.messages = []
        self.levels = dict(I='info',
                           D='debug',
                           W='warning',
                           E='error',
                           C='critical')

        # Initialized axis states and bounds
        self.bounds = dict(min={}, max={})
        for axis in 'xyz':
            self.bounds['min'][axis] = math.inf
            self.bounds['max'][axis] = -math.inf

        self.maxSpeed = 0
        self.currentSpeed = None
        self.lastProgress = None
        self.lastProgressTime = 0
        self.time = 0
예제 #2
0
 def reset(self, stop=True):
     if stop: self.ctrl.mach.stop()
     self.planner = gplan.Planner()
     self.planner.set_resolver(self._get_var_cb)
     self.planner.set_logger(self._log_cb, 1, 'LinePlanner:3')
     self.update_position()
     self.cmdq.clear()
     self.reset_times()
     self.ctrl.state.reset()
예제 #3
0
 def reset(self, stop=True):
     if stop: self.ctrl.mach.stop()
     self.planner = gplan.Planner()
     self.planner.set_resolver(self._get_var_cb)
     # TODO logger is global and will not work correctly in demo mode
     self.planner.set_logger(self._log_cb, 1, 'LinePlanner:3')
     self._position_dirty = True
     self.cmdq.clear()
     self.reset_times()
     self.ctrl.state.reset()
예제 #4
0
    def reset(self, *args, **kwargs):
        stop = kwargs.get('stop', True)
        if stop:
            self.ctrl.mach.stop()

        self.planner = gplan.Planner()
        self.planner.set_resolver(self._get_var_cb)
        # TODO logger is global and will not work correctly in demo mode
        self.planner.set_logger(self._log_cb, 1, 'LinePlanner:3')
        self._position_dirty = True
        self.cmdq.clear()
        self.reset_times()

        resetState = kwargs.get('resetState', True)
        if resetState:
            self.ctrl.state.reset()
예제 #5
0
 def reset(self):
     if (hasattr(self.ctrl, 'mach')): self.ctrl.mach.stop()
     self.planner = gplan.Planner()
     self.planner.set_resolver(self._get_var_cb)
     self.planner.set_logger(self._log_cb, 1, 'LinePlanner:3')
     self.cmdq.clear()
예제 #6
0
    def _exec_plan(self, filename, state, config):
        # Check if this plan was already run
        hid = plan_hash(filename, config)
        plan_path = 'plans/' + filename + '.' + hid + '.gz'
        meta_path = 'meta/' + filename + '.' + hid + '.gz'

        try:
            if os.path.exists(plan_path) and os.path.exists(meta_path):
                with open(plan_path, 'rb') as f:
                    data = f.read()
                with open(meta_path, 'rb') as f:
                    meta = f.read()
                meta = json.loads(gzip.decompress(meta).decode('utf8'))
                return (data, meta)

        except Exception as e:
            log.error(e)

        # Clean up old plans
        self._clean_plans(filename)

        def get_var_cb(name, units):
            value = 0

            if len(name) and name[0] == '_':
                value = state.get(name[1:], 0)
                if units == 'IMPERIAL': value /= 25.4

            return value

        start = time.time()
        moves = []
        line = 0
        totalLines = sum(1 for line in open('upload/' + filename))
        maxLine = 0
        maxLineTime = time.time()
        totalTime = 0
        position = {}
        rapid = False
        moves = []
        times = []
        bounds = dict(min={}, max={})
        messages = []
        count = 0
        cancelled = False

        for axis in 'xyzabc':
            position[axis] = 0
            bounds['min'][axis] = math.inf
            bounds['max'][axis] = -math.inf

        def add_to_bounds(axis, value):
            if value < bounds['min'][axis]: bounds['min'][axis] = value
            if bounds['max'][axis] < value: bounds['max'][axis] = value

        levels = dict(I='info',
                      D='debug',
                      W='warning',
                      E='error',
                      C='critical')

        def log_cb(level, msg, filename, line, column):
            if level in levels: level = levels[level]
            messages.append(
                dict(level=level,
                     msg=msg,
                     filename=filename,
                     line=line,
                     column=column))

        self.ctrl.mach.planner.log_intercept(log_cb)
        planner = gplan.Planner()
        planner.set_resolver(get_var_cb)
        planner.load('upload/' + filename, config)

        try:
            while planner.has_more():
                cmd = planner.next()
                planner.set_active(cmd['id'])  # Release plan

                # Cannot synchronize with actual machine so fake it
                if planner.is_synchronizing(): planner.synchronize(0)

                if cmd['type'] == 'line':
                    if 'first' in cmd: continue

                    totalTime += sum(cmd['times']) / 1000
                    times.append((cmd['id'], totalTime))
                    target = cmd['target']
                    move = {}

                    for axis in 'xyzabc':
                        if axis in target:
                            position[axis] = target[axis]
                            move[axis] = target[axis]
                            add_to_bounds(axis, move[axis])

                    if 'rapid' in cmd: move['rapid'] = cmd['rapid']

                    moves.append(move)

                elif cmd['type'] == 'set' and cmd['name'] == 'line':
                    line = cmd['value']
                    if maxLine < line:
                        maxLine = line
                        maxLineTime = time.time()

                elif cmd['type'] == 'dwell':
                    totalTime += cmd['seconds']
                    times.append((cmd['id'], totalTime))

                if not self._progress(filename, maxLine / totalLines):
                    cancelled = True
                    raise Exception('Plan canceled.')

                if self.max_plan_time < time.time() - start:
                    raise Exception('Max planning time (%d sec) exceeded.' %
                                    self.max_plan_time)

                if self.max_loop_time < time.time() - maxLineTime:
                    raise Exception('Max loop time (%d sec) exceeded.' %
                                    self.max_loop_time)

                count += 1
                if count % 50 == 0: time.sleep(0.001)  # Yield some time

        except Exception as e:
            log_cb('error', str(e), filename, line, 0)

        self._progress(filename, 1)

        # Remove infinity from bounds
        for axis in 'xyzabc':
            if bounds['min'][axis] == math.inf: del bounds['min'][axis]
            if bounds['max'][axis] == -math.inf: del bounds['max'][axis]

        # Encode data as string
        data = dict(time=totalTime,
                    lines=totalLines,
                    path=moves,
                    messages=messages)
        data = gzip.compress(dump_json(data).encode('utf8'))

        # Meta data
        meta = dict(times=times, bounds=bounds)
        meta_comp = gzip.compress(dump_json(meta).encode('utf8'))

        # Save plan & meta data
        if not cancelled:
            with open(plan_path, 'wb') as f:
                f.write(data)
            with open(meta_path, 'wb') as f:
                f.write(meta_comp)

        return (data, meta)
예제 #7
0
 def reset(self):
     self.planner = gplan.Planner()
     self.planner.set_resolver(self._get_var_cb)
     self.planner.set_logger(self._log_cb, 1, 'LinePlanner:3')
     self.cmdq.clear()