Esempio n. 1
0
def _wait_home_origin(xbee):
    """
    Wait for the HOME_ORIGIN sent by the GCS.
    
    `HOME_ORIGIN` is not the internal `home` set by the flight controller, it is
    a high-level reference coordinate, used in the application algorithms.
    Note that this is a blocking wait, so the program is stuck indefinately unless
    stopped by `EXIT` command or killed by KeyboardInterrupt.
    
    Args:
        xbee(xbee.Zigbee): the XBee communication interface.
        
    Returns:
        bool: True if success, False if killed by `EXIT` command. 
    """
    util.log_info("Waiting HOME_ORIGIN.")
    wait_count = 0
    while not shared.home_origin:
        time.sleep(1)
        wait_count = wait_count + 1

        if shared.status['command'] == 'EXIT':
            comm.xbee_broadcast(xbee,
                                "IFO,%s abort takeoff." % shared.AGENT_ID)
            util.log_info("'EXIT' received. Abort takeoff.")
            return False

        if wait_count >= 10:
            wait_count = 0
            comm.xbee_broadcast(
                xbee, "IFO,%s awaiting HOME_ORIGIN." % shared.AGENT_ID)

    return True
Esempio n. 2
0
def _log_and_broadcast(xbee, info):
    """
    Log some information at `INFO` level and broadcast via XBee.
    
    Args:
        xbee(xbee.Zigbee): the XBee communication interface.
        info(str): the information string.
    """
    comm.xbee_broadcast(xbee, info)
    util.log_info(info)
Esempio n. 3
0
def _wait_lift_cmd(xbee):
    """
    Wait for takeoff clearance from the GCS.
    
    This is a blocking check, so the program is stuck indefinately unless
    received `LIFT` clearance, stopped by `EXIT` command or killed by 
    KeyboardInterrupt.
    
    Args:
        xbee(xbee.Zigbee): the XBee communication interface.
        
    Returns:
        bool: True if success, False if killed by `EXIT` command. 
    """
    shared.status['command'] = 'STDBY'
    util.log_info("%s Standby, awaiting 'LIFT'." % shared.AGENT_ID)

    wait_count = 0
    while True:
        time.sleep(.1)
        wait_count = wait_count + 1

        if shared.status['command'] == 'LIFT':
            comm.xbee_broadcast(
                xbee, "IFO,%s cleared for takeoff." % shared.AGENT_ID)
            util.log_info("'LIFT' received! Taking off!")
            return True

        elif shared.status['command'] == 'EXIT':
            comm.xbee_broadcast(xbee,
                                "IFO,%s abort takeoff." % shared.AGENT_ID)
            util.log_info("'EXIT' received. Abort takeoff.")
            return False

        elif wait_count >= 100:
            wait_count = 0
            comm.xbee_broadcast(
                xbee, "IFO,%s standby. Alt: %.2f m." %
                (shared.AGENT_ID, shared.des_alt))
Esempio n. 4
0
def _preflight_check(vehicle, xbee):
    """
    Perform preflight check, validate home coordinates and satellites fix.
    
    This is a blocking check, so the program is stuck indefinately unless
    stopped by `EXIT` command or killed by KeyboardInterrupt.
    
    Args:
        vehicle(dronekit.Vehicle): the vehicle to be controlled.
        xbee(xbee.Zigbee): the XBee communication interface.
        
    Returns:
        bool: True if success, False if killed by `EXIT` command. 
    """
    util.log_info("Waiting for home location.")
    while not vehicle.home_location:
        if shared.status['command'] == 'EXIT':
            comm.xbee_broadcast(xbee,
                                "IFO,%s abort takeoff." % shared.AGENT_ID)
            util.log_info("'EXIT' received. Abort takeoff.")
            return False

        time.sleep(2)
        cmds = vehicle.commands
        cmds.download()
        cmds.wait_ready()
        comm.xbee_broadcast(xbee, "IFO,%s getting home fix." % shared.AGENT_ID)

    # We have a home location now.
    comm.xbee_broadcast(
        xbee, 'IFO,%s home: %s.' % (shared.AGENT_ID, vehicle.home_location))
    util.log_info('Home location: %s' % vehicle.home_location)

    # Check satellite condition to ensure 3D-fix first
    while vehicle.gps_0.fix_type < 3:
        if shared.status['command'] == 'EXIT':
            comm.xbee_broadcast(xbee,
                                "IFO,%s abort takeoff." % shared.AGENT_ID)
            util.log_info("'EXIT' received. Abort takeoff.")
            return False

        comm.xbee_broadcast(xbee, "IFO,%s GNSS No 3D-fix." % shared.AGENT_ID)
        util.log_warning("GNSS No 3D Fix.")
        time.sleep(3)

    # APM:Copter parameter: GPS_HDOP_GOOD
    # The value is mutiplied by 100 into a integer, default good HDOP is below 140
    while vehicle.gps_0.eph > 140 or vehicle.gps_0.satellites_visible < 9:
        if shared.status['command'] == 'EXIT':
            comm.xbee_broadcast(xbee,
                                "IFO,%s abort takeoff." % shared.AGENT_ID)
            util.log_info("'EXIT' received. Abort takeoff.")
            return False

        util.log_info(
            "HDOP: %.2f NumSat: %s" %
            (vehicle.gps_0.eph / 100.0, vehicle.gps_0.satellites_visible))

        comm.xbee_broadcast(
            xbee, "IFO,%s HDOP: %.2f NumSat: %s" %
            (shared.AGENT_ID, vehicle.gps_0.eph / 100.0,
             vehicle.gps_0.satellites_visible))

        time.sleep(3)
    # --END of while-- Preflight check passed.

    comm.xbee_broadcast(xbee,
                        "IFO,%s Preflight check passed." % shared.AGENT_ID)
    util.log_info(
        "Preflight check passed. HDOP: %.2f NumSats: %s" %
        (vehicle.gps_0.eph / 100.0, vehicle.gps_0.satellites_visible))

    util.log_info("Local time %s" % shared.timestamp)
    return True
Esempio n. 5
0
    def run(self):
        """
        Run `SquareRoute` thread.
        """
        info = "IFO,Leader %s engaging <SquareRoute>." % shared.AGENT_ID
        comm.xbee_broadcast(self._xbee, info)
        util.log_info(info)

        EDGE_LEN = 7.0  # square edge length
        WP_GSPEED = 1.0  # groundspeed for navigating
        edge_count = 0  # a counter holding which edge the copter is on
        old_gspeed = self._vehicle.groundspeed  # log original gspeed

        # flying direction vector
        dir = [
            # dNorth, dEast
            [EDGE_LEN, 0, 'North'],  # North
            [0, EDGE_LEN, 'East'],  # East
            [-EDGE_LEN, 0, 'South'],  # South
            [0, -EDGE_LEN, 'West']  # West
        ]

        # waypoints
        wp = [
            # WP, description
            [None, 'N-W'],
            [None, 'N-E'],
            [None, 'S-E'],
            [None, 'S-W']
        ]

        # extract square-shaped waypoints (hard waypoints to counter drifting)
        wp[-1][0] = self._vehicle.location.global_relative_frame
        wp[0][0] = nav.get_location_metres(wp[-1][0], dir[0][0], dir[0][1])
        wp[1][0] = nav.get_location_metres(wp[0][0], dir[1][0], dir[1][1])
        wp[2][0] = nav.get_location_metres(wp[1][0], dir[2][0], dir[2][1])

        is_on_hold = False  # hold position flag for low Nsats

        while not self._stopflag:
            [self._stopflag,
             exit_number] = _check_terminate_condition(self._vehicle,
                                                       'SquareRoute')

            is_on_hold = _check_satellite_low(self._xbee, is_on_hold)
            if is_on_hold: continue

            # hold position if RC_CH6 is at low-level
            if self._vehicle.channels['6'] < 1500:
                time.sleep(1)
                continue

            # loiter for 3 second and moving along an edge utilizing
            # internal function <simple_goto>
            time.sleep(3)
            _log_and_broadcast(
                self._xbee, "IFO,Leader-%s moving towards %s" %
                (shared.AGENT_ID, dir[edge_count][2]))
            self._vehicle.simple_goto(wp[edge_count][0], groundspeed=WP_GSPEED)

            # check distance until reached
            while not self._stopflag:
                [self._stopflag, exit_number
                 ] = _check_terminate_condition(self._vehicle, 'SquareRoute')

                is_on_hold = _check_satellite_low(self._xbee, is_on_hold)
                if is_on_hold: continue

                time.sleep(0.2)

                current = self._vehicle.location.global_relative_frame
                distance = nav.get_distance_metres(current, wp[edge_count][0])

                if distance <= shared.WP_RADIUS:
                    _log_and_broadcast(
                        self._xbee, "IFO,Leader-%s %s corner reached" %
                        (shared.AGENT_ID, wp[edge_count][1]))
                    edge_count = (edge_count + 1) % 4
                    break

                elif self._vehicle.channels['6'] < 1500:
                    nav.send_ned_velocity(self._vehicle, 0, 0, 0, 0.5)  # brake
                    break
        # End of While #
        _log_and_broadcast(
            self._xbee, "IFO,%s SquareRoute ended with number %d." %
            (shared.AGENT_ID, exit_number))

        self._vehicle.groundspeed = old_gspeed  #restore vehicle gspeed