示例#1
0
    def __init__(self, session):

        monkey.patch_socket() 
        import gevent_zeromq
        gevent_zeromq.monkey_patch()
         #we do use greenlets, but only patch sock stuff
        #other stuff messes up the

        config = session.arduino 
        boardglob = config['board']
        boards = glob(boardglob)
        if not len(boards):
              raise Exception("No Arduino found")
        
        self.board = Arduino(boards[0])
        #self.iterator = util.Iterator(self.board)
        #self.iterator.daemon = True
        #self.iterator.start()

        #initialize servo objects
        self.servos = {}
        if "servos" in config:
            for servo in config["servos"]:
                self.servos[servo['name']] = Servo(servo['pin'], self.board)

        #initialize light objects
        self.digitalouts = {}
        if "digitalouts" in config:
            for do in config["digitalouts"]:
                self.digitalouts[do['name']] = DigitalOut(do['pin'], self.board)

        if "digitalouts" in config or "servos" in config:
            self.subsock = ChannelManager().subscribe("ControlOutput/")

        self.buttons = []
        if "buttons" in config:
            for button in config["buttons"]:
                self.buttons.append(Button(button['pin'], button['message'], self.board))

        self.potentiometers = []
        if "potentiometers" in config:
            for pot in config["potentiometers"]:
                self.buttons.append(Potentiometer(pot['pin'], pot['name'], self.board))                
示例#2
0
    def __init__(self, config):
        if Core._instance is not None:
            assert RuntimeError, 'Only one state machine allowed currently'
        Core._instance = self
        self._states = {}
        self._cur_state = None
        self._events = Queue()
        self._clock = util.Clock(1.0, sleep=gevent.sleep)
        self._config = config
        self._worker_enabled = None
        self._worker_checked = None
        self.config = config #bkcompat for old SeerCore stuff
        self.cameras = []
        self.video_cameras = []
        self.log = logging.getLogger(__name__)
        self._mem_prof_ticker = 0
        self._channel_manager = ChannelManager(shareConnection=False)
    
        for cinfo in config.cameras:
            cam = StillCamera(**cinfo)
            video = cinfo.get('video')
            if video is not None:
                cam = VideoCamera(cam, 1.0, **video)
                cam.start()
                self.video_cameras.append(cam)
            self.cameras.append(cam)

        util.load_plugins()
        self.reloadInspections()
        
        if not self.config.skip_worker_check and not self.config.framebuffer:
            self.workerCheck(5.0) #wait up to 5s for worker processes
        
        if self.config.framebuffer and not self.config.skip_worker_check:
            log.warn("Framebuffer is active, while worker is enabled.  Workers can not handle framebuffer calls, so you should add skip_worker_check: 1 to the config")
        
        self.lastframes = deque()
        self.framecount = 0
        self.reset()
示例#3
0
class Core(object):
    '''Implements the core functionality of SimpleSeer
       - capture
       - inspect
       - measure
       - watch
    '''
    _instance=None

    class Transition(Exception):
        def __init__(self, state):
            self.state = state

    def __init__(self, config):
        if Core._instance is not None:
            assert RuntimeError, 'Only one state machine allowed currently'
        Core._instance = self
        self._states = {}
        self._cur_state = None
        self._events = Queue()
        self._clock = util.Clock(1.0, sleep=gevent.sleep)
        self._config = config
        self._worker_enabled = None
        self._worker_checked = None
        self.config = config #bkcompat for old SeerCore stuff
        self.cameras = []
        self.video_cameras = []
        self.log = logging.getLogger(__name__)
        self._mem_prof_ticker = 0
        self._channel_manager = ChannelManager(shareConnection=False)
    
        for cinfo in config.cameras:
            cam = StillCamera(**cinfo)
            video = cinfo.get('video')
            if video is not None:
                cam = VideoCamera(cam, 1.0, **video)
                cam.start()
                self.video_cameras.append(cam)
            self.cameras.append(cam)

        util.load_plugins()
        self.reloadInspections()
        
        if not self.config.skip_worker_check and not self.config.framebuffer:
            self.workerCheck(5.0) #wait up to 5s for worker processes
        
        if self.config.framebuffer and not self.config.skip_worker_check:
            log.warn("Framebuffer is active, while worker is enabled.  Workers can not handle framebuffer calls, so you should add skip_worker_check: 1 to the config")
        
        self.lastframes = deque()
        self.framecount = 0
        self.reset()
        
    @classmethod
    def get(cls):
        return cls._instance
        
    def workerCheck(self, timeout = 0.5, checkinterval = 0.1):
        result = ping_worker.delay(1)
        checktime = time.time()
        self.log.info("checking for worker process")
        
        self._worker_checked = checktime
        while not result.ready():
            time.sleep(checkinterval)
            if time.time() - checktime > timeout:
                self.log.info("worker check timeout")
                self._worker_enabled = False
                return False
        
        if result.get() == 2:
            self.log.info("worker found")
            self._worker_enabled = True
            return True
        else:
            self._worker_enabled = False
            return False
                
    def reloadInspections(self):
        i = list(M.Inspection.objects)
        m = list(M.Measurement.objects)
        w = list(M.Watcher.objects)
        self.inspections = i
        self.measurements = m
        self.watchers = w

    def subscribe(self, name):
        # Create thread that listens for event specified by name
        # If message received, trigger that event 
        
        def callback(msg):
            data = jsondecode(msg.body)
            self.trigger(name, data)
            
        def listener():
            self._channel_manager.subscribe(name, callback)
        
        gevent.spawn_link_exception(listener)
    
    def publish(self, name, data):
        self._channel_manager.publish(name, data)

    def get_image(self, width, index, camera):
        frame = self.lastframes[index][camera]
        image = frame.image

        if (width):
            image = image.scale(width / float(image.width))

        s = StringIO()
        image.save(s, "jpeg", quality=60)

        return dict(
                content_type='image/jpeg',
                data=s.getvalue())

    def get_config(self):
        return self._config.get_config()

    def reset(self):
        start = State(self, 'start')
        self._states = dict(start=start)
        self._cur_state = start

    def capture(self, indexes = []):
        currentframes = []
        self.framecount += 1

        cameras = self.cameras
        if len(indexes):
            cameras = [ self.cameras[i] for i in indexes ]
        
        currentframes = [ cam.getFrame() for cam in cameras ]

        while len(self.lastframes) >= (self._config.max_frames or 30):
            self.lastframes.popleft()

        self.lastframes.append(currentframes)
        new_frame_ids = []
        for frame in currentframes:
            new_frame_ids.append(frame.id)

        return currentframes
    
    """
    This is probably not used any more.  commenting out to make sure
        
    def inspect(self, frames = []):
        if not len(frames) and not len(self.lastframes):
            frames = self.capture()
        elif not len(frames):
            frames = self.lastframes[-1]
        
        for frame in frames:
            frame.features = []
            frame.results = []
            for inspection in self.inspections:
                if inspection.parent:  #root parents only
                    continue
                
                if inspection.camera and frame.camera != inspection.camera:
                    #this camera, or all cameras if no camera is specified
                    continue
                
                feats = inspection.execute(frame.image)
                frame.features.extend(feats)
                for m in inspection.measurements:
                    m.execute(frame, feats)
                    
            for watcher in self.watchers:
                watcher.check(frame.results)
    """
    
    
    def process(self, frame):
        if self._worker_enabled:
            async_results = self.process_async(frame)
            return self.process_async_complete(frame, async_results)
        
        frame.features = []
        frame.results = []
        
        # all times are in seconds, not ms
        ct_epoch = int(frame.capturetime.strftime("%s"))
        for inspection in M.Inspection.objects:
            if inspection.parent:
                continue
            if inspection.camera and inspection.camera != frame.camera:
                continue
            if 'interval' in inspection.parameters and not nextInInterval(frame, inspection.parameters['intervalField'], inspection.parameters['interval']):
                continue
            
            features = inspection.execute(frame)
            frame.features += features
            
            for m in inspection.measurements:
                if 'interval' in m.parameters and not nextInInterval(frame, m.parameters['intervalField'], m.parameters['interval']):
                    continue
            
                m.execute(frame, features)
            
    def process_async(self, frame):
        frame.features = []
        frame.results = []
        frame.save_image()
        #make sure the image is in gridfs (does nothing if already saved)
        
        results_async = []
        inspections = list(M.Inspection.objects)
        #allocate each inspection to a celery task

        # all times are in seconds, not ms
        for inspection in M.Inspection.objects:
            if inspection.parent:
                continue
            if inspection.camera and inspection.camera != frame.camera:
                continue
            if 'interval' in inspection.parameters and not nextInInterval(frame, inspection.parameters['intervalField'], inspection.parameters['interval']):
                continue
            results_async.append(execute_inspection.delay(inspection.id, frame.imgfile.grid_id, frame.metadata))
        
        return results_async
        
    def process_async_complete(self, frame, results_async):
        
        #note that async results refer to Celery results, and not Frame results
        results_complete = []
        ct_epoch = int(frame.capturetime.strftime("%s"))
        while not len(results_complete) == len(results_async):
            new_ready_results = []
            for index, r in enumerate(results_async):
                if not index in results_complete and r.ready():
                    new_ready_results.append(index)
                    
            for result_index in new_ready_results:
                (scvfeatures, inspection_id) = results_async[result_index].get()
                insp = M.Inspection.objects.get(id=inspection_id)
                features = []
                
                
                for scvfeature in scvfeatures:
                    scvfeature.image = frame.image 
                    ff = M.FrameFeature()
                    ff.setFeature(scvfeature)
                    ff.inspection = insp.id
                    features.append(ff)
                
                frame.features += features
                #import pdb;pdb.set_trace()
                for m in insp.measurements:
                    if 'interval' in m.parameters and not nextInInterval(frame, m.parameters['intervalField'], m.parameters['interval']):
                        continue
                    m.execute(frame, features)
                    
            results_complete += new_ready_results
            time.sleep(0.2)
                
    @property
    def results(self):
        ret = []
        for frameset in self.lastframes:
            results = []
            for f in frameset:
                results += [f.results for f in frameset]
            
            ret.append(results)
            
        return ret

    """
    def get_inspection(self, name):
        return M.Inspection.objects(name=name).next()

    def get_measurement(self, name):
        return M.Measurement.objects(name=name).next()
    """
    
    def state(self, name):
        if name in self._states: return self._states[name]
        s = self._states[name] = State(self, name)
        return s

    def trigger(self, name, data=None):
        self._events.put((name, data))

    def step(self):
        next = self._cur_state = self._cur_state.run()
        return next

    def wait(self, name):
        while True:
            try:
                (n,d) = self._events.get(timeout=0.5)
                if n == name: return (n,d)
            except Empty:
                continue
            self._cur_state.trigger(n,d)

    def on(self, state_name, event_name):
        state = self.state(state_name)
        self.subscribe(event_name)
        return state.on(event_name)

    def run(self, audit=False):
        audit_trail = []
        while True:
            print self._cur_state
            if self._cur_state is None: break
            if audit: audit_trail.append(self._cur_state.name)
            try:
                self._cur_state = self._cur_state.run()
            except self.Transition, t:
                if isinstance(t.state, State):
                    self._cur_state = t.state
                elif t.state is None:
                    self._cur_state = None
                else:
                    self._cur_state = self.state(t.state)
        audit_trail.append(None)
        return audit_trail
示例#4
0
class Controls(object):
    iterator = ''
    board = ''
    servos = None
    digitalouts = None
    buttons = None
    subsock = None

    def __init__(self, session):

        monkey.patch_socket() 
        import gevent_zeromq
        gevent_zeromq.monkey_patch()
         #we do use greenlets, but only patch sock stuff
        #other stuff messes up the

        config = session.arduino 
        boardglob = config['board']
        boards = glob(boardglob)
        if not len(boards):
              raise Exception("No Arduino found")
        
        self.board = Arduino(boards[0])
        #self.iterator = util.Iterator(self.board)
        #self.iterator.daemon = True
        #self.iterator.start()

        #initialize servo objects
        self.servos = {}
        if "servos" in config:
            for servo in config["servos"]:
                self.servos[servo['name']] = Servo(servo['pin'], self.board)

        #initialize light objects
        self.digitalouts = {}
        if "digitalouts" in config:
            for do in config["digitalouts"]:
                self.digitalouts[do['name']] = DigitalOut(do['pin'], self.board)

        if "digitalouts" in config or "servos" in config:
            self.subsock = ChannelManager().subscribe("ControlOutput/")

        self.buttons = []
        if "buttons" in config:
            for button in config["buttons"]:
                self.buttons.append(Button(button['pin'], button['message'], self.board))

        self.potentiometers = []
        if "potentiometers" in config:
            for pot in config["potentiometers"]:
                self.buttons.append(Potentiometer(pot['pin'], pot['name'], self.board))                

    def checkSubscription(self):
        if not self.subsock:
            return
            
        while True:
            channel = self.subsock.recv()
            message = self.subsock.recv()            
            message = jsondecode(message)
            
            for name,value in message.items():
                if name in self.servos:
                    self.servos[name].moveTo(value)
                elif name in self.digitalouts:
                    self.digitalouts[name].write(value)
            gevent.sleep(0)

    def run(self):
        if self.subsock and len(self.buttons):
            gevent.spawn_link_exception(Controls.checkSubscription, self)
        elif self.subsock:
            self.checkSubscription()
            return
        
        while True:
            while self.board.bytes_available():
                self.board.iterate()
            #make sure we have a clean buffer before bouncing the buttons    
            for b in self.buttons:
                b.read()
                
            for p in self.potentiometers:
                p.read()
                
            gevent.sleep(0)