Beispiel #1
0
def test():
    c = Camera()
    c.start()
    
    def test_get_image(frame):
            cv2.imshow("test image", frame)
            cv2.waitKey(1)
            
    p = r.pubsub(ignore_subscribe_messages=True)
    start = datetime.datetime.now()
    p.subscribe(messages.NEW_IMAGE_FRAME)

    while (datetime.datetime.now() - start).total_seconds() < 10:
        message = p.get_message()
        if message:
            channel = message['channel']
            data = message['data']
            msg_type = message['type']

            img = redis_helpers.fromRedis(data, np.uint8)

            test_get_image(img)

        time.sleep(0.1)

    r.publish(messages.STOP_ALL, "")
Beispiel #2
0
def get_current_status():
    p = r.pubsub(ignore_subscribe_messages=True)

    status = {
        messages.STATUS_TRACKING_STATUS: None,
        messages.STATUS_MOVEMENT_STATUS: None,
        messages.STATUS_GUIDING_STATUS: None,
        messages.STATUS_DITHERING_STATUS: None
    }

    for key in status.keys():
        p.subscribe(key)

    r.publish(messages.STATUS_GET_ALL_STATUS, "")

    while 1:
        message = p.get_message()
        if message:
            channel = message['channel'].decode('ASCII')
            data = redis_helpers.fromRedis(message['data'])
            if channel in status:
                status[channel] = data

                finished = functools.reduce(
                    lambda a, b: a and b,
                    map(lambda x: x is not None, status.values()))
                if finished:
                    break
        time.sleep(0.1)

    return status
Beispiel #3
0
def gen_frame(msg_type):
    r2 = redis.StrictRedis(host='localhost', port=6379)
    p = r2.pubsub(ignore_subscribe_messages=True)
    p.subscribe(msg_type)

    for message in p.listen():
        data = message['data']
        jpeg_bytes = redis_helpers.fromRedis(data)

        newImageContent = (b'--frame\r\n'
                           b'Content-Type: image/jpeg\r\n\r\n' + jpeg_bytes +
                           b'\r\n')

        yield newImageContent
    def set_absolute_position_handler(self, message):
        ra, dec = redis_helpers.fromRedis(message['data'])
        print('received absolute position update: ', ra, dec)

        if ra is None or dec is None:
            print('getting absolute position failed, ignoring None(s)')
        else:
            new_ra_zero_pos = self.relative_ra_degrees - ra
            new_dec_zero_pos = self.relative_dec_degrees - dec

            print('coodinate zero pos update deltas: ',
                  self.ra_zero_pos_degrees - new_ra_zero_pos,
                  self.dec_zero_pos_degrees - new_dec_zero_pos)

            self.ra_zero_pos_degrees = new_ra_zero_pos
            self.dec_zero_pos_degrees = new_dec_zero_pos
    def message_to_scaled_jpeg_bytes(self, message):

        image = redis_helpers.fromRedis(message['data'])

        target_size = 400
        if image.shape[0] > target_size:
            factor = image.shape[0] // target_size
            image = cv2.resize(image,
                               None,
                               fx=1.0 / factor,
                               fy=1.0 / factor,
                               interpolation=cv2.INTER_AREA)

        output_image = image * self.visual_gain

        ret, jpeg = cv2.imencode('.jpg', output_image)
        jpeg_bytes = jpeg.tobytes()
        return jpeg_bytes
    def run(self):
        desired_location = None
        guide_vector = None
        guide_vector_orthogonal = None

        orthogonal_distance = None
        parallel_distance = None
        update_time = None

        filtered_adjustment = 0
        ema_factor = 0.8

        current_state = AdjusterStates.NOT_GUIDING

        r = redis.StrictRedis(host='localhost', port=6379)
        p = r.pubsub(ignore_subscribe_messages=True)

        p.subscribe(messages.CMD_START_GUIDING)
        p.subscribe(messages.CMD_STOP_GUIDING)
        p.subscribe(messages.STATUS_CURRENT_TRACKING_POSITION)
        p.subscribe(messages.CMD_START_TRACKING)
        p.subscribe(messages.STATUS_STARTING_TRACKING_POSITION)
        p.subscribe(messages.CMD_SET_DITHERING_POSITION_OFFSET_PIXELS)
        p.subscribe(messages.STATUS_GET_ALL_STATUS)

        start_guiding_dir_1_start_time = None
        start_guiding_dir_1_start_location = None

        guiding_dir_2_start_time = None

        guiding_dir_orth_start_time = None

        failed_track_count = 0

        dithering_offset = [0, 0]

        while not self.kill:
            message = p.get_message()
            if message:
                channel = message['channel'].decode('ASCII')
                data = message['data']

                if channel == messages.CMD_START_TRACKING:
                    #reset things
                    desired_location = None

                elif channel == messages.CMD_START_GUIDING:
                    print('start guiding received')
                    #desired_location = None #will get grabbed first
                    current_state = AdjusterStates.CMD_START_GUIDING

                    #TODO: publish state?

                elif channel == messages.CMD_STOP_GUIDING:
                    r.publish(
                        messages.CMD_ENABLE_MOVEMENT,
                        "")  #in case this came in during guide vector finding
                    r.publish(messages.CMD_SET_SPEED_ADJUSTMENT_RA,
                              redis_helpers.toRedis(0))
                    r.publish(messages.STATUS_CURRENT_RAW_ADJUSTMENT,
                              redis_helpers.toRedis(0))
                    r.publish(messages.CMD_SET_SPEED_ADJUSTMENT_DEC,
                              redis_helpers.toRedis(0))

                    current_state = AdjusterStates.NOT_GUIDING
                    desired_location = None
                    #publish state?

                elif channel == messages.STATUS_STARTING_TRACKING_POSITION:
                    desired_location = redis_helpers.fromRedis(data)
                    print('adjuster got new desired location: ',
                          desired_location)

                elif channel == messages.CMD_SET_DITHERING_POSITION_OFFSET_PIXELS:
                    dithering_offset = redis_helpers.fromRedis(data)
                    # print('new dithering offset: ', dithering_offset)

                elif channel == messages.STATUS_GET_ALL_STATUS:
                    r.publish(
                        messages.STATUS_GUIDING_STATUS,
                        redis_helpers.toRedis(
                            current_state != AdjusterStates.NOT_GUIDING))

                elif channel == messages.STATUS_CURRENT_TRACKING_POSITION:
                    current_position = redis_helpers.fromRedis(data)

                    if desired_location is None:
                        print('trying to track with no desired location?')
                        #desired_location = current_position
                        continue
                    else:
                        shift = current_position - desired_location
                        r.publish(messages.STATUS_DRIFT_X,
                                  redis_helpers.toRedis(shift[1]))
                        r.publish(messages.STATUS_DRIFT_Y,
                                  redis_helpers.toRedis(shift[0]))

                    if current_state == AdjusterStates.NOT_GUIDING:
                        pass

                    elif current_state == AdjusterStates.CMD_START_GUIDING:  #set up to calc guiding vector
                        r.publish(messages.CMD_SET_SPEED_ADJUSTMENT_RA,
                                  redis_helpers.toRedis(-1))

                        #desired_location = current_position
                        #TODO: wait a frame or two?

                        start_guiding_dir_1_start_location = None
                        start_guiding_dir_1_start_time = None
                        current_state = AdjusterStates.START_GUIDING_DIR_1

                    elif current_state == AdjusterStates.START_GUIDING_DIR_1:  #calculate the guiding vector

                        if start_guiding_dir_1_start_location is None:
                            start_guiding_dir_1_start_time = datetime.now()
                            start_guiding_dir_1_start_location = current_position
                        elif (
                                datetime.now() - start_guiding_dir_1_start_time
                        ).total_seconds() < VECTOR_ESTIMATION_TIME_SECONDS:
                            pass
                        else:  #end of guide vector finding in direction 1
                            start_guiding_dir_1_end_time = datetime.now()
                            start_guiding_dir_1_end_location = current_position


                            guide_vector = np.array((start_guiding_dir_1_end_location[0] - start_guiding_dir_1_start_location[0],
                                                    start_guiding_dir_1_end_location[1] - start_guiding_dir_1_start_location[1])) / \
                                                            (start_guiding_dir_1_end_time - start_guiding_dir_1_start_time).total_seconds()

                            print('guide vector: ', guide_vector)
                            r.publish(messages.STATUS_GUIDE_VECTOR_RA,
                                      redis_helpers.toRedis(guide_vector))

                            #now speed forwards to get back to original position
                            # r.publish(messages.CMD_ENABLE_MOVEMENT, "")
                            r.publish(messages.CMD_SET_SPEED_ADJUSTMENT_RA,
                                      redis_helpers.toRedis(1.0))
                            current_state = AdjusterStates.START_GUIDING_DIR_2

                    elif current_state == AdjusterStates.START_GUIDING_DIR_2:  #return to starting point, get off-axis vector

                        if guiding_dir_2_start_time is None:
                            guiding_dir_2_start_time = datetime.now()
                        else:

                            distance_along_guide = np.dot(
                                shift, guide_vector) / (
                                    np.linalg.norm(guide_vector)**2)
                            print('guide state 2, distance along guide: ',
                                  distance_along_guide)
                            if distance_along_guide > 0:
                                #still getting back to the start
                                pass
                            else:
                                # elapsed_time_seconds = (datetime.now() - guiding_dir_2_start_time).total_seconds()

                                calibration_time_seconds = (
                                    datetime.now() -
                                    start_guiding_dir_1_start_time
                                ).total_seconds()
                                shift = current_position - desired_location
                                orthogonal_distance_entire_calibration_pixels = np.dot(
                                    shift, [-guide_vector[1], guide_vector[0]])

                                calibration_process_orthogonal_drift = orthogonal_distance_entire_calibration_pixels * GUIDE_CAM_ARC_SECONDS_PER_PIXEL / calibration_time_seconds

                                # orthogonal_vector = (shift - distance_along_guide * guide_vector) / elapsed_time_seconds
                                # print('orthogonal vector: ', orthogonal_vector)
                                # #convert pixels/second to arc-seconds/s or something
                                # orthogonal_distance = np.linalg.norm(orthogonal_vector)

                                r.publish(
                                    messages.
                                    STATUS_CALIBRATION_DRIFT_ARC_SECONDS,
                                    redis_helpers.toRedis(
                                        calibration_process_orthogonal_drift))

                                r.publish(messages.CMD_SET_SPEED_ADJUSTMENT_RA,
                                          redis_helpers.toRedis(0.))
                                filtered_adjustment = 0  #reset
                                current_state = AdjusterStates.START_GUIDING_DIR_ORTH_1
                                guiding_dir_orth_start_time = None
                                print('guiding...')

                    elif current_state in [
                            AdjusterStates.START_GUIDING_DIR_ORTH_1,
                            AdjusterStates.START_GUIDING_DIR_ORTH_2,
                            AdjusterStates.GUIDING
                    ]:

                        if current_position is None:
                            failed_track_count += 1

                            if failed_track_count > 20:
                                print(
                                    'failed tracking too many times, trying to restart...?'
                                )
                                # r.publish(messages.CMD_START_TRACKING, "")
                                # r.publish(messages.CMD_STOP_GUIDING)
                                # r.publish(messages.CMD_START_GUIDING)

                                current_state = AdjusterStates.NOT_GUIDING
                                filtered_adjustment_ra = 0
                                raw_adjustment_ra = 0
                                parallel_distance = 0
                                orthogonal_distance = 0
                                filtered_adjustment_dec = 0
                                raw_adjustment_dec = 0

                                r.publish(
                                    messages.STATUS_FAILED_TRACKING_COUNT,
                                    redis_helpers.toRedis(failed_track_count))
                        else:
                            failed_track_count = 0
                            r.publish(
                                messages.STATUS_FAILED_TRACKING_COUNT,
                                redis_helpers.toRedis(failed_track_count))

                            #do parallel guiding in all states. only dither once we're up and running
                            if current_state == AdjusterStates.GUIDING:
                                shift = current_position - (desired_location +
                                                            dithering_offset)
                            else:
                                shift = current_position - desired_location
                            # print('shift: ', shift)
                            parallel_distance = np.dot(shift, guide_vector) / (
                                np.linalg.norm(guide_vector)**2)

                            if guide_vector_orthogonal is None:
                                orthogonal_distance = 0
                            else:
                                orthogonal_distance = np.dot(
                                    shift, guide_vector_orthogonal) / (
                                        np.linalg.norm(guide_vector_orthogonal)
                                        **2)

                            raw_adjustment_ra = parallel_distance / ADJUSTMENT_TARGET_SECONDS
                            clipped_adjustment = np.clip(
                                raw_adjustment_ra, -MAX_ADJUSTMENT,
                                MAX_ADJUSTMENT)
                            filtered_adjustment = filtered_adjustment * ema_factor + clipped_adjustment * (
                                1 - ema_factor)
                            filtered_adjustment_ra = filtered_adjustment

                            if current_state == AdjusterStates.START_GUIDING_DIR_ORTH_1:
                                if guiding_dir_orth_start_time is None:
                                    print('starting guiding for orthogonal')
                                    guiding_dir_orth_start_time = datetime.now(
                                    )
                                    guiding_dir_orth_start_location = current_position
                                    filtered_adjustment_dec = -1
                                    raw_adjustment_dec = -1
                                else:
                                    elapsed_time_seconds = (
                                        datetime.now() -
                                        guiding_dir_orth_start_time
                                    ).total_seconds()
                                    print(
                                        'orth guide vector estimating time: ',
                                        elapsed_time_seconds)
                                    if elapsed_time_seconds >= VECTOR_ESTIMATION_TIME_SECONDS:
                                        distance_along_guide = np.dot(
                                            shift, guide_vector) / (
                                                np.linalg.norm(guide_vector)**
                                                2)
                                        orthogonal_vector = shift - distance_along_guide * guide_vector
                                        guide_vector_orthogonal = orthogonal_vector / elapsed_time_seconds

                                        print('guide vector orthogonal: ',
                                              guide_vector_orthogonal)
                                        print(
                                            'angle between vectors: ',
                                            angle_between_vectors(
                                                guide_vector,
                                                guide_vector_orthogonal))

                                        r.publish(
                                            messages.STATUS_GUIDE_VECTOR_DEC,
                                            redis_helpers.toRedis(
                                                guide_vector_orthogonal))

                                        current_state = AdjusterStates.GUIDING
                                        filtered_adjustment_dec = 1  #start speeding back towards origin
                                        raw_adjustment_dec = 1

                            elif current_state == AdjusterStates.START_GUIDING_DIR_ORTH_2:
                                print('dir_orth_2, orth distance = ',
                                      orthogonal_distance)

                                if orthogonal_distance < 0:
                                    print('back to origin, moving to guiding')
                                    filtered_adjustment_dec = 0
                                    raw_adjustment_dec = 0
                                    current_state = AdjusterStates.GUIDING

                                #TODO: back to original position

                            elif current_state == AdjusterStates.GUIDING:

                                orthogonal_vector = shift - parallel_distance * guide_vector

                                #TODO: filter realllll slow instead of just making it slow
                                raw_adjustment_dec = orthogonal_distance / ORTHOGONAL_ADJUSTMENT_TARGET_SECONDS
                                filtered_adjustment_dec = np.clip(
                                    raw_adjustment_dec, -MAX_ADJUSTMENT,
                                    MAX_ADJUSTMENT)

                        r.publish(
                            messages.CMD_SET_SPEED_ADJUSTMENT_RA,
                            redis_helpers.toRedis(filtered_adjustment_ra))
                        r.publish(messages.STATUS_CURRENT_RAW_ADJUSTMENT,
                                  redis_helpers.toRedis(raw_adjustment_ra))
                        r.publish(messages.STATUS_PARALLEL_ERROR,
                                  redis_helpers.toRedis(parallel_distance))
                        r.publish(messages.STATUS_ORTHOGONAL_ERROR,
                                  redis_helpers.toRedis(orthogonal_distance))
                        r.publish(
                            messages.CMD_SET_SPEED_ADJUSTMENT_DEC,
                            redis_helpers.toRedis(filtered_adjustment_dec))

                        guiding_status = {
                            'drift_x': str(shift[1]),
                            'drift_y': str(shift[0]),
                            'parallel_error': str(parallel_distance),
                            'orthogonal_error': str(orthogonal_distance),
                            'raw_adjustment_ra': str(raw_adjustment_ra),
                            'filtered_adjustment_ra':
                            str(filtered_adjustment_ra),
                            'raw_adjustment_dec': str(raw_adjustment_dec),
                            'filtered_adjustment_dec':
                            str(filtered_adjustment_dec)
                        }
                        r.publish(messages.STATUS_GUIDING_STATUS,
                                  redis_helpers.toRedis(guiding_status))

                    else:
                        print('unknown state: ', current_state)
 def set_visual_gain_handler(self, message):
     new_gain = redis_helpers.fromRedis(message['data'])
     self.visual_gain = new_gain
Beispiel #8
0
	def dither_offset_handler(message):
		offsets = redis_helpers.fromRedis(message['data'])
		# print(offsets)
		xs.append(offsets[1])
		ys.append(offsets[0])
Beispiel #9
0
 def set_dithering_interval_handler(self, message):
 	self.t = 0
 	self.dithering_interval_seconds = redis_helpers.fromRedis(message['data'])
 	print('dithering interval: ', self.dithering_interval_seconds)
Beispiel #10
0
 def set_dithering_magnitude_handler(self, message):
 	self.t = 0
 	self.dithering_magnitude_pixels = redis_helpers.fromRedis(message['data'])
 	print('dithering magnitude: ', self.dithering_magnitude_pixels)
 def update_ha_handler(self, message):
     self.ha_relative_degrees += redis_helpers.fromRedis(message['data'])
     self.on_new_position()
Beispiel #12
0
 def set_shutter_speed_handler(self, message):
     shutter_speed_ms = redis_helpers.fromRedis(message['data'])
     self.set_shutter_speed(shutter_speed_ms)
Beispiel #13
0
 def set_adjustment_factor_handler(self, message):
     self.adjustment_factor = redis_helpers.fromRedis(message['data'])