Example #1
0
def view_thread():
    '''image viewing thread - this runs on the ground station'''
    import cuav_mosaic
    state = mpstate.camera_state

    bsend = block_xmit.BlockSender(state.settings.gcs_view_port,
                                   bandwidth=state.settings.bandwidth)
    state.bsocket = MavSocket(mpstate.mav_master[0])
    state.bsend2 = block_xmit.BlockSender(mss=96,
                                          sock=state.bsocket,
                                          dest_ip='mavlink',
                                          dest_port=0,
                                          backlog=5,
                                          debug=False)
    state.bsend2.set_bandwidth(state.settings.bandwidth2)

    view_window = False
    image_count = 0
    thumb_count = 0
    image_total_bytes = 0
    jpeg_total_bytes = 0
    thumb_total_bytes = 0
    region_count = 0
    mosaic = None
    thumbs_received = set()
    view_dir = os.path.join(state.camera_dir, "view")
    thumb_dir = os.path.join(state.camera_dir, "thumb")
    cuav_util.mkdir_p(view_dir)
    cuav_util.mkdir_p(thumb_dir)

    img_window = mp_image.MPImage(title='Camera')

    mpstate.console.set_status('Images', 'Images %u' % image_count, row=6)
    mpstate.console.set_status('Lost', 'Lost %u' % 0, row=6)
    mpstate.console.set_status('Regions', 'Regions %u' % region_count, row=6)
    mpstate.console.set_status('JPGSize', 'JPGSize %.0f' % 0.0, row=6)
    mpstate.console.set_status('XMITQ', 'XMITQ %.0f' % 0.0, row=6)

    mpstate.console.set_status('Thumbs', 'Thumbs %u' % thumb_count, row=7)
    mpstate.console.set_status('ThumbSize', 'ThumbSize %.0f' % 0.0, row=7)
    mpstate.console.set_status('ImageSize', 'ImageSize %.0f' % 0.0, row=7)

    ack_time = time.time()

    while not state.unload.wait(0.02):
        if state.viewing:
            tnow = time.time()
            if tnow - ack_time > 0.1:
                bsend.tick(packet_count=1000,
                           max_queue=state.settings.maxqueue1)
                state.bsend2.tick(packet_count=1000,
                                  max_queue=state.settings.maxqueue2)
                if state.bsend_slave is not None:
                    state.bsend_slave.tick(packet_count=1000)
                ack_time = tnow
            if not view_window:
                view_window = True
                mosaic = cuav_mosaic.Mosaic(slipmap=mpstate.map,
                                            C=state.c_params)
                if state.boundary_polygon is not None:
                    mosaic.set_boundary(state.boundary_polygon)
                if mpstate.continue_mode:
                    reload_mosaic(mosaic)

            # check for keyboard events
            mosaic.check_events()

            buf = bsend.recv(0)
            if buf is None:
                buf = state.bsend2.recv(0)
            if buf is None:
                continue
            try:
                obj = cPickle.loads(str(buf))
                if obj == None:
                    continue
            except Exception as e:
                continue

            if state.settings.gcs_slave is not None:
                if state.bsend_slave is None:
                    state.bsend_slave = block_xmit.BlockSender(
                        0,
                        bandwidth=state.settings.bandwidth * 10,
                        debug=False)
                state.bsend_slave.send(buf,
                                       dest=(state.settings.gcs_slave,
                                             state.settings.gcs_view_port),
                                       priority=1)

            if isinstance(obj, ThumbPacket):
                # we've received a set of thumbnails from the plane for a positive hit
                if obj.frame_time in thumbs_received:
                    continue
                thumbs_received.add(obj.frame_time)

                thumb_total_bytes += len(buf)

                # save the thumbnails
                thumb_filename = '%s/v%s.jpg' % (
                    thumb_dir, cuav_util.frame_time(obj.frame_time))
                chameleon.save_file(thumb_filename, obj.thumb)
                composite = cv.LoadImage(thumb_filename)
                thumbs = cuav_mosaic.ExtractThumbs(composite, len(obj.regions))

                # log the joe positions
                filename = '%s/v%s.jpg' % (
                    view_dir, cuav_util.frame_time(obj.frame_time))
                pos = obj.pos
                log_joe_position(pos, obj.frame_time, obj.regions, filename,
                                 thumb_filename)

                # update the mosaic and map
                mosaic.set_brightness(state.settings.brightness)
                mosaic.add_regions(obj.regions, thumbs, filename, pos=pos)

                # update console display
                region_count += len(obj.regions)
                state.frame_loss = obj.frame_loss
                state.xmit_queue = obj.xmit_queue
                thumb_count += 1

                mpstate.console.set_status('Lost',
                                           'Lost %u' % state.frame_loss)
                mpstate.console.set_status('Regions',
                                           'Regions %u' % region_count)
                mpstate.console.set_status('XMITQ',
                                           'XMITQ %.0f' % state.xmit_queue)
                mpstate.console.set_status('Thumbs', 'Thumbs %u' % thumb_count)
                mpstate.console.set_status(
                    'ThumbSize',
                    'ThumbSize %.0f' % (thumb_total_bytes / thumb_count))

            if isinstance(obj, ImagePacket):
                # we have an image from the plane
                image_total_bytes += len(buf)

                state.xmit_queue = obj.xmit_queue
                mpstate.console.set_status('XMITQ',
                                           'XMITQ %.0f' % state.xmit_queue)

                # save it to disk
                filename = '%s/v%s.jpg' % (
                    view_dir, cuav_util.frame_time(obj.frame_time))
                chameleon.save_file(filename, obj.jpeg)
                img = cv.LoadImage(filename)
                if img.width == 1280:
                    display_img = cv.CreateImage((640, 480), 8, 3)
                    cv.Resize(img, display_img)
                else:
                    display_img = img

                mosaic.add_image(obj.frame_time, filename, obj.pos)

                cv.ConvertScale(display_img,
                                display_img,
                                scale=state.settings.brightness)
                img_window.set_image(display_img, bgr=True)

                # update console
                image_count += 1
                jpeg_total_bytes += len(obj.jpeg)
                state.jpeg_size = 0.95 * state.jpeg_size + 0.05 * len(obj.jpeg)
                mpstate.console.set_status('Images', 'Images %u' % image_count)
                mpstate.console.set_status(
                    'JPGSize',
                    'JPG Size %.0f' % (jpeg_total_bytes / image_count))
                mpstate.console.set_status(
                    'ImageSize',
                    'ImageSize %.0f' % (image_total_bytes / image_count))

            if isinstance(obj, CommandResponse):
                print('REMOTE: %s' % obj.response)

        else:
            if view_window:
                view_window = False
Example #2
0
def view_thread():
    '''image viewing thread - this runs on the ground station'''
    import cuav_mosaic
    state = mpstate.camera_state

    bsend = block_xmit.BlockSender(state.gcs_view_port, state.bandwidth)

    view_window = False
    image_count = 0
    thumb_count = 0
    image_total_bytes = 0
    jpeg_total_bytes = 0
    thumb_total_bytes = 0
    region_count = 0
    mosaic = None
    view_dir = os.path.join(state.camera_dir, "view")
    thumb_dir = os.path.join(state.camera_dir, "thumb")
    cuav_util.mkdir_p(view_dir)
    cuav_util.mkdir_p(thumb_dir)

    img_window = mp_image.MPImage(title='Camera')

    mpstate.console.set_status('Images', 'Images %u' % image_count, row=6)
    mpstate.console.set_status('Lost', 'Lost %u' % 0, row=6)
    mpstate.console.set_status('Regions', 'Regions %u' % region_count, row=6)
    mpstate.console.set_status('JPGSize', 'JPGSize %.0f' % 0.0, row=6)
    mpstate.console.set_status('XMITQ', 'XMITQ %.0f' % 0.0, row=6)

    mpstate.console.set_status('Thumbs', 'Thumbs %u' % thumb_count, row=7)
    mpstate.console.set_status('ThumbSize', 'ThumbSize %.0f' % 0.0, row=7)
    mpstate.console.set_status('ImageSize', 'ImageSize %.0f' % 0.0, row=7)

    while not state.unload.wait(0.02):
        if state.viewing:
            bsend.tick(packet_count=1000)
            cv.WaitKey(1)
            if not view_window:
                view_window = True
                key = cv.WaitKey(1)
                mosaic = cuav_mosaic.Mosaic(slipmap=mpstate.map,
                                            lens=state.lens)
                if state.boundary is not None:
                    boundary = cuav_util.polygon_load(state.boundary)
                    mosaic.set_boundary(boundary)
            buf = bsend.recv(0)
            if buf is None:
                continue
            try:
                obj = cPickle.loads(str(buf))
                if obj == None:
                    continue
            except Exception as e:
                continue

            if isinstance(obj, ThumbPacket):
                # we've received a set of thumbnails from the plane for a positive hit
                thumb_total_bytes += len(buf)

                # save the thumbnails
                filename = '%s/v%s.jpg' % (
                    thumb_dir, cuav_util.frame_time(obj.frame_time))
                chameleon.save_file(filename, obj.thumb)
                composite = cv.LoadImage(filename)
                thumbs = cuav_mosaic.ExtractThumbs(composite, len(obj.regions))

                # log the joe positions
                filename = '%s/v%s.jpg' % (
                    view_dir, cuav_util.frame_time(obj.frame_time))
                pos = get_plane_position(obj.frame_time)
                log_joe_position(pos, obj.frame_time, obj.regions, filename)

                # update the mosaic and map
                mosaic.add_regions(obj.regions,
                                   thumbs,
                                   obj.latlon_list,
                                   filename,
                                   pos=pos)

                # update console display
                region_count += len(obj.regions)
                state.frame_loss = obj.frame_loss
                state.xmit_queue = obj.xmit_queue
                thumb_count += 1

                mpstate.console.set_status('Lost',
                                           'Lost %u' % state.frame_loss)
                mpstate.console.set_status('Regions',
                                           'Regions %u' % region_count)
                mpstate.console.set_status('XMITQ',
                                           'XMITQ %.0f' % state.xmit_queue)
                mpstate.console.set_status('Thumbs', 'Thumbs %u' % thumb_count)
                mpstate.console.set_status(
                    'ThumbSize',
                    'ThumbSize %.0f' % (thumb_total_bytes / thumb_count))

            if isinstance(obj, ImagePacket):
                # we have an image from the plane
                image_total_bytes += len(buf)

                # save it to disk
                filename = '%s/v%s.jpg' % (
                    view_dir, cuav_util.frame_time(obj.frame_time))
                chameleon.save_file(filename, obj.jpeg)
                img = cv.LoadImage(filename)

                # work out where we were at the time
                try:
                    pos = state.mpos.position(obj.frame_time, 0)
                except mav_position.MavInterpolatorException, msg:
                    print msg
                    pos = None
                if pos:
                    mosaic.add_image(filename, img, pos)

                img = cv.LoadImage(filename)
                if img.width == 1280:
                    display_img = cv.CreateImage((640, 480), 8, 3)
                    cv.Resize(img, display_img)
                else:
                    display_img = img

                cv.ConvertScale(display_img,
                                display_img,
                                scale=state.brightness)
                img_window.set_image(display_img, bgr=True)

                # update console
                image_count += 1
                jpeg_total_bytes += len(obj.jpeg)
                state.jpeg_size = 0.95 * state.jpeg_size + 0.05 * len(obj.jpeg)
                mpstate.console.set_status('Images', 'Images %u' % image_count)
                mpstate.console.set_status(
                    'JPGSize',
                    'JPG Size %.0f' % (jpeg_total_bytes / image_count))
                mpstate.console.set_status(
                    'ImageSize',
                    'ImageSize %.0f' % (image_total_bytes / image_count))

        else:
            if view_window:
                view_window = False
Example #3
0
def transmit_thread():
    '''thread for image transmit to GCS'''
    state = mpstate.camera_state

    tx_count = 0
    skip_count = 0
    bsend = block_xmit.BlockSender(0,
                                   bandwidth=state.settings.bandwidth,
                                   debug=False)
    state.bsocket = MavSocket(mpstate.mav_master[0])
    state.bsend2 = block_xmit.BlockSender(mss=96,
                                          sock=state.bsocket,
                                          dest_ip='mavlink',
                                          dest_port=0,
                                          backlog=5,
                                          debug=False)
    state.bsend2.set_bandwidth(state.settings.bandwidth2)

    while not state.unload.wait(0.02):
        bsend.tick(packet_count=1000, max_queue=state.settings.maxqueue1)
        state.bsend2.tick(packet_count=1000,
                          max_queue=state.settings.maxqueue2)
        check_commands()
        if state.transmit_queue.empty():
            continue

        (frame_time, regions, im_full, im_640) = state.transmit_queue.get()
        if state.settings.roll_stabilised:
            roll = 0
        else:
            roll = None
        pos = get_plane_position(frame_time, roll=roll)

        # this adds the latlon field to the regions
        log_joe_position(pos, frame_time, regions)

        # filter out any regions outside the boundary
        if state.boundary_polygon:
            regions = cuav_region.filter_boundary(regions,
                                                  state.boundary_polygon, pos)
            regions = cuav_region.filter_regions(
                im_full, regions, min_score=state.settings.minscore)

        state.xmit_queue = bsend.sendq_size()
        state.xmit_queue2 = state.bsend2.sendq_size()
        state.efficiency = bsend.get_efficiency()
        state.bandwidth_used = bsend.get_bandwidth_used()
        state.rtt_estimate = bsend.get_rtt_estimate()

        jpeg = None

        if len(regions) > 0:
            lowscore = 0
            highscore = 0
            for r in regions:
                lowscore = min(lowscore, r.score)
                highscore = max(highscore, r.score)

            if state.settings.transmit:
                # send a region message with thumbnails to the ground station
                thumb = None
                if state.settings.send1:
                    thumb = cuav_mosaic.CompositeThumbnail(
                        cv.GetImage(cv.fromarray(im_full)),
                        regions,
                        quality=state.settings.quality,
                        thumb_size=state.settings.thumbsize)
                    pkt = ThumbPacket(frame_time, regions, thumb,
                                      state.frame_loss, state.xmit_queue, pos)

                    buf = cPickle.dumps(pkt, cPickle.HIGHEST_PROTOCOL)
                    bsend.set_bandwidth(state.settings.bandwidth)
                    bsend.set_packet_loss(state.settings.packet_loss)
                    bsend.send(buf,
                               dest=(state.settings.gcs_address,
                                     state.settings.gcs_view_port),
                               priority=1)
                # also send thumbnails via 900MHz telemetry
                if state.settings.send2 and highscore >= state.settings.minscore2:
                    if thumb is None or lowscore < state.settings.minscore2:
                        # remove some of the regions
                        regions = cuav_region.filter_regions(
                            im_full,
                            regions,
                            min_score=state.settings.minscore2)
                        thumb = cuav_mosaic.CompositeThumbnail(
                            cv.GetImage(cv.fromarray(im_full)),
                            regions,
                            quality=state.settings.quality,
                            thumb_size=state.settings.thumbsize)
                        pkt = ThumbPacket(frame_time, regions, thumb,
                                          state.frame_loss, state.xmit_queue,
                                          pos)

                        buf = cPickle.dumps(pkt, cPickle.HIGHEST_PROTOCOL)
                    state.bsend2.set_bandwidth(state.settings.bandwidth2)
                    state.bsend2.send(buf, priority=highscore)

        # Base how many images we send on the send queue size
        send_frequency = state.xmit_queue // 3
        if send_frequency == 0 or (tx_count +
                                   skip_count) % send_frequency == 0:
            jpeg = scanner.jpeg_compress(im_640, state.settings.quality)

        if jpeg is None:
            skip_count += 1
            continue

        # keep filtered image size
        state.jpeg_size = 0.95 * state.jpeg_size + 0.05 * len(jpeg)

        tx_count += 1

        if state.settings.gcs_address is None:
            continue
        bsend.set_packet_loss(state.settings.packet_loss)
        bsend.set_bandwidth(state.settings.bandwidth)
        pkt = ImagePacket(frame_time, jpeg, state.xmit_queue, pos)
        str = cPickle.dumps(pkt, cPickle.HIGHEST_PROTOCOL)
        bsend.send(str,
                   dest=(state.settings.gcs_address,
                         state.settings.gcs_view_port))
Example #4
0
def transmit_thread():
    '''thread for image transmit to GCS'''
    state = mpstate.camera_state

    tx_count = 0
    skip_count = 0
    bsend = block_xmit.BlockSender(0, state.bandwidth)

    while not state.unload.wait(0.02):
        bsend.tick()
        if state.transmit_queue.empty():
            continue

        (frame_time, regions, im_full, im_640) = state.transmit_queue.get()
        pos = get_plane_position(frame_time)
        latlon_list = log_joe_position(pos, frame_time, regions)

        state.xmit_queue = bsend.sendq_size()
        state.efficiency = bsend.get_efficiency()
        state.bandwidth_used = bsend.get_bandwidth_used()
        state.rtt_estimate = bsend.get_rtt_estimate()

        jpeg = None

        if len(regions) > 0 and bsend.sendq_size() < 2000:
            # send a region message with thumbnails to the ground station
            thumb = cuav_mosaic.CompositeThumbnail(im_full,
                                                   regions,
                                                   quality=state.quality,
                                                   thumb_size=100)
            bsend.set_bandwidth(state.bandwidth)
            bsend.set_packet_loss(state.packet_loss)
            pkt = ThumbPacket(frame_time, regions, thumb, latlon_list,
                              state.frame_loss, state.xmit_queue)

            # send matches with a higher priority
            bsend.send(cPickle.dumps(pkt, cPickle.HIGHEST_PROTOCOL),
                       dest=(state.gcs_address, state.gcs_view_port),
                       priority=1)

        # Base how many images we send on the send queue size
        send_frequency = state.xmit_queue // 3
        if send_frequency == 0 or (tx_count +
                                   skip_count) % send_frequency == 0:
            jpeg = scanner.jpeg_compress(im_640, state.quality)

        if jpeg is None:
            skip_count += 1
            continue

        # keep filtered image size
        state.jpeg_size = 0.95 * state.jpeg_size + 0.05 * len(jpeg)

        tx_count += 1

        if state.gcs_address is None:
            continue
        bsend.set_packet_loss(state.packet_loss)
        bsend.set_bandwidth(state.bandwidth)
        pkt = ImagePacket(frame_time, jpeg)
        bsend.send(cPickle.dumps(pkt, cPickle.HIGHEST_PROTOCOL),
                   dest=(state.gcs_address, state.gcs_view_port))