def run_loop(self, frame_manager: FrameManager, run_while: Callable): # process most recent events first and discard old ones q = queue.LifoQueue() subscribe_for_events(q) latest_processed_event = None while run_while(): try: event = q.get(timeout=1) except queue.Empty: # re-evaluate run_while continue if event['type'] != 'image': continue if latest_processed_event and latest_processed_event[ 'unix_timestamp'] >= event['unix_timestamp']: # skip over old events continue latest_processed_event = event frame_path = event['image_path'] frame = frame_manager.get_frame_by_path(frame_path) self.on_new_frame(frame) log_event(f'Tracking status: Stopped') unsubscribe_from_events(q)
def on_new_frame(self, frame): # only process frames from one device if frame.device != self.device: return pil_image = frame.get_pil_image() # TODO this assumes a color image image = np.transpose(np.asarray(pil_image), (1, 0, 2)) image_for_offset_detection = sigma_clip_dark_end( image, self.sigma_threshold) if self.reference_image is None: self.reference_image = image_for_offset_detection log_event(f'Using reference frame: {frame.path}') return (ra_error, dec_error), _, __ = register_translation(self.reference_image, image_for_offset_detection) if self.config['ra']['invert']: ra_error = -ra_error if self.config['dec']['invert']: dec_error = -dec_error if self.config['ra'].get('enable', True): ra_speed = self.ra_resting_speed_dps + self.ra_pid(ra_error) else: ra_speed = self.ra_resting_speed_dps if self.config['dec'].get('enable', True): dec_speed = self.dec_resting_speed_dps + self.dec_pid(dec_error) else: dec_speed = self.dec_resting_speed_dps self.axis_control.set_axis_speeds(ra_dps=ra_speed, dec_dps=dec_speed, mode='guiding') log_event( f'Guiding. Frame: {frame.path}. Offsets: {(ra_error, dec_error)}') if self.influx_client is not None: self.write_frame_stats( file_path=frame.path, ra_image_error=float(ra_error), ra_speed=float(ra_speed), ra_pid_p=float(self.ra_pid.components[0]), ra_pid_i=float(self.ra_pid.components[1]), ra_pid_d=float(self.ra_pid.components[2]), dec_image_error=float(dec_error), dec_speed=float(dec_speed), dec_pid_p=float(self.dec_pid.components[0]), dec_pid_i=float(self.dec_pid.components[1]), dec_pid_d=float(self.dec_pid.components[2]), brightness=np.average(image), )
def run_sequence(): try: cam_controller = get_camera_controller() frame_manager = get_frame_manager() for frame in cam_controller.capture_sequence( device_name, cam_state): frame_manager.add_frame(frame, persist=cam_state.persist) image_event(device_name, frame.path) log_event(f'New frame: {frame.path}') except Exception as e: log_event(f'Capture error: {e}') finally: cam_state.sequence_stop_requested = False cam_state.running_sequence = False app_state.send_event()
def exp(): app_state = get_app_state() cam_state = app_state.cameras[device_name] cam_controller = get_camera_controller() frame_manager = get_frame_manager() try: cam_state.capturing = True app_state.send_event() frame = cam_controller.capture_image(device_name, cam_state) frame_manager.add_frame(frame, persist=cam_state.persist) cam_state.capturing = False app_state.send_event() image_event(device_name, frame.path) log_event(f'New frame: {frame.path}') except TypeError as e: log_event(f'Capture error: {e}') cam_state.capturing = False app_state.send_event()
def analyze_fun(): app_state.calibrating = True calibration_data = Solver().analyze_image( filepath, timeout, run_callback=lambda: app_state.calibrating, ) app_state.calibrating = False timestamp = int(datetime.datetime.now().timestamp()) if calibration_data is None: log_event('Calibration failed') else: rotation_angle = calibration_data.rotation_angle position = calibration_data.center_deg log_event( f'Image center: {position} Rotation: {rotation_angle}') if app_state.target is not None: target_distance = Coordinates( app_state.target.ra - position.ra, app_state.target.dec - position.dec) log_event(f'Distance to target: {target_distance}') app_state.last_known_position = { 'timestamp': timestamp, 'position': position, }