예제 #1
0
    def _setup_state(self):
        ''' Performs calculations and operations required for the "setup" state
            NOTE:  Deprecated
        '''
        # If init required, set waypoint fwd of the target by the run-in distance
        if not self._state_initialized:
            self.log_info("Commence setup phase")
            self.wp_msg.lat, self.wp_msg.lon = \
                gps.gps_newpos(self._xt[0], self._xt[1], self._xt[2], \
                               PNInterceptor.R_RUNIN)
            self.wp_msg.alt = self._ap_intent.z
            self.publishWaypoint(self.wp_msg)
            self._state_initialized = True
            self.log_dbug("Setup waypoint order to lat %f, lon %f"\
                          %(self.wp_msg.lat, self.wp_msg.lon)) 

        self._range = gps.gps_distance(self._xp[0], self._xp[1], \
                                       self._xt[0], self._xt[1])

        # Keep going until we're in front of the target
        # Then set the waypoint to the target location for the run-in
        if gps.gps_distance(self._xp[0], self._xp[1], \
                            self.wp_msg.lat, self.wp_msg.lon) < \
           PNInterceptor.R_CAP_SETUP:
            self._state_initialized = False
            self._state = PNInterceptor.RUN_IN
            self.log_info("Transition to run-in phase")
예제 #2
0
    def _setup_state(self):
        ''' Performs calculations and operations required for the "setup" state
            NOTE:  Deprecated
        '''
        # If init required, set waypoint fwd of the target by the run-in distance
        if not self._state_initialized:
            self.log_info("Commence setup phase")
            self.wp_msg.lat, self.wp_msg.lon = \
                gps.gps_newpos(self._xt[0], self._xt[1], self._xt[2], \
                               PNInterceptor.R_RUNIN)
            self.wp_msg.alt = self._ap_intent.z
            self.publishWaypoint(self.wp_msg)
            self._state_initialized = True
            self.log_dbug("Setup waypoint order to lat %f, lon %f"\
                          %(self.wp_msg.lat, self.wp_msg.lon))

        self._range = gps.gps_distance(self._xp[0], self._xp[1], \
                                       self._xt[0], self._xt[1])

        # Keep going until we're in front of the target
        # Then set the waypoint to the target location for the run-in
        if gps.gps_distance(self._xp[0], self._xp[1], \
                            self.wp_msg.lat, self.wp_msg.lon) < \
           PNInterceptor.R_CAP_SETUP:
            self._state_initialized = False
            self._state = PNInterceptor.RUN_IN
            self.log_info("Transition to run-in phase")
    def compute_intercept_waypoint(self, wpt=None):
        ''' Computes an intercept waypoint for the UAV to steer to
        @param wpt: waypoint object to use for computed values
        @return waypoint object (LLA) with the intercept waypoint (or None)
        '''
        lead_uav = self._pre_check()
        if not lead_uav:
            return None

        # Convenience variables for state info
        own_lat = self.own_pose.pose.pose.position.lat
        own_lon = self.own_pose.pose.pose.position.lon
        own_spd = math.hypot(self.own_pose.twist.twist.linear.x, \
                             self.own_pose.twist.twist.linear.y)
        lead_lat = lead_uav.state.pose.pose.position.lat
        lead_lon = lead_uav.state.pose.pose.position.lon
        lead_alt = lead_uav.state.pose.pose.position.rel_alt
        lead_x_dot = lead_uav.state.twist.twist.linear.x
        lead_y_dot = lead_uav.state.twist.twist.linear.y
        lead_crs = math.atan2(lead_y_dot, lead_x_dot)
        lead_spd = math.hypot(lead_y_dot, lead_x_dot)

        # Compute tgt positions and distances for potential calculation
        tgt_lat, tgt_lon = gps.gps_newpos(lead_lat, lead_lon, \
                                          (lead_crs + self._follow_angle), \
                                          self._follow_distance)
        dist = gps.gps_distance(own_lat, own_lon, tgt_lat, tgt_lon)
        angle = gps.gps_bearing(own_lat, own_lon, tgt_lat, tgt_lon)
        x_dist = dist * math.cos(angle)
        y_dist = dist * math.sin(angle)
        time_to_intercept = 0.0
        if own_spd > 0.1:
            time_to_intercept = \
                gps.gps_distance(own_lat, own_lon, tgt_lat, tgt_lon) / own_spd
        time_to_intercept = min(time_to_intercept, self.lookahead)
        lead_travel = lead_spd * time_to_intercept
        x_travel = lead_travel * lead_x_dot
        y_travel = lead_travel * lead_y_dot

        # Compute potential values and target waypoint
        x_potential = self._dist_coefficient * x_dist + \
                      self._align_coefficient * lead_x_dot/lead_spd + \
                      self._intercept_coefficient * x_travel
        y_potential = self._dist_coefficient * y_dist + \
                      self._align_coefficient * lead_y_dot/lead_spd + \
                      self._intercept_coefficient * y_travel
        if not wpt: wpt = brdgmsg.LLA()
        wpt.lat, wpt.lon = \
            gps.gps_newpos(own_lat, own_lon, \
                           math.atan2(y_potential, x_potential), \
                           InterceptCalculator.OVERSHOOT)
        if self._alt_mode == InterceptCalculator.BASE_ALT_MODE:
            wpt.alt = self._alt
        else:
            wpt.alt = lead_uav.state.pose.pose.rel_alt + self._alt
        self._owner.log_dbug(
            "intercept waypoint (lat, lon, alt) = (%f, %f, %f)" %
            (wpt.lat, wpt.lon, wpt.alt))
        return wpt
    def compute_intercept_waypoint(self, wpt=None):
        ''' Computes an intercept waypoint for the UAV to steer to
        @param wpt: waypoint object to use for computed values
        @return waypoint object (LLA) with the intercept waypoint (or None)
        '''
        lead_uav = self._pre_check()
        if not lead_uav:
            return None

        # Convenience variables for state info
        own_lat = self.own_pose.pose.pose.position.lat
        own_lon = self.own_pose.pose.pose.position.lon
        own_spd = math.hypot(self.own_pose.twist.twist.linear.x, \
                             self.own_pose.twist.twist.linear.y)
        lead_lat = lead_uav.state.pose.pose.position.lat
        lead_lon = lead_uav.state.pose.pose.position.lon
        lead_alt = lead_uav.state.pose.pose.position.rel_alt
        lead_x_dot = lead_uav.state.twist.twist.linear.x
        lead_y_dot = lead_uav.state.twist.twist.linear.y
        lead_crs = math.atan2(lead_y_dot, lead_x_dot)
        lead_spd = math.hypot(lead_y_dot, lead_x_dot)

        # Compute tgt positions and distances for potential calculation
        tgt_lat, tgt_lon = gps.gps_newpos(lead_lat, lead_lon, \
                                          (lead_crs + self._follow_angle), \
                                          self._follow_distance)
        dist = gps.gps_distance(own_lat, own_lon, tgt_lat, tgt_lon)
        angle = gps.gps_bearing(own_lat, own_lon, tgt_lat, tgt_lon)
        x_dist = dist * math.cos(angle)
        y_dist = dist * math.sin(angle)
        time_to_intercept = 0.0
        if own_spd > 0.1:
            time_to_intercept = \
                gps.gps_distance(own_lat, own_lon, tgt_lat, tgt_lon) / own_spd
        time_to_intercept = min(time_to_intercept, self.lookahead)
        lead_travel = lead_spd * time_to_intercept
        x_travel = lead_travel * lead_x_dot
        y_travel = lead_travel * lead_y_dot

        # Compute potential values and target waypoint
        x_potential = self._dist_coefficient * x_dist + \
                      self._align_coefficient * lead_x_dot/lead_spd + \
                      self._intercept_coefficient * x_travel
        y_potential = self._dist_coefficient * y_dist + \
                      self._align_coefficient * lead_y_dot/lead_spd + \
                      self._intercept_coefficient * y_travel
        if not wpt:  wpt = brdgmsg.LLA()
        wpt.lat, wpt.lon = \
            gps.gps_newpos(own_lat, own_lon, \
                           math.atan2(y_potential, x_potential), \
                           InterceptCalculator.OVERSHOOT)
        if self._alt_mode == InterceptCalculator.BASE_ALT_MODE:
            wpt.alt = self._alt
        else:
            wpt.alt = lead_uav.state.pose.pose.rel_alt + self._alt
        self._owner.log_dbug("intercept waypoint (lat, lon, alt) = (%f, %f, %f)"
                             %(wpt.lat, wpt.lon, wpt.alt))
        return wpt
예제 #5
0
    def _identify_target(self):
        ''' Determines which red UAV will be targeted
        Will always be the closest red UAV that has not already been shot
        @return the ID (int) of the UAV to target (None if no targets left)
        '''
        t = rospy.Time.now()
        self._target_id = None
        min_range = 1e6
        with self._reds_lock:
            for uav_id in self._reds:
                uav = self._reds[uav_id]
                if uav_id not in self._reds_shot and \
                   (t - uav.state.header.stamp) < GreedyShooter.MAX_TIME_LATE:
                    d = gps.gps_distance(self._own_pose.pose.pose.position.lat, \
                                         self._own_pose.pose.pose.position.lon, \
                                         uav.state.pose.pose.position.lat, \
                                         uav.state.pose.pose.position.lon)
                    if d < min_range:
                        self._target_id = uav_id
                        min_range = d

        if self._target_id == None:
            self.log_info("no targets identified for greedy shooter")
        else:
            self.log_info("greedy shooter identified red UAV %d as target" \
                          %self._target_id)
            self._wp_calc.set_params(self._target_id, 0.0, 0.0, \
                                     self._ap_intent.z, \
                                     pputils.InterceptCalculator.BASE_ALT_MODE)
        return self._target_id
예제 #6
0
    def identify_target(self, t):
        self._target_id = None
        self_pos = self._own_pose.pose.pose.position
        min_range = np.inf

        for uav_id in self._reds:
            red_veh_state = self._reds[uav_id]
            red_pos = red_veh_state.state.pose.pose.position

            shot = uav_id in self._shot
            pursued = uav_id in self.reds_pursued
            active_game = \
                (red_veh_state.game_status == enums.GAME_ACTIVE_DEFENSE or
                 red_veh_state.game_status == enums.GAME_ACTIVE_OFFENSE)
            recent_pose = \
                (t - red_veh_state.state.header.stamp.to_sec() <
                 self.MAX_TIME_LATE.to_sec())

            if not shot and not pursued and recent_pose and active_game:
                d = gps.gps_distance(self_pos.lat, self_pos.lon, red_pos.lat,
                                     red_pos.lon)

                if d < min_range:
                    self._target_id = uav_id
                    self.target_dist = d
                    min_range = d

        if self._target_id:
            self.pursuit_status = True
            self.wp_calc.set_params(self._target_id, 0.0, 0.0, self_pos.alt,
                                    pputils.InterceptCalculator.BASE_ALT_MODE)
            self.pursuit_status_update()
예제 #7
0
    def step_autonomy(self, t, dt):
        # Go to desired latitude, longitude, and maintain altitude
        # deconfliction:

        own_pos = self._own_pose.pose.pose.position
        own_lat = own_pos.lat
        own_lon = own_pos.lon
        own_alt = own_pos.rel_alt
        own_orientation = self._own_pose.pose.pose.orientation

        # Calculate bearing to target and from target to self
        bearing = gps.normalize(
            gps.gps_bearing(own_lat, own_lon, self._desired_lat,
                            self._desired_lon))
        lat = self._desired_lat
        lon = self._desired_lon
        dist = gps.gps_distance(own_lat, own_lon, self._desired_lat,
                                self._desired_lon)
        bearing_adj = 0.0
        if dist > 100:
            bearing_adj = math.pi / 4 * (-1 + self._id % 2 * 2)
            lat, lon = gps.gps_newpos(own_lat, own_lon, bearing + bearing_adj,
                                      1000)
            if bearing_adj > 0:
                print 'ID: {} orbiting CW'.format(self._id)
            else:
                print 'ID: {} orbiting CCW'.format(self._id)

        self._wp = np.array([lat, lon, self._last_ap_wp[2]])

        return True
    def step_autonomy(self, t, dt):

        # Reset the action and target ID every loop
        self._action = ["None", 0]
        self._target_id = None

        # Search for the closest target every frame
        min_dist = np.inf
        for uav in self._reds.values():
            if uav.vehicle_id not in self._shot:
                # print uav.vehicle_id,
                d = gps.gps_distance(self._own_pose.pose.pose.position.lat,\
                                     self._own_pose.pose.pose.position.lon,\
                                     uav.state.pose.pose.position.lat,\
                                     uav.state.pose.pose.position.lon)

                if d < min_dist:
                    min_dist = d
                    self._target_id = uav.vehicle_id
        
        #print self._blues.values()

        # If a target has been identified, move towards it
        if self._target_id != None:
            #print self._reds[self._target_id]
            target_pos = self._reds[self._target_id].state.pose.pose.position
            # s = ", ".join(str(e) for e in self._shot)
            # print "Reds Shot: "
            # print s
            #print "ID: %d   Target ID: %d   Dist: %d" % (self._id, self._target_id, min_dist)
            own_lat = self._own_pose.pose.pose.position.lat
            own_lon = self._own_pose.pose.pose.position.lon
            tgt_lat = target_pos.lat
            tgt_lon = target_pos.lon

            # Set the waypoint past the current target, so we don't go into a
            # loiter mode
            bearing = gps.gps_bearing(own_lat, own_lon, tgt_lat, tgt_lon)
            lat, lon = gps.gps_newpos(own_lat, own_lon, bearing, 1000)

            self._wp = np.array([lat, lon, target_pos.rel_alt])

            # Determine if the target is within firing parameters
            if gps.hitable(self._own_pose.pose.pose.position.lat, \
                           self._own_pose.pose.pose.position.lon, \
                           self._own_pose.pose.pose.position.rel_alt, \
                           (self._own_pose.pose.pose.orientation.x, \
                            self._own_pose.pose.pose.orientation.y, \
                            self._own_pose.pose.pose.orientation.z, \
                            self._own_pose.pose.pose.orientation.w ), \
                           self._max_range, self._fov_width, self._fov_height,\
                           target_pos.lat, target_pos.lon, target_pos.rel_alt):
                self._action = ["Fire", self._target_id]
                #print "=====>ID: %d shot at Target %d" % (self._id, self._target_id)
        else:
            # If a target hasn't been identified, return to the safe waypoint
            self._wp = self._safe_waypoint
        return True
예제 #9
0
    def step_autonomy(self, t, dt):

        # Reset the action and target ID every loop
        self._action = ["None", 0]
        self._target_id = None

        # Search for the closest target every frame
        min_dist = np.inf
        for uav in self._reds.values():
            if uav.vehicle_id not in self._shot and (uav.game_status == enums.GAME_ACTIVE_DEFENSE or uav.game_status == enums.GAME_ACTIVE_OFFENSE):                
                d = gps.gps_distance(self._own_pose.pose.pose.position.lat,\
                                     self._own_pose.pose.pose.position.lon,\
                                     uav.state.pose.pose.position.lat,\
                                     uav.state.pose.pose.position.lon)

                if d < min_dist:
                    min_dist = d
                    self._target_id = uav.vehicle_id

        # If a target has been identified, move towards it
        if self._target_id != None:
            target_pos = self._reds[self._target_id].state.pose.pose.position

            own_lat = self._own_pose.pose.pose.position.lat
            own_lon = self._own_pose.pose.pose.position.lon
            tgt_lat = target_pos.lat
            tgt_lon = target_pos.lon

            lat = tgt_lat
            lon = tgt_lon

            if self._vehicle_type == enums.AC_FIXED_WING:
                # When using fixed wing, Set the waypoint past the current
                # target, so we don't go into a loiter mode
                bearing = gps.gps_bearing(own_lat, own_lon, tgt_lat, tgt_lon)
                lat, lon = gps.gps_newpos(own_lat, own_lon, bearing, 1000)

            self._wp = np.array([lat, lon, target_pos.rel_alt])

            # Determine if the target is within firing parameters
            if gps.hitable(self._own_pose.pose.pose.position.lat, \
                           self._own_pose.pose.pose.position.lon, \
                           self._own_pose.pose.pose.position.rel_alt, \
                           (self._own_pose.pose.pose.orientation.x, \
                            self._own_pose.pose.pose.orientation.y, \
                            self._own_pose.pose.pose.orientation.z, \
                            self._own_pose.pose.pose.orientation.w ), \
                           self._max_range, self._fov_width, self._fov_height,\
                           target_pos.lat, target_pos.lon, target_pos.rel_alt):
                self._action = ["Fire", self._target_id]
        else:
            # If a target hasn't been identified, return to the safe waypoint
            self._wp = self._safe_waypoint

        # Maintain altitude
        self._wp[2] = self._last_ap_wp[2]
            
        return True
    def compute_intercept_waypoint(self, wpt=None):
        ''' Computes an intercept waypoint for the UAV to steer to
        @param wpt: waypoint object to use for computed values
        @return waypoint object (LLA) with the intercept waypoint (or None)
        '''
        lead_uav = self._pre_check()
        if not lead_uav:
            return None

        # Update pursuer and target position and velocity info
        lead_lat, lead_lon = \
            gps.gps_newpos(lead_uav.state.pose.pose.position.lat, \
                           lead_uav.state.pose.pose.position.lon, \
                           self._follow_distance,  self._follow_angle)
        lead_spd = math.hypot(lead_uav.state.twist.twist.linear.x, \
                              lead_uav.state.twist.twist.linear.y)
        lead_crs = math.atan2(lead_uav.state.twist.twist.linear.y, \
                              lead_uav.state.twist.twist.linear.x)
        own_lat = self.own_pose.pose.pose.position.lat
        own_lon = self.own_pose.pose.pose.position.lon
        own_spd = math.hypot(self.own_pose.twist.twist.linear.x, \
                             self.own_pose.twist.twist.linear.y)
        if (own_spd - lead_spd) < 1.0: own_spd = lead_spd + 1.0
        own_crs = math.atan2(self.own_pose.twist.twist.linear.y, \
                             self.own_pose.twist.twist.linear.x)

        # Compute the control parameters
        self._theta = gps.gps_bearing(own_lat, own_lon, lead_lat, lead_lon)
        tgt_distance = gps.gps_distance(own_lat, own_lon, lead_lat, lead_lon)
        crossing_spd = own_spd * math.sin(self._theta - own_crs) + \
                       lead_spd * math.sin(self._theta + math.pi - lead_crs)
        self._theta_dot = crossing_spd / tgt_distance
        theta_diff = gps.normalize_pi(self._theta - own_crs)
        self._bias = min(gps.signum(theta_diff) * 2.5, theta_diff / 10.0)

        # Use the PN calculation to compute the ordered acceleration
        ordered_a = (self._gain * self._theta_dot + self._bias) * own_spd
        a_max = min(self._a_max, ((2.0 * math.pow(own_spd, 2.0)) / self._L1))
        if math.fabs(ordered_a) > a_max:
            ordered_a = gps.signum(ordered_a) * a_max
        nu = math.asin((ordered_a * self._L1) / (2.0 * math.pow(own_spd, 2.0)))

        # Compute the waypoint command
        if not wpt: wpt = brdgmsg.LLA()
        wpt.lat, wpt.lon = \
            gps.gps_newpos(lead_lat, lead_lon, nu + own_crs, self._L1)

        if self._alt_mode == InterceptCalculator.BASE_ALT_MODE:
            wpt.alt = self._alt
        else:
            wpt.alt = lead_uav.state.pose.pose.rel_alt + self._alt
        self._owner.log_dbug(
            "intercept waypoint (lat, lon, alt) = (%f, %f, %f)" %
            (wpt.lat, wpt.lon, wpt.alt))
        return wpt
    def compute_intercept_waypoint(self, wpt=None):
        ''' Computes an intercept waypoint for the UAV to steer to
        @param wpt: waypoint object to use for computed values
        @return waypoint object (LLA) with the intercept waypoint (or None)
        '''
        lead_uav = self._pre_check()
        if not lead_uav:
            return None

        # Update pursuer and target position and velocity info
        lead_lat, lead_lon = \
            gps.gps_newpos(lead_uav.state.pose.pose.position.lat, \
                           lead_uav.state.pose.pose.position.lon, \
                           self._follow_distance,  self._follow_angle)
        lead_spd = math.hypot(lead_uav.state.twist.twist.linear.x, \
                              lead_uav.state.twist.twist.linear.y)
        lead_crs = math.atan2(lead_uav.state.twist.twist.linear.y, \
                              lead_uav.state.twist.twist.linear.x)
        own_lat = self.own_pose.pose.pose.position.lat
        own_lon = self.own_pose.pose.pose.position.lon
        own_spd = math.hypot(self.own_pose.twist.twist.linear.x, \
                             self.own_pose.twist.twist.linear.y)
        if (own_spd - lead_spd) < 1.0: own_spd = lead_spd + 1.0
        own_crs = math.atan2(self.own_pose.twist.twist.linear.y, \
                             self.own_pose.twist.twist.linear.x)

        # Compute the control parameters
        self._theta = gps.gps_bearing(own_lat, own_lon, lead_lat, lead_lon)
        tgt_distance = gps.gps_distance(own_lat, own_lon, lead_lat, lead_lon)
        crossing_spd = own_spd * math.sin(self._theta - own_crs) + \
                       lead_spd * math.sin(self._theta + math.pi - lead_crs)
        self._theta_dot = crossing_spd / tgt_distance
        theta_diff = gps.normalize_pi(self._theta - own_crs)
        self._bias = min(gps.signum(theta_diff) * 2.5, theta_diff / 10.0)

        # Use the PN calculation to compute the ordered acceleration
        ordered_a = (self._gain * self._theta_dot + self._bias) * own_spd
        a_max = min(self._a_max, ((2.0 * math.pow(own_spd, 2.0)) / self._L1))
        if math.fabs(ordered_a) > a_max:
            ordered_a = gps.signum(ordered_a) * a_max
        nu = math.asin((ordered_a * self._L1) / (2.0 * math.pow(own_spd, 2.0)))

        # Compute the waypoint command
        if not wpt:  wpt = brdgmsg.LLA()
        wpt.lat, wpt.lon = \
            gps.gps_newpos(lead_lat, lead_lon, nu + own_crs, self._L1)

        if self._alt_mode == InterceptCalculator.BASE_ALT_MODE:
            wpt.alt = self._alt
        else:
            wpt.alt = lead_uav.state.pose.pose.rel_alt + self._alt
        self._owner.log_dbug("intercept waypoint (lat, lon, alt) = (%f, %f, %f)"
                             %(wpt.lat, wpt.lon, wpt.alt))
        return wpt
    def compute_intercept_waypoint(self, wpt=None):
        ''' Computes an intercept waypoint for the UAV to steer to
        @param wpt: waypoint object to use for computed values
        @return waypoint object (LLA) with the intercept waypoint (or None)
        '''
        lead_uav = self._pre_check()
        if not lead_uav:
            return None

        # Grab & compute required own & leader state info
        own_lat = self.own_pose.pose.pose.position.lat
        own_lon = self.own_pose.pose.pose.position.lon
        own_crs = math.atan2(self.own_pose.twist.twist.linear.y, \
                             self.own_pose.twist.twist.linear.x)
        own_spd = math.hypot(self.own_pose.twist.twist.linear.x, \
                             self.own_pose.twist.twist.linear.y)

        lead_lat = lead_uav.state.pose.pose.position.lat
        lead_lon = lead_uav.state.pose.pose.position.lon
        lead_alt = lead_uav.state.pose.pose.position.rel_alt
        lead_crs = math.atan2(lead_uav.state.twist.twist.linear.y, \
                              lead_uav.state.twist.twist.linear.x)
        lead_spd = math.hypot(lead_uav.state.twist.twist.linear.x, \
                              lead_uav.state.twist.twist.linear.y)

        # Compute tgt point & project it forward to intercept + l1_distance
        tgt_lat, tgt_lon = gps.gps_newpos(lead_lat, lead_lon, \
                                          (lead_crs + self._follow_angle), \
                                          self._follow_distance)
        time_to_intercept = 0.0
        if own_spd > 0.1:
            time_to_intercept = \
                gps.gps_distance(own_lat, own_lon, tgt_lat, tgt_lon) / own_spd
        time_to_intercept = min(time_to_intercept, self.lookahead)
        tgt_travel = (lead_spd * time_to_intercept) + self.l1_distance
        tgt_lat, tgt_lon = \
            gps.gps_newpos(tgt_lat, tgt_lon, lead_crs, tgt_travel)

        # compute a wpt along the line from the current posit to the intercept
        if not wpt: wpt = brdgmsg.LLA()
        to_tgt = gps.gps_bearing(own_lat, own_lon, tgt_lat, tgt_lon)
        wpt.lat, wpt.lon = \
            gps.gps_newpos(own_lat, own_lon, to_tgt, InterceptCalculator.OVERSHOOT)
        if self._alt_mode == InterceptCalculator.BASE_ALT_MODE:
            wpt.alt = self._alt
        else:
            wpt.alt = lead_uav.state.pose.pose.rel_alt + self._alt
        self._owner.log_dbug(
            "intercept waypoint (lat, lon, alt) = (%f, %f, %f)" %
            (wpt.lat, wpt.lon, wpt.alt))
        return wpt
    def compute_intercept_waypoint(self, wpt=None):
        ''' Computes an intercept waypoint for the UAV to steer to
        @param wpt: waypoint object to use for computed values
        @return waypoint object (LLA) with the intercept waypoint (or None)
        '''
        lead_uav = self._pre_check()
        if not lead_uav:
            return None

        # Grab & compute required own & leader state info
        own_lat = self.own_pose.pose.pose.position.lat
        own_lon = self.own_pose.pose.pose.position.lon
        own_crs = math.atan2(self.own_pose.twist.twist.linear.y, \
                             self.own_pose.twist.twist.linear.x)
        own_spd = math.hypot(self.own_pose.twist.twist.linear.x, \
                             self.own_pose.twist.twist.linear.y)

        lead_lat = lead_uav.state.pose.pose.position.lat
        lead_lon = lead_uav.state.pose.pose.position.lon
        lead_alt = lead_uav.state.pose.pose.position.rel_alt
        lead_crs = math.atan2(lead_uav.state.twist.twist.linear.y, \
                              lead_uav.state.twist.twist.linear.x)
        lead_spd = math.hypot(lead_uav.state.twist.twist.linear.x, \
                              lead_uav.state.twist.twist.linear.y)

        # Compute tgt point & project it forward to intercept + l1_distance
        tgt_lat, tgt_lon = gps.gps_newpos(lead_lat, lead_lon, \
                                          (lead_crs + self._follow_angle), \
                                          self._follow_distance)
        time_to_intercept = 0.0
        if own_spd > 0.1:
            time_to_intercept = \
                gps.gps_distance(own_lat, own_lon, tgt_lat, tgt_lon) / own_spd
        time_to_intercept = min(time_to_intercept, self.lookahead)
        tgt_travel = (lead_spd * time_to_intercept) + self.l1_distance
        tgt_lat, tgt_lon = \
            gps.gps_newpos(tgt_lat, tgt_lon, lead_crs, tgt_travel)

        # compute a wpt along the line from the current posit to the intercept
        if not wpt: wpt = brdgmsg.LLA()
        to_tgt = gps.gps_bearing(own_lat, own_lon, tgt_lat, tgt_lon)
        wpt.lat, wpt.lon = \
            gps.gps_newpos(own_lat, own_lon, to_tgt, InterceptCalculator.OVERSHOOT)
        if self._alt_mode == InterceptCalculator.BASE_ALT_MODE:
            wpt.alt = self._alt
        else:
            wpt.alt = lead_uav.state.pose.pose.rel_alt + self._alt
        self._owner.log_dbug("intercept waypoint (lat, lon, alt) = (%f, %f, %f)"
                             %(wpt.lat, wpt.lon, wpt.alt))
        return wpt
예제 #14
0
    def closestCorners(self):
        order = []
        uav_lat = self._own_pose.pose.pose.position.lat
        uav_lon = self._own_pose.pose.pose.position.lon
        for corner in self._safe_corners:
            if order == []:
                order.append(corner)
            else:
                index = 0
                inserted = False
                for otherCorner in order:
                    if not inserted and gps.gps_distance(
                            uav_lat, uav_lon, corner[0],
                            corner[1]) < gps.gps_distance(
                                uav_lat, uav_lon, otherCorner[0],
                                otherCorner[1]):
                        order.insert(index, corner)
                        inserted = True
                    index += 1

                if inserted == False:
                    order.append(corner)
        return order
예제 #15
0
 def _set_ctrl_params(self, own_state, own_vel, tgt_state, tgt_vel):
     ''' Sets the control parameter values based on own and target state
         @param own_state:  pursuer vehicle state (lat, lon, psi)
         @param own_vel:  pursuer velocity (x_dot, y_dot)
         @param tgt_state:  target vehicle state (lat, lon, psi)
         @param tgt_vel:  target velocity (x_dot, y_dot)            
     '''
     self._range = gps.gps_distance(own_state[0], own_state[1], \
                                    tgt_state[0], tgt_state[1])
     self._theta = gps.gps_bearing(own_state[0], own_state[1], \
                                   tgt_state[0], tgt_state[1])
     own_spd = math.hypot(own_vel[0], own_vel[1])
     tgt_spd = math.hypot(tgt_vel[0], tgt_vel[1])
     crossing_spd = own_spd * math.sin(self._theta - own_state[2]) + \
                    tgt_spd * math.sin(self._theta + math.pi - tgt_state[2])
     self._theta_dot = crossing_spd / self._range
예제 #16
0
 def _set_ctrl_params(self, own_state, own_vel, tgt_state, tgt_vel):
     ''' Sets the control parameter values based on own and target state
         @param own_state:  pursuer vehicle state (lat, lon, psi)
         @param own_vel:  pursuer velocity (x_dot, y_dot)
         @param tgt_state:  target vehicle state (lat, lon, psi)
         @param tgt_vel:  target velocity (x_dot, y_dot)            
     '''
     self._range = gps.gps_distance(own_state[0], own_state[1], \
                                    tgt_state[0], tgt_state[1])
     self._theta = gps.gps_bearing(own_state[0], own_state[1], \
                                   tgt_state[0], tgt_state[1])
     own_spd = math.hypot(own_vel[0], own_vel[1])
     tgt_spd = math.hypot(tgt_vel[0], tgt_vel[1])
     crossing_spd = own_spd * math.sin(self._theta - own_state[2]) + \
                    tgt_spd * math.sin(self._theta + math.pi - tgt_state[2])
     self._theta_dot = crossing_spd / self._range
예제 #17
0
    def step_autonomy(self, t, dt):                

        # remove any red entries in sorter
        to_del = [key for key in self.sorter._data if key in self._reds]
        for key in to_del:
            del self.sorter._data[key]

        self.sorter.send_requested(t)

        self.wp_calc._swarm = self._blues

        self.sorter._subswarm = set(self.wp_calc._swarm.keys())

        if self.behavior_state == States.setup:
            self._wp = self._safe_waypoint
            if not self.setup_formation(t):
                return True

            self.behavior_state = States.fly

        else:
            
            if self.formation_params['lead']:

                pos = self._own_pose.pose.pose.position
                if gps.gps_distance(pos.lat, pos.lon, self._wp[0], self._wp[1]) < 2 * self.cube_offset:
                    print 'selecting a new waypoint'
                    self.curr_corner = (self.curr_corner + 1) % 4

                wp = self.geobox._corners[self.curr_corner]
                self._wp = np.array([wp[0], wp[1], self._wp[2]])

            elif not self.formation_params['lead']:
                wp = self.wp_calc.compute_intercept_waypoint(None, t)
                if wp is None:
                    self.log_warn("calculated a None waypoint to leader in LinearFormation")
                else: 
                    self._wp = np.array([wp.lat, wp.lon, wp.alt])

        return True
예제 #18
0
    def step_autonomy(self, t, dt):
        # Go to desired latitude, longitude, and maintain altitude
        # deconfliction:
       
        d = gps.gps_distance(self._own_pose.pose.pose.position.lat, self._own_pose.pose.pose.position.lon, self._desired_lat, self._desired_lon)

        if d < self._wp_dist:
            if self._step < 3:
                if (self._loc[self._step + 1]) in range(0,16): # wp 0-15
                    self._step += 1
                elif (self._loc[self._step + 1]) < 0:  # -1
                    self._step = 0
                elif (self._loc[self._step + 1]) > 16:
                    pass        # stay at current waypoint forever
            else:
                self._step = 0  # go back to beginning
        
        self._desired_lat = float(usma_enums.WP_LOC[self._loc[self._step]][0])
        self._desired_lon = float(usma_enums.WP_LOC[self._loc[self._step]][1])

        self._wp = np.array([self._desired_lat, self._desired_lon, self._last_ap_wp[2]])

        return True
예제 #19
0
    def step_autonomy(self, t, dt):

        # Reset the action and target ID every loop
        self._action = ["None", 0]

        # Search for the closest target every frame
        for uav in self._reds.values():
            if uav.vehicle_id not in self._shot:
                # Calculate target and own position and orientation
                target_pos = self._reds[uav.vehicle_id].state.pose.pose.position
                target_orientation = self._reds[uav.vehicle_id].state.pose.pose.orientation
                tgt_lat = target_pos.lat
                tgt_lon = target_pos.lon
                tgt_alt = target_pos.rel_alt

                if self._bboxes[0].contains(tgt_lat, tgt_lon, tgt_alt): # added to only consider those in battlebox
                    own_pos = self._own_pose.pose.pose.position
                    own_lat = own_pos.lat
                    own_lon = own_pos.lon
                    own_alt = own_pos.rel_alt
                    own_orientation = self._own_pose.pose.pose.orientation

                    # Calculate bearing to target and from target to self
                    bearing = gps.normalize(gps.gps_bearing(own_lat, own_lon, tgt_lat, tgt_lon))
                    tgt_bearing = gps.normalize(gps.gps_bearing(tgt_lat, tgt_lon, own_lat, own_lon))

                    # Calculate heading/yaw of self and target
                    own_rpy = qmath.quat_to_euler((own_orientation.x,\
                                           own_orientation.y, \
                                           own_orientation.z, \
                                           own_orientation.w))
                    own_heading = gps.normalize(own_rpy[2])

                    tgt_rpy = qmath.quat_to_euler((target_orientation.x,\
                                           target_orientation.y, \
                                           target_orientation.z, \
                                           target_orientation.w))
                    tgt_heading = gps.normalize(tgt_rpy[2])

                    # Calculate distance to target
                    dist = gps.gps_distance(own_lat, own_lon, tgt_lat, tgt_lon)
                    
                    bearing_adj = 0.0

                    # Calculate offset between bearing and target heading (measures degree of "head on")
                    # ----------------------------------------------------------------------------
                    heading_diff = own_heading - tgt_heading
                    tgt_bearing_diff = gps.normalize_pi( tgt_heading - tgt_bearing )
                    if math.fabs(heading_diff) > math.pi/2:
                        # moving towards each other
                        if tgt_bearing > (tgt_heading - self._fov_width_radians/2) or tgt_bearing < (tgt_heading + self._fov_width_radians/2):
                            # we are in the "fan"
                            if dist > 2*self._max_range and math.fabs(tgt_bearing_diff) < self._fov_width_radians/2:                
                                bearing_adj = math.copysign(ADJ_ANGLE, tgt_bearing_diff)
                                #print 'ID: {} toward UAV: {}: adjusting bearing by {}'.format(self._id, uav.vehicle_id, math.degrees(bearing_adj))
                            elif dist < self._max_range and math.fabs(tgt_bearing_diff) > self._fov_width_radians*3:
                                # along side each other
                                bearing_adj = math.copysign(3*ADJ_ANGLE, tgt_bearing_diff)
                                #print 'ID: {} along side UAV: {}: adjusting bearing by {}'.format(self._id, uav.vehicle_id, math.degrees(bearing_adj))
                    else:
                        # heading in same general direction
                        if math.fabs(tgt_bearing_diff) < math.pi/2:
                            # I am in front of target
                            if dist < 2*self._max_range and math.fabs(tgt_bearing_diff) < self._fov_width_radians/2:                      
                                bearing_adj = -math.copysign(ADJ_ANGLE, tgt_bearing_diff)
                                #print 'ID: {} away from UAV: {} adjusting bearing by {}'.format(self._id, uav.vehicle_id, math.degrees(bearing_adj))
                    # ----------------------------------------------------------------------------
                    lat, lon = gps.gps_newpos(own_lat, own_lon, bearing + bearing_adj, 1000)
                    self._wp = np.array([lat, lon, own_alt])    # keep own alt

                    # Determine if the target is within firing parameters
                    if gps.hitable(own_lat, own_lon, own_alt, \
                                   (own_orientation.x, \
                                    own_orientation.y, \
                                    own_orientation.z, \
                                    own_orientation.w ), \
                                   self._max_range, self._fov_width, self._fov_height,\
                                   tgt_lat, tgt_lon, tgt_alt):
                        self._action = ["Fire", uav.vehicle_id]
                        print "EA=======================>ID: %d shot at Target %d" % (self._id, uav.vehicle_id)

        return True
예제 #20
0
    def step_autonomy(self, t, dt):

        # Reset the action and target ID every loop
        self._action = ["None", 0]

        msg = apmsg.MsgStat()
        msg.id = self._id

        ############################################################
        # If self._target_id is not None and in the shot group
        # then reset to None, otherwise set to last_target
        ############################################################

        min_dist = self._target_dist
        for uav in self._reds.values():
            if uav.vehicle_id not in self._shot:
                if uav.vehicle_id not in self._taken:
                    uav_lat = uav.state.pose.pose.position.lat
                    uav_lon = uav.state.pose.pose.position.lon
                    uav_alt = uav.state.pose.pose.position.rel_alt
                    d = gps.gps_distance(self._own_pose.pose.pose.position.lat,\
                                     self._own_pose.pose.pose.position.lon,\
                                     uav_lat, uav_lon)

                    if d < min_dist:
                        min_dist = d
                        self._target_id = uav.vehicle_id
                        self._target_range = d

        if self._target_id in self._shot:
            self._target_id = None
            self._target_dist = np.inf
            self._target_count = 0
            self._target_last_lat = None
            self._target_last_lon = None
            self._target_heading = None
            self._target_speed = None

        # If a target has been identified, move towards it
        if self._target_id != None:
            msg.count = self._target_id
            msg.latency = self._target_range
            self.pubs['my_topic'].publish(msg)
            print '{} targeting UAV {} at a distance of {}'.format(
                self._id, msg.count, msg.latency)
            print '{} has taken list of {}'.format(self._id, self._taken)

            own_lat = self._own_pose.pose.pose.position.lat
            own_lon = self._own_pose.pose.pose.position.lon

            if self._last_lat is not None:
                self._speed = gps.gps_distance(own_lat, own_lon,\
                                     self._last_lat, self._last_lon) / 0.1
                self._heading = gps.gps_bearing(self._last_lat, self._last_lon,
                                                own_lat, own_lon)

            self._last_lat = own_lat
            self._last_lon = own_lon

            target_pos = self._reds[self._target_id].state.pose.pose.position
            tgt_lat = target_pos.lat
            tgt_lon = target_pos.lon
            tgt_alt = target_pos.rel_alt

            d = gps.gps_distance(self._own_pose.pose.pose.position.lat,\
                                     self._own_pose.pose.pose.position.lon,\
                                     tgt_lat, tgt_lon)

            if self._target_last_lat is not None:
                self._target_speed = gps.gps_distance(tgt_lat, tgt_lon,\
                                     self._target_last_lat, self._target_last_lon) / 0.1
                self._target_heading = gps.gps_bearing(self._target_last_lat,
                                                       self._target_last_lon,
                                                       tgt_lat, tgt_lon)
                #print "ID: %d   Target: %d" % (self._id, self._target_id)
                #print "Lat: %f  Lon: %f  Head: %f   T_lat: %f  T_lon %f  T_head: %f" % (own_lat, own_lon, self._heading, \
                #tgt_lat, tgt_lon, self._target_heading)

            self._target_last_lat = tgt_lat
            self._target_last_lon = tgt_lon

            #############################################################################
            # Calc intercept point
            # Reference:  http://jaran.de/goodbits/2011/07/17/calculating-an-intercept-course-to-a-target-with-constant-direction-and-velocity-in-a-2-dimensional-plane/
            # Translated from Java to Python
            #############################################################################
            t = None
            if self._target_heading is not None:
                s = self._speed
                ox = tgt_lat - own_lat
                oy = tgt_lon - own_lon
                vx = self._target_speed * math.cos(self._target_heading)  # sin
                vy = self._target_speed * math.sin(self._target_heading)  # cos
                h1 = vx**2 + vy**2 - s**2
                h2 = ox * vx + oy * vy

                if h1 == 0:
                    t = -(ox**2 + oy**2) / (2 * h2)
                else:
                    minusPHalf = -h2 / h1
                    disc = minusPHalf**2 - (ox**2 + oy**2) / h1
                    if disc < 0:
                        t = None
                    else:
                        root = math.sqrt(disc)
                        t1 = minusPHalf + root
                        t2 = minusPHalf - root
                        tmin = t1 if t1 < t2 else t2
                        tmax = t1 if t1 > t2 else t2

                        t = tmin if tmin > 0 else tmax

                        if t < 0 or d < self._max_range:  # close enough so go right to him (switch to greedy shooter)
                            t = None
                        else:
                            t *= 1.53

            if t is not None:
                int_lat = tgt_lat + vx * t
                int_lon = tgt_lon + vy * t
                int_dist = gps.gps_distance(own_lat, own_lon, int_lat, int_lon)
                bearing = gps.gps_bearing(own_lat, own_lon, int_lat, int_lon)
                lat, lon = gps.gps_newpos(own_lat, own_lon, bearing, int_dist)
                #print "ID: %d using intercept bearing %f to Lat: %f  Lon: %f  Dist: %f  Time: %f" % (self._id, bearing, lat, lon, int_dist, t*10000)  #  I_lat: %f  I_lon: %f  t: %f
            else:
                bearing = gps.gps_bearing(own_lat, own_lon, tgt_lat, tgt_lon)
                dist = gps.gps_distance(own_lat, own_lon, tgt_lat, tgt_lon)
                lat, lon = gps.gps_newpos(own_lat, own_lon, bearing,
                                          dist + 250)  # range was 1000
                #print "ID: %d using direct bearing %f to Lat: %f  Lon: %f  Dist: %f" % (self._id, bearing, lat, lon, dist)

            # Set the waypoint past the current target, so we don't go into a loiter mode

            self._wp = np.array([lat, lon, tgt_alt])

            # Determine if the target is within firing parameters
            if gps.hitable(self._own_pose.pose.pose.position.lat, \
                           self._own_pose.pose.pose.position.lon, \
                           self._own_pose.pose.pose.position.rel_alt, \
                           (self._own_pose.pose.pose.orientation.x, \
                            self._own_pose.pose.pose.orientation.y, \
                            self._own_pose.pose.pose.orientation.z, \
                            self._own_pose.pose.pose.orientation.w ), \
                           self._max_range, self._fov_width, self._fov_height,\
                           tgt_lat, tgt_lon, tgt_alt):
                self._action = ["Fire", self._target_id]
                #print "GS Int=============================>ID: %d shot at Target %d" % (self._id, self._target_id)

        else:
            # If a target hasn't been identified, return to the safe waypoint
            self._wp = self._safe_waypoint
        self._taken.clear(
        )  # clear the taken list in case it's full of old data
        return True
예제 #21
0
    def step_autonomy(self, t, dt):
        # Execute this portion of the code on the loop only
        if self._first_tick == True:
            self._first_tick = False

            # Set initial altitude settings
            self._desired_alt = self._last_ap_wp[2]
            self._original_alt = self._last_ap_wp[2]

            # Determine your own subswarm ID
            #key     #value
            for blue_id, blue in self._blues.iteritems():
                print "vehicle id = ", blue.vehicle_id, "self._id = ", self._id
                if blue.vehicle_id == self._id:
                    self._subswarm_id = blue.subswarm_id
                    break
            print "subswarm_id: ", self._subswarm_id

            # Build a list of all vehicle IDs within your subswarm
            # produces the list (and therefore number) of specific swarm
            blue_in_subswarm = dict()
            i = 0
            for blue_id, blue in self._blues.iteritems():
                if blue.subswarm_id == self._subswarm_id:
                    self._id_in_subswarm.append(blue.vehicle_id)
                    self._subswarm_num_to_assign.append(0)
                    blue_in_subswarm[i] = blue
                    i = i + 1
            print "id_in_subswarm: ", self._id_in_subswarm

            # Divide # of lanes by # of vehicles and create empty bundle of lanes for each
            num_in_subwarm = len(
                self._id_in_subswarm)  # in our case 5 vehicles
            for i in range(0, num_in_subwarm):
                self._subswarm_num_to_assign[i] = int(
                    math.floor(len(self.lanes) / num_in_subwarm))
                if i < (len(self.lanes) % num_in_subwarm):
                    self._subswarm_num_to_assign[
                        i] = self._subswarm_num_to_assign[i] + 1
            print "num_to_assign: ", self._subswarm_num_to_assign  #should be 2

            # Logic for assigning lanes and movement of subswarm
            # Loop over each UAS in subswarm.
            for i in range(0, num_in_subwarm):  #from 0 to 5
                # Set the start location to current UAS position
                place_in_lane = 0
                if i > 0:
                    place_in_lane += self._subswarm_num_to_assign[i - 1]

                temp_lat = blue_in_subswarm[i].state.pose.pose.position.lat
                temp_lon = blue_in_subswarm[i].state.pose.pose.position.lon
                assignment_list = []
                # Loop over each element of the lanes bundle
                for j in range(0, self._subswarm_num_to_assign[i]
                               ):  #self._sub_num_to_assign[0] = 6
                    # Loop over each end of lane defined in the mission
                    if i > 0:
                        for k in self.lanes[j + place_in_lane]:
                            coord_to_assign = k
                            assignment_list.append(coord_to_assign)
                            self._subswarm_wp_assignment[i] = assignment_list
                    else:
                        for k in self.lanes[j]:  #looking at both
                            #coordinates in a single lane--should be 2
                            coord_to_assign = k  #full coordinate
                            assignment_list.append(coord_to_assign)
                            self._subswarm_wp_assignment[i] = assignment_list

                #print "list for drone: ",i, ": ", self._subswarm_wp_assignment[i], "\n"
                # Assign yourself your own bundle of lanes
                print "vehicle id: ", blue_in_subswarm[
                    i].vehicle_id, "self._id: ", self._id
                #if blue_in_subswarm[i].vehicle_id == self._id:
                if self._id == blue_in_subswarm[i].vehicle_id:
                    self._wp_id_list = self._subswarm_wp_assignment[i]
                    #print "vehicle id: ", self._id, " waypoints: ", self._subswarm_wp_assignment[i]
                    print "it has reached this point"
                    #self._loc = self._wp_id_list[self._wp_id_list_id]

            print "way point id list :", self._wp_id_list
            # Proceed to the first Waypoint in the bundle
            self._loc = self._wp_id_list[0]
            self._desired_lat = float([self._loc][0][0])
            self._desired_lon = float([self._loc][0][1])

            print "subswarm_wp_assignment: ", self._subswarm_wp_assignment, "\n"
            # Proceed to the first coordinate in the lanes bundle

            print "Going to coordinate: ", self._loc
            # Go to desired latitude, longitude, and maintain altitude
            # deconfliction:
            self._wp = np.array(
                [self._desired_lat, self._desired_lon, self._desired_alt])

        # Determine current position
        pos = self._own_pose.pose.pose.position
        dist = gps.gps_distance(pos.lat, pos.lon, self._desired_lat,
                                self._desired_lon)

        #if close enough to a hotspot (using hotspot threshold as test), send info to one drone on standby
        #call hotspot_identified function

        if (self._vehicle_type == 2
                and dist < DIST2WP_ZEPH) or (self._vehicle_type == 1
                                             and dist < DIST2WP_QUAD):
            if self._at_wp == False:
                self._time_start = timeit.default_timer()
            self._at_wp = True
            self._time_at_wp = timeit.default_timer() - self._time_start
        else:
            self._at_wp = False
            self._time_at_wp = 0

        # If you reach your point, proceed to the next one
        if self._at_wp == True:
            self._wp_id_list_id = self._wp_id_list_id + 1
            # If you get to the end of your bundle, repeat from its beginning
            # and reset to original altitude
            if self._wp_id_list_id > (len(self._wp_id_list) - 1):
                print("test")
                self._wp_id_list_id = 0
                self._desired_alt = self._original_alt
            self._loc = self._wp_id_list[self._wp_id_list_id]
            self._desired_lat = float(self._loc[0])
            self._desired_lon = float(self._loc[1])
            # Reset these so that UAV knows it's no longer at its goal WP
            self._at_wp = False
            print "Going to coordinate: ", self._loc
            self._wp = np.array(
                [self._desired_lat, self._desired_lon, self._desired_alt])

        return True
예제 #22
0
    def step_autonomy(self, t, dt):

        # Reset the action and target ID every loop
        self._action = ["None", 0]
        self._target_id = None

        # Search for the closest target every frame
        min_dist = np.inf
        for uav in self._reds.values():
            if uav.vehicle_id not in self._shot:
                d = gps.gps_distance(self._own_pose.pose.pose.position.lat,\
                                     self._own_pose.pose.pose.position.lon,\
                                     uav.state.pose.pose.position.lat,\
                                     uav.state.pose.pose.position.lon)

                if d < min_dist:
                    min_dist = d
                    self._target_id = uav.vehicle_id

                # Determine if the target is within firing parameters
                if gps.hitable(self._own_pose.pose.pose.position.lat, \
                               self._own_pose.pose.pose.position.lon, \
                               self._own_pose.pose.pose.position.rel_alt, \
                               (self._own_pose.pose.pose.orientation.x, \
                                self._own_pose.pose.pose.orientation.y, \
                                self._own_pose.pose.pose.orientation.z, \
                                self._own_pose.pose.pose.orientation.w ), \
                               self._max_range, self._fov_width, self._fov_height,\
                               uav.state.pose.pose.position.lat,\
                               uav.state.pose.pose.position.lon, \
                               uav.state.pose.pose.position.rel_alt):
                    self._action = ["Fire", uav.vehicle_id]
                    print "RT=========(loop)========>ID: %d shot at Target %d" % (
                        self._id, uav.vehicle_id)
        '''if self._last_target_id == self._target_id:
            if d < 100:  # how close do we have to be before I call chasing
                self._target_count += 1
                if self._target_count > 100:
                    self._target_count = 300
                    self._target_id = None
        elif self._target_count > 0:
            self._target_count -= 1
            self._target_id = None
        '''
        # If a target has been identified, move towards it
        if self._target_id != None:
            self._last_target_id = self._target_id

            # Calculate target and own position and orientation
            target_pos = self._reds[self._target_id].state.pose.pose.position
            target_orientation = self._reds[
                self._target_id].state.pose.pose.orientation
            tgt_lat = target_pos.lat
            tgt_lon = target_pos.lon
            tgt_alt = target_pos.rel_alt

            own_pos = self._own_pose.pose.pose.position
            own_lat = own_pos.lat
            own_lon = own_pos.lon
            own_alt = own_pos.rel_alt
            own_orientation = self._own_pose.pose.pose.orientation

            # Calculate bearing to target and from target to self
            bearing = gps.normalize(
                gps.gps_bearing(own_lat, own_lon, tgt_lat, tgt_lon))
            tgt_bearing = gps.normalize(
                gps.gps_bearing(tgt_lat, tgt_lon, own_lat, own_lon))

            # Calculate heading/yaw of self and target
            own_rpy = qmath.quat_to_euler((own_orientation.x,\
                                   own_orientation.y, \
                                   own_orientation.z, \
                                   own_orientation.w))
            own_heading = gps.normalize(own_rpy[2])

            tgt_rpy = qmath.quat_to_euler((target_orientation.x,\
                                   target_orientation.y, \
                                   target_orientation.z, \
                                   target_orientation.w))
            tgt_heading = gps.normalize(tgt_rpy[2])

            # Calculate distance to target
            dist = gps.gps_distance(own_lat, own_lon, tgt_lat, tgt_lon)

            bearing_adj = 0.0
            #print 'ID: {} targeting UAV: {} at bearing {} and distance {}'.format(self._id, self._target_id, math.degrees(bearing), dist)
            #print 'UAV: {} own bearing: {}'.format(self._target_id, math.degrees(tgt_heading))

            # Calculate offset between bearing and target heading (measures degree of "head on")
            # This section needs more work
            # ----------------------------------------------------------------------------
            heading_diff = own_heading - tgt_heading
            tgt_bearing_diff = gps.normalize_pi(tgt_heading - tgt_bearing)
            if math.fabs(heading_diff) > math.pi / 2:
                # moving towards each other
                if tgt_bearing > (
                        tgt_heading - self._fov_width_radians / 2
                ) or tgt_bearing < (tgt_heading + self._fov_width_radians / 2):
                    # we are in the "fan"
                    if dist > self._max_range and math.fabs(
                            tgt_bearing_diff) < self._fov_width_radians / 2:
                        bearing_adj = math.copysign(ADJ_ANGLE,
                                                    tgt_bearing_diff)
                        print 'ID: {} toward UAV: {}: adjusting bearing by {}'.format(
                            self._id, self._target_id,
                            math.degrees(bearing_adj))
            else:
                # heading in same general direction
                if math.fabs(tgt_bearing_diff) < math.pi / 2:
                    # I am in front of target
                    if dist < 2 * self._max_range and math.fabs(
                            tgt_bearing_diff) < self._fov_width_radians / 2:
                        bearing_adj = -math.copysign(ADJ_ANGLE,
                                                     tgt_bearing_diff)
                        print 'ID: {} away from UAV: {} adjusting bearing by {}'.format(
                            self._id, self._target_id,
                            math.degrees(bearing_adj))
            # ----------------------------------------------------------------------------
            lat, lon = gps.gps_newpos(own_lat, own_lon, bearing + bearing_adj,
                                      1000)
            self._wp = np.array([lat, lon, own_alt])  # keep own alt

            # Determine if the target is within firing parameters
            if gps.hitable(self._own_pose.pose.pose.position.lat, \
                           self._own_pose.pose.pose.position.lon, \
                           self._own_pose.pose.pose.position.rel_alt, \
                           (self._own_pose.pose.pose.orientation.x, \
                            self._own_pose.pose.pose.orientation.y, \
                            self._own_pose.pose.pose.orientation.z, \
                            self._own_pose.pose.pose.orientation.w ), \
                           self._max_range, self._fov_width, self._fov_height,\
                           target_pos.lat, target_pos.lon, target_pos.rel_alt):
                self._action = ["Fire", self._target_id]
                print "RT=======================>ID: %d shot at Target %d" % (
                    self._id, self._target_id)
        else:
            # If a target hasn't been identified, return to the safe waypoint
            self._wp = self._safe_waypoint
        return True
예제 #23
0
    def step_autonomy(self, t, dt):
        # Execute this portion of the code on the loop only
        if self._first_tick == True:
            raddir = self.radeyeDir + 'radeye.py'
            subprocess.Popen(["python",
                              raddir])  # Runs Radeye in the background

            self._first_tick = False
            finishedset = set([])
            #create a TCP/IP socket
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            serverflag = 1
            if (SERVER_FLAG == 1):
                server_address = ('192.168.11.202', 10000)
            else:
                server_address = ('127.0.0.1', 10000)
            #server_address = ('192.168.11.202',10000)
            #connect the socket to the port where the server is listening
            #server_address = ('127.0.0.1',10000)
            print >> sys.stderr, '---connecting to %s port %s---' % server_address
            self._parent.log_info("stepautonomy0++++=++++++++++++++++++++++")
            self._parent.log_info("stepautonomy1++++=++++++++++++++++++++++")
            try:
                sock.connect(server_address)
                messageArray = [
                    self._id, 100000, 100000, 99999, 100000, self._desired_lat,
                    self._desired_lon, 0, self._desired_alt, "PRDER"
                ]
                message = str(messageArray)
                sock.sendall(message)

                #look for response
                num_symbols = 4096
                delta = 4096
                while delta == num_symbols:
                    data = sock.recv(num_symbols)
                    delta = len(data)
                    print >> sys.stderr, 'Received: %s' % data
                finishedset = eval(data)
            except:
                self._parent.log_info("socket communication failed")
            finally:
                print >> sys.stderr, '---closing socket---'
                sock.close()
            self._parent.log_info("stepautonomy2++++=++++++++++++++++++++++")

            # Set initial altitude settings
            self._desired_alt = self._last_ap_wp[2]
            self._original_alt = self._last_ap_wp[2]

            # Determine your own subswarm ID
            #key     #value
            for blue_id, blue in self._blues.iteritems():
                if blue.vehicle_id == self._id:
                    self._subswarm_id = blue.subswarm_id
                    break
            print "subswarm_id: ", self._subswarm_id
            print(finishedset)

            # Build a list of all vehicle IDs within your subswarm
            blue_in_subswarm = dict()
            i = 0
            self._parent.log_info("stepautonomy++++=++++++++++++++++++++++")
            for blue_id, blue in self._blues.iteritems():
                if blue.subswarm_id == self._subswarm_id:
                    self._id_in_subswarm.append(blue.vehicle_id)
                    self._subswarm_num_to_assign.append(0)
                    blue_in_subswarm[i] = blue
                    i = i + 1
            self._parent.log_info("id_in_subswarm: ", self._id_in_subswarm)
            print(self._vehicle_type)

            for n in finishedset:
                self._wp_assigned[n] = True

            # Divide # of waypoints by # of vehicles and create empty bundle of wpts for each
            num_in_subwarm = len(self._id_in_subswarm)
            for i in range(0, num_in_subwarm):
                self._subswarm_num_to_assign[i] = (
                    len(self._enumList) - len(finishedset)) / (num_in_subwarm)
                if i < (
                    (len(self._enumList) - len(finishedset)) % num_in_subwarm):
                    self._subswarm_num_to_assign[
                        i] = self._subswarm_num_to_assign[i] + 1
            print "num_to_assign: ", self._subswarm_num_to_assign

            # Perform sequencial greedy wpt assignment.  Loop over each UAS in subswarm.
            for i in range(0, num_in_subwarm):
                # Set the start location to current UAS position
                temp_lat = blue_in_subswarm[i].state.pose.pose.position.lat
                temp_lon = blue_in_subswarm[i].state.pose.pose.position.lon
                assignment_list = []
                # Loop over each element of the waypoint bundle
                for j in range(0, self._subswarm_num_to_assign[i]):
                    min_dist = 99999  #initialize as large number
                    new_wp_assigned = False
                    # Loop over each waypoint defined in the mission
                    for k in range(0, len(self._enumList)):
                        # Skip to next if that waypoint is already assigned
                        if self._wp_assigned[k] == False:
                            # Set the end location to that waypoint
                            temp2_lat = float(self._enumList[k][0])
                            temp2_lon = float(self._enumList[k][1])
                            # Check if start to end location distance is new minimum, if so mark
                            # if for assignment
                            temp_dist = gps.gps_distance(
                                temp_lat, temp_lon, temp2_lat, temp2_lon)
                            if temp_dist < min_dist:
                                min_dist = temp_dist
                                wp_to_assign = k
                                new_wp_assigned = True
                    # Add the next closest waypoint to the bundle
                    if new_wp_assigned == True:
                        assignment_list.append(wp_to_assign)
                        self._subswarm_wp_assignment[i] = assignment_list
                        # Mark that waypoint as "assigned" so unavailable to others
                        self._wp_assigned[wp_to_assign] = True
                        # Update the start location to that waypoint
                        temp_lat = float(self._enumList[wp_to_assign][0])
                        temp_lon = float(self._enumList[wp_to_assign][1])
                # Assign yourself your own bundle of waypoints
                if blue_in_subswarm[i].vehicle_id == self._id:
                    self._wp_id_list = self._subswarm_wp_assignment[i]
            print "subswarm_wp_assignment: ", self._subswarm_wp_assignment
            # Proceed to the first Waypoint in the bundle
            self._loc = self._wp_id_list[0]
            self._desired_lat = float(self._enumList[self._loc][0])
            self._desired_lon = float(self._enumList[self._loc][1])
            print "Going to WP: ", self._loc

        # Go to desired latitude, longitude, and maintain altitude
        # deconfliction:
        self._wp = np.array(
            [self._desired_lat, self._desired_lon, self._desired_alt])
        #self._wp = np.array([self._desired_lat, self._desired_lon,
        #self._last_ap_wp[2]])

        pos = self._own_pose.pose.pose.position
        dist = gps.gps_distance(pos.lat, pos.lon, self._desired_lat,
                                self._desired_lon)

        # Detect whether UAS has arrived at WP (within threshold distance), track time at WP
        # Zephyrs (type 2) loitersocket.error: [Errno 104] Connection reset by peer around point, so set threshold distance > loiter radius
        # Set threshold distance for Quads (type 1), much smaller

        SURVEY_ALT = self._base_alt + (
            self._alt_change * self._id_in_subswarm.index(self._id)
        )  #redefine SURVEY_ALT within the loop to stack behavior

        if (self._vehicle_type == 2
                and dist < DIST2WP_ZEPH) or (self._vehicle_type == 1
                                             and dist < DIST2WP_QUAD):
            if self._at_wp == False:
                if (pos.rel_alt > SURVEY_ALT - BUFFER) and (
                        pos.rel_alt < SURVEY_ALT + BUFFER):
                    self._time_start = timeit.default_timer()
            self._at_wp = True
            self._time_at_wp = timeit.default_timer() - self._time_start
        else:
            self._at_wp = False
            self._time_at_wp = 0

        # Detect if Quad is close enough to first WP to descend to survey altitude
        if self._vehicle_type == 1 and dist < DIST_START_DESCENT:
            self._desired_alt = SURVEY_ALT

        # After X time has elapsed at WP, move onto next WP in your bundle
        if self._time_at_wp > TIME_AT_WP:

            ############################# HEATMAP VARS ##############################
            def getcounts():

                with open(self.radeyeDir + 'radfile.csv', 'r') as radfile:
                    firstline = radfile.readline().split(',')
                    print(firstline)
                    return ((firstline[0], firstline[1]))

            lat = pos.lat
            lon = pos.lon
            alt = pos.alt
            counts, radtype = getcounts()
            print(counts)
            print(radtype)
            #########################################################################
            #create a TCP/IP socket
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            #192.168.11.202
            #connect the socket to the port where the server is listening
            #server_address = ('192.168.11.202',10000)
            #server_address = ('127.0.0.1', 10000)
            serverflag = 1
            if (SERVER_FLAG == 1):
                server_address = ('192.168.11.202', 10000)
            else:
                server_address = ('127.0.0.1', 10000)
            print >> sys.stderr, '---connecting to %s port %s---' % server_address
            try:
                sock.connect(server_address)
                #send data
                #str(self._subswarm_wp_assignment)

                #messageArray = [self._id, [0,0,0,0,0], self._loc, self._wp_id_list.index(self._loc), [0,0,0,0], lat, lon, counts, alt]
                messageArray = [
                    self._id,
                    len(self._wp_id_list), self._loc,
                    self._wp_id_list.index(self._loc),
                    len(self._enumList), lat, lon, counts, alt, radtype
                ]
                message = str(messageArray)
                print("UAV ID: " + str(self._id))
                print("Sending Message to Base Station...")
                sock.sendall(message)

                #look for response 4194304
                amount_received = 0
                num_symbols = 4096
                delta = 4096
                while delta == num_symbols:
                    data = sock.recv(num_symbols)
                    delta = len(data)
                    #print >>sys.stderr,'Received: %s' % data

            except:
                #self._parent.log_info("socket communication failed")
                pass
            finally:
                print >> sys.stderr, '---closing socket---'
                sock.close()
            self._wp_id_list_id = self._wp_id_list_id + 1

            # If you get to the end of your bundle, repeat from its beginning
            # and reset to original altitude
            if self._wp_id_list_id > (len(self._wp_id_list) - 1):
                self._wp_id_list_id = 0
                self._desired_alt = self._original_alt
            self._loc = self._wp_id_list[self._wp_id_list_id]
            self._desired_lat = float(self._enumList[self._loc][0])
            self._desired_lon = float(self._enumList[self._loc][1])
            # Reset these so that UAV knows it's no longer at its goal WP
            self._at_wp = False
            self._time_at_wp = 0
            print "Going to WP: ", self._loc

        return True
예제 #24
0
    def step_autonomy(self, t, dt):

        # Reset the action and target ID every loop
        self._action = ["None", 0]
        self._target_id = None
        self._target_range = np.inf
        # print set(self._blues)

        # Search for the closest target every frame
        min_dist = MIN_DIST  # range to start looking for enemy
        for uav in self._reds.values():
            if (uav.vehicle_id not in self._shot) and (uav.vehicle_id
                                                       not in self._taken):
                target_pos = self._reds[
                    uav.vehicle_id].state.pose.pose.position
                own_lat = self._own_pose.pose.pose.position.lat
                own_lon = self._own_pose.pose.pose.position.lon
                own_alt = self._own_pose.pose.pose.position.rel_alt
                own_orientation = self._own_pose.pose.pose.orientation
                tgt_lat = target_pos.lat
                tgt_lon = target_pos.lon
                tgt_alt = target_pos.rel_alt

                d = gps.gps_distance(own_lat, own_lon, tgt_lat, tgt_lon)

                # is the target UAV in front of me?
                if gps.hitable(own_lat, own_lon, own_alt, \
                    (own_orientation.x, \
                    own_orientation.y, \
                    own_orientation.z, \
                    own_orientation.w ), \
                    np.inf, 180.0, self._fov_height,\
                    tgt_lat, tgt_lon, tgt_alt):
                    if d < min_dist:
                        min_dist = d
                        self._target_id = uav.vehicle_id
                        self._target_range = d

        if (self._target_id in self._shot) or (self._target_id in self._taken):
            self._target_id = None
            self._target_range = np.inf

        # If a target has been identified, move towards it
        if self._target_id != None:
            msg = apmsg.MsgStat()
            msg.id = self._id
            msg.count = self._target_id
            msg.latency = self._target_range
            self.pubs['taken'].publish(msg)
            print '{} targeting UAV {} at a distance of {}'.format(
                self._id, self._target_id, self._target_range)
            print '{} has taken list of {}'.format(self._id, self._taken)

            target_pos = self._reds[self._target_id].state.pose.pose.position
            own_lat = self._own_pose.pose.pose.position.lat
            own_lon = self._own_pose.pose.pose.position.lon
            own_alt = self._own_pose.pose.pose.position.rel_alt
            own_orientation = self._own_pose.pose.pose.orientation
            tgt_lat = target_pos.lat
            tgt_lon = target_pos.lon
            tgt_alt = target_pos.rel_alt

            # Set the waypoint past the current target, so we don't go into a
            # loiter mode
            bearing = gps.gps_bearing(own_lat, own_lon, tgt_lat, tgt_lon)
            lat, lon = gps.gps_newpos(own_lat, own_lon, bearing, 100)

            self._wp = np.array([lat, lon, target_pos.rel_alt])

            # Determine if the target is within firing parameters
            if gps.hitable(own_lat, own_lon, own_alt, \
                           (own_orientation.x, \
                            own_orientation.y, \
                            own_orientation.z, \
                            own_orientation.w ), \
                           self._max_range, self._fov_width, self._fov_height,\
                           tgt_lat, tgt_lon, tgt_alt):
                self._action = ["Fire", self._target_id]
                print "=================>ID: %d shot at Target %d" % (
                    self._id, self._target_id)
        else:
            # If a target hasn't been identified, return to the safe waypoint
            self._wp = self._safe_waypoint
        self._taken.clear(
        )  # clear the taken list in case it's full of old data
        return True
예제 #25
0
    def step_autonomy(self, t, dt):
        # Execute this portion of the code on the loop only
        if self._first_tick == True:
            self._first_tick = False

            # Set initial altitude settings
            self._desired_alt = self._last_ap_wp[2]
            self._original_alt = self._last_ap_wp[2]

            # Determine your own subswarm ID
               #key     #value
            for blue_id, blue in self._blues.iteritems():
                if blue.vehicle_id == self._id:
                    self._subswarm_id = blue.subswarm_id
                    break
            print "subswarm_id: ", self._subswarm_id
 
            # Build a list of all vehicle IDs within your subswarm
            blue_in_subswarm = dict()
            i = 0
            for blue_id, blue in self._blues.iteritems():
                if blue.subswarm_id == self._subswarm_id:
                    self._id_in_subswarm.append(blue.vehicle_id)
                    self._subswarm_num_to_assign.append(0) 
                    blue_in_subswarm[i] = blue
                    i = i+1        
            print "id_in_subswarm: ", self._id_in_subswarm

            # Divide # of waypoints by # of vehicles and create empty bundle of wpts for each 
            num_in_subwarm = len(self._id_in_subswarm)
            for i in range(0, num_in_subwarm):
                self._subswarm_num_to_assign[i] = int(math.floor(len(usma_enums.WP_LOC)/num_in_subwarm))
                if i < (len(usma_enums.WP_LOC) % num_in_subwarm):
                    self._subswarm_num_to_assign[i] = self._subswarm_num_to_assign[i] + 1
            print "num_to_assign: ", self._subswarm_num_to_assign

            # Perform sequencial greedy wpt assignment.  Loop over each UAS in subswarm.
            for i in range(0, num_in_subwarm):
                # Set the start location to current UAS position
                temp_lat = blue_in_subswarm[i].state.pose.pose.position.lat
                temp_lon = blue_in_subswarm[i].state.pose.pose.position.lon
                assignment_list = []
                # Loop over each element of the waypoint bundle 
                for j in range(0, self._subswarm_num_to_assign[i]):
                    min_dist = 99999 #initialize as large number
                    new_wp_assigned = False
                    # Loop over each waypoint defined in the mission  
                    for k in range(0, len(usma_enums.WP_LOC)):
                        # Skip to next if that waypoint is already assigned
                        if self._wp_assigned[k] == False:
                            # Set the end location to that waypoint
                            temp2_lat = float(usma_enums.WP_LOC[k][0])
                            temp2_lon = float(usma_enums.WP_LOC[k][1])
                            # Check if start to end location distance is new minimum, if so mark
                            # if for assignment
                            temp_dist = gps.gps_distance(temp_lat, temp_lon, temp2_lat, temp2_lon)
                            if temp_dist < min_dist:
                                min_dist = temp_dist
                                wp_to_assign = k
                                new_wp_assigned = True
                    # Add the next closest waypoint to the bundle
                    if new_wp_assigned == True:
                        assignment_list.append(wp_to_assign)
                        self._subswarm_wp_assignment[i] = assignment_list
                        # Mark that waypoint as "assigned" so unavailable to others
                        self._wp_assigned[wp_to_assign] = True
                        # Update the start location to that waypoint
                        temp_lat = float(usma_enums.WP_LOC[wp_to_assign][0])
                        temp_lon = float(usma_enums.WP_LOC[wp_to_assign][1])
                # Assign yourself your own bundle of waypoints
                if blue_in_subswarm[i].vehicle_id == self._id:
                    self._wp_id_list = self._subswarm_wp_assignment[i]
            print "subswarm_wp_assignment: ", self._subswarm_wp_assignment
            # Proceed to the first Waypoint in the bundle
            self._loc = self._wp_id_list[0]
            self._desired_lat = float(usma_enums.WP_LOC[self._loc][0])
            self._desired_lon = float(usma_enums.WP_LOC[self._loc][1]) 
            print "Going to wp: ", self._loc

        # Go to desired latitude, longitude, and maintain altitude
        # deconfliction:
        self._wp = np.array([self._desired_lat, self._desired_lon, 
                             self._desired_alt])
        #self._wp = np.array([self._desired_lat, self._desired_lon, 
                             #self._last_ap_wp[2]])

        pos = self._own_pose.pose.pose.position
        dist = gps.gps_distance(pos.lat, pos.lon, self._desired_lat, self._desired_lon)

        # Detect whether UAS has arrived at WP (within threshold distance), track time at WP
        # Zephyrs (type 2) loiter around point, so set threshold distance > loiter radius
        # Set threshold distance for Quads (type 1), much smaller
        if (self._vehicle_type == 2 and dist < DIST2WP_ZEPH) or (self._vehicle_type == 1 and dist < DIST2WP_QUAD):
            if self._at_wp == False:
                self._time_start = timeit.default_timer()
            self._at_wp = True
            self._time_at_wp = timeit.default_timer() - self._time_start
        else:
            self._at_wp = False
            self._time_at_wp = 0

        # Detect if Quad is close enough to first WP to descend to survey altitude
        if self._vehicle_type == 1 and dist < DIST_START_DESCENT: 
            self._desired_alt = SURVEY_ALT
        
        # After X time has elapsed at WP, move onto next WP in your bundle
        if self._time_at_wp > TIME_AT_WP:
            self._wp_id_list_id = self._wp_id_list_id + 1
            # If you get to the end of your bundle, repeat from its beginning 
            # and reset to original altitude
            if self._wp_id_list_id > (len(self._wp_id_list)-1): 
                self._wp_id_list_id = 0
                self._desired_alt = self._original_alt
            self._loc = self._wp_id_list[self._wp_id_list_id]
            self._desired_lat = float(usma_enums.WP_LOC[self._loc][0])
            self._desired_lon = float(usma_enums.WP_LOC[self._loc][1]) 
            # Reset these so that UAV knows it's no longer at its goal WP
            self._at_wp = False
            self._time_at_wp = 0
            print "Going to wp: ", self._loc
        
        return True
예제 #26
0
    def step_autonomy(self, t, dt):

        # Reset the action and target ID every loop
        self._action = ["None", 0]

        ############################################################
        # If self._target_id is not None and in the shot group
        # then reset to None, otherwise set to last_target
        ############################################################

        min_dist = self._target_dist
        for uav in self._reds.values():
            if uav.vehicle_id not in self._shot:
                uav_lat = uav.state.pose.pose.position.lat
                uav_lon = uav.state.pose.pose.position.lon
                uav_alt = uav.state.pose.pose.position.rel_alt
                d = gps.gps_distance(self._own_pose.pose.pose.position.lat,\
                                     self._own_pose.pose.pose.position.lon,\
                                     uav_lat, uav_lon)

                if gps.hitable(self._own_pose.pose.pose.position.lat, \
                           self._own_pose.pose.pose.position.lon, \
                           self._own_pose.pose.pose.position.rel_alt, \
                           (self._own_pose.pose.pose.orientation.x, \
                            self._own_pose.pose.pose.orientation.y, \
                            self._own_pose.pose.pose.orientation.z, \
                            self._own_pose.pose.pose.orientation.w ), \
                           9999, 180, 180, uav_lat, uav_lon, uav_alt):
                    if d < min_dist:
                        min_dist = d
                        self._target_id = uav.vehicle_id

        if self._target_id in self._shot:
            self._target_id = None
            self._target_dist = np.inf
            self._target_count = 0
            self._target_last_lat = None
            self._target_last_lon = None
            self._target_heading = None
            self._target_speed = None

        # If a target has been identified, move towards it
        if self._target_id != None:
            own_lat = self._own_pose.pose.pose.position.lat
            own_lon = self._own_pose.pose.pose.position.lon

            if self._last_lat is not None:
                self._speed = gps.gps_distance(own_lat, own_lon,\
                                     self._last_lat, self._last_lon) / 0.1
                self._heading = gps.gps_bearing(self._last_lat, self._last_lon,
                                                own_lat, own_lon)

            self._last_lat = own_lat
            self._last_lon = own_lon

            target_pos = self._reds[self._target_id].state.pose.pose.position
            tgt_lat = target_pos.lat
            tgt_lon = target_pos.lon
            tgt_alt = target_pos.rel_alt

            d = gps.gps_distance(self._own_pose.pose.pose.position.lat,\
                                     self._own_pose.pose.pose.position.lon,\
                                     tgt_lat,\
                                     tgt_lon)

            if self._target_last_lat is not None:
                self._target_speed = gps.gps_distance(tgt_lat, tgt_lon,\
                                     self._target_last_lat, self._target_last_lon) / 0.1
                self._target_heading = gps.gps_bearing(self._target_last_lat,
                                                       self._target_last_lon,
                                                       tgt_lat, tgt_lon)
                #print "ID: %d   Target: %d" % (self._id, self._target_id)
                #print "Lat: %f  Lon: %f  Head: %f   T_lat: %f  T_lon %f  T_head: %f" % (own_lat, own_lon, self._heading, \
                #tgt_lat, tgt_lon, self._target_heading)

            self._target_last_lat = tgt_lat
            self._target_last_lon = tgt_lon

            #############################################################################
            # Calc intercept point
            # swapped lat, lon, sin, cos to see if it changed
            t = None
            if self._target_heading is not None:
                s = self._speed
                ox = tgt_lat - own_lat
                oy = tgt_lon - own_lon
                vx = self._target_speed * math.cos(self._target_heading)  # sin
                vy = self._target_speed * math.sin(self._target_heading)  # cos
                h1 = vx**2 + vy**2 - s**2
                h2 = ox * vx + oy * vy

                if h1 == 0:
                    t = -(ox**2 + oy**2) / (2 * h2)
                else:
                    minusPHalf = -h2 / h1
                    disc = minusPHalf**2 - (ox**2 + oy**2) / h1
                    if disc < 0:
                        t = None
                    else:
                        root = math.sqrt(disc)
                        t1 = minusPHalf + root
                        t2 = minusPHalf - root
                        tmin = t1 if t1 < t2 else t2
                        tmax = t1 if t1 > t2 else t2

                        t = tmin if tmin > 0 else tmax

                        if t < 0:
                            t = None
                        #else:
                        #t *= 1.65

            if t is not None:
                t_adj = 0.0  # 003			# add equiv of 1 sec
                int_lat = tgt_lat + vx * (t + t_adj)
                int_lon = tgt_lon + vy * (t + t_adj)
                int_dist = gps.gps_distance(own_lat, own_lon, int_lat, int_lon)
                bearing = gps.gps_bearing(own_lat, own_lon, int_lat, int_lon)
                lat, lon = gps.gps_newpos(own_lat, own_lon, bearing, int_dist)
                #print "ID: %d using intercept bearing %f to Lat: %f  Lon: %f  Dist: %f  Time: %f" % (self._id, bearing, lat, lon, int_dist, t*10000)  #  I_lat: %f  I_lon: %f  t: %f
            else:
                bearing = gps.gps_bearing(own_lat, own_lon, tgt_lat, tgt_lon)
                dist = gps.gps_distance(own_lat, own_lon, tgt_lat, tgt_lon)
                lat, lon = gps.gps_newpos(own_lat, own_lon, bearing,
                                          dist + 250)  # range was 1000
                #print "ID: %d using direct bearing %f to Lat: %f  Lon: %f  Dist: %f" % (self._id, bearing, lat, lon, dist)

            # Set the waypoint past the current target, so we don't go into a
            # loiter mode
            #if tgt_alt < 200:		# we're getting ground collisions
            #tgt_alt = 200

            self._wp = np.array([lat, lon, tgt_alt])

            # Determine if the target is within firing parameters
            if gps.hitable(self._own_pose.pose.pose.position.lat, \
                           self._own_pose.pose.pose.position.lon, \
                           self._own_pose.pose.pose.position.rel_alt, \
                           (self._own_pose.pose.pose.orientation.x, \
                            self._own_pose.pose.pose.orientation.y, \
                            self._own_pose.pose.pose.orientation.z, \
                            self._own_pose.pose.pose.orientation.w ), \
                           self._max_range, self._fov_width, self._fov_height,\
                           tgt_lat, tgt_lon, tgt_alt):
                self._action = ["Fire", self._target_id]
                print "GS Int=============================>ID: %d shot at Target %d" % (
                    self._id, self._target_id)

        else:
            # If a target hasn't been identified, return to the safe waypoint
            self._wp = self._safe_waypoint
        return True
예제 #27
0
    def step_autonomy(self, t, dt):

        # Reset the action every loop
        self._action = ["None", 0]
        self._target_id = None

        own_lat = self._own_pose.pose.pose.position.lat
        own_lon = self._own_pose.pose.pose.position.lon
        own_alt = self._own_pose.pose.pose.position.alt

        # Search for the closest target
        min_dist = np.inf
        for uav in self._reds.values():
            if uav.vehicle_id not in self._shot:
                d = gps.gps_distance(own_lat, \
                                     own_lon, \
                                     uav.state.pose.pose.position.lat, \
                                     uav.state.pose.pose.position.lon)

                if d < min_dist:
                    min_dist = d
                    self._target_id = uav.vehicle_id

        # If a target has been identified, move towards it
        if self._target_id != None:
            target_pos = self._reds[self._target_id].state.pose.pose.position

            tgt_lat = target_pos.lat
            tgt_lon = target_pos.lon

            distance_to_target = gps.gps_distance(own_lat, own_lon, tgt_lat,
                                                  tgt_lon)

            # Set bearing to look at the enemy vehicle
            bearing = gps.gps_bearing(own_lat, own_lon, tgt_lat, tgt_lon)

            # Set waypoint to move forward and strafe sideways once the enemy is within range
            self._evasion_range = self._weapons_range * 2
            self._engagement_range = self._weapons_range * 2 / 3
            if distance_to_target <= self._engagement_range:
                lat, lon = gps.gps_newpos(
                    own_lat, own_lon,
                    gps.normalize(bearing - self._fov_width / 2), 0.1)
            elif distance_to_target <= self._evasion_range:
                # Check to see if sidestep right waypoint is outside the battlebox
                # (only need to check distance_to_target/2 since enemy is closing)
                lat_right, lon_right = gps.gps_newpos(own_lat, own_lon, \
                                                      gps.normalize(bearing + (math.pi / 3)), distance_to_target/2)
                if self._bboxes[0].contains(lat_right, lon_right, own_alt):
                    lat, lon = gps.gps_newpos(own_lat, own_lon, \
                                                      gps.normalize(bearing + (math.pi / 3)), distance_to_target)
                else:
                    # If right sidestep is outside the battlebox, sidestep to the left
                    lat, lon = gps.gps_newpos(
                        own_lat, own_lon,
                        gps.normalize(bearing - (math.pi / 3)),
                        distance_to_target)
            else:
                lat, lon = gps.gps_newpos(own_lat, own_lon, bearing, 1000)

            self._wp = np.array([lat, lon, target_pos.rel_alt])

            # Determine if the target is within firing parameters
            if gps.hitable(self._own_pose.pose.pose.position.lat, \
                           self._own_pose.pose.pose.position.lon, \
                           self._own_pose.pose.pose.position.rel_alt, \
                           (self._own_pose.pose.pose.orientation.x, \
                            self._own_pose.pose.pose.orientation.y, \
                            self._own_pose.pose.pose.orientation.z, \
                            self._own_pose.pose.pose.orientation.w), \
                           self._weapons_range, self._fov_width, self._fov_height, \
                           target_pos.lat, target_pos.lon, target_pos.rel_alt):
                self._action = ["Fire", self._target_id]
        else:
            # If a target hasn't been identified, return to the safe waypoint
            self._wp = self._safe_waypoint

        return True
예제 #28
0
    def step_autonomy(self, t, dt):
        
        #swarmCount = 0
        # Reset the action and target ID every loop
        self._action = ["None", 0]
        #self._target_id = self._last_target

        if self._team is None:
            if self._id in self._blues:
                self._team = 'blue'
            else:
                self._team = 'red'
        
            (self._goal_lat, self._goal_lon, _) = enums.GOAL_POSITS[self._team]
            print "lat %f lon %f" % (self._goal_lat, self._goal_lon)
        
        #go to waypoints for storm formation
        
        if self._got_target is False and self._goal_lat is not None:
            #self._in_swarm = True
            if self._id%5 == 0:
                storm_lat, storm_lon = gps.gps_newpos(self._goal_lat, self._goal_lon, math.radians(enums.BATTLE_CUBE_ORIENT) + math.pi/2.0, 0)     
                self._wp = np.array([storm_lat, storm_lon, 500])
                #self._safe_waypoint_reserve 35.720785, -120.765860
                print "ID: %d sent RESERVE %f, %f\n" % (self._id, storm_lat, storm_lon)

            if self._id%5 == 1:
                storm_lat, storm_lon = gps.gps_newpos(self._goal_lat, self._goal_lon, math.radians(enums.BATTLE_CUBE_ORIENT), 100)
                self._wp = np.array([storm_lat, storm_lon, 500])
                #self._wp = np.array([125, 375, 250])#self._safe_waypoint_nw 35.720785, -120.765860
                print "ID: %d sent NW %f, %f\n" % (self._id, storm_lat, storm_lon)

            if self._id%5 == 2:
                storm_lat, storm_lon = gps.gps_newpos(self._goal_lat, self._goal_lon, math.radians(enums.BATTLE_CUBE_ORIENT) + math.pi, 100)
                self._wp = np.array([storm_lat, storm_lon, 500])
                #self._wp = np.array([125, 125, 300])#self._safe_waypoint_sw 35.719981, -120.769101
                print "ID: %d sent SW %f, %f\n" % (self._id, storm_lat, storm_lon)

            if self._id%5 == 3:
                storm_lat, storm_lon = gps.gps_newpos(self._goal_lat, self._goal_lon, math.radians(enums.BATTLE_CUBE_ORIENT) + math.pi/4.0, 100)
                self._wp = np.array([storm_lat, storm_lon, 500])
                #self._wp = np.array([375, 375, 200])#self._safe_waypoint_ne 35.720785, -120.765860
                print "ID: %d sent NE %f, %f\n" % (self._id, storm_lat, storm_lon)

            if self._id%5 == 4:
                storm_lat, storm_lon = gps.gps_newpos(self._goal_lat, self._goal_lon, math.radians(enums.BATTLE_CUBE_ORIENT) + 3.0*math.pi/4.0, 100)
                self._wp = np.array([storm_lat, storm_lon, 500])
                #self._wp = np.array([375, 125, 350])#self._safe_waypoint_se 35.719981, -120.769101
                print "ID: %d sent SE %f, %f\n" % (self._id, storm_lat, storm_lon)   
     

        # Search for the closest target every frame if you don't already have one
        min_dist = self._target_dist   # self._min_dist
        if self._got_target is False:
            for uav in self._reds.values():
                if uav.vehicle_id not in self._shot:
                    d = gps.gps_distance(self._own_pose.pose.pose.position.lat,\
                                     self._own_pose.pose.pose.position.lon,\
                                     uav.state.pose.pose.position.lat,\
                                     uav.state.pose.pose.position.lon)

                    if d < min_dist:
                        min_dist = d
                        self._target_id = uav.vehicle_id
                        self._last_target = self._target_id
                        
                        if d < self._max_range:
                            self._got_target = True
                            self._in_swarm = False
                            print "UAV %d within range of Target %d\n" % (self._id, self._target_id)
                            break
        else:
            self._got_target = False
            self._target_id = None
            for uav in self._reds.values():
                if uav.vehicle_id not in self._shot:
                    if self._last_target == uav.vehicle_id:
                        d = gps.gps_distance(self._own_pose.pose.pose.position.lat,\
                                     self._own_pose.pose.pose.position.lon,\
                                     uav.state.pose.pose.position.lat,\
                                     uav.state.pose.pose.position.lon)
                        if d < self._max_range:
                            self._target_id = self._last_target
                            if self._got_target is False:   # only print once
                                print "UAV %d within range of Target %d\n" % (self._id, self._target_id)
                                self._got_target = True

                        else:   # was a match, but d > MIN_DIST, reset all
                            print "UAV %d out of range of Target %d\n" % (self._id, self._last_target)
                            self._got_target = False
                            self._target_id = None
                            self._last_target = None

      # If a target has been identified, move towards it
        if self._target_id != None:
            target_pos = self._reds[self._target_id].state.pose.pose.position
            #print "*************************************"
            #print "ID: %d   Target ID: %d\n" % (self._id, self._target_id)
            
            own_lat = self._own_pose.pose.pose.position.lat
            own_lon = self._own_pose.pose.pose.position.lon
            tgt_lat = target_pos.lat
            tgt_lon = target_pos.lon
            tgt_alt = target_pos.rel_alt

            # Set the waypoint past the current target, so we don't go into a
            # loiter mode
            if self._got_target is True:
                bearing = gps.gps_bearing(own_lat, own_lon, tgt_lat, tgt_lon)
                lat, lon = gps.gps_newpos(own_lat, own_lon, bearing, 1000)
                self._wp = np.array([lat, lon, tgt_alt])

            # Determine if the target is within firing parameters
            if gps.hitable(self._own_pose.pose.pose.position.lat, \
                           self._own_pose.pose.pose.position.lon, \
                           self._own_pose.pose.pose.position.rel_alt, \
                           (self._own_pose.pose.pose.orientation.x, \
                            self._own_pose.pose.pose.orientation.y, \
                            self._own_pose.pose.pose.orientation.z, \
                            self._own_pose.pose.pose.orientation.w ), \
                           self._max_range, self._fov_width, self._fov_height,\
                           target_pos.lat, target_pos.lon, target_pos.rel_alt):
                self._action = ["Fire", self._target_id]
                #self._action = ["None", 0]
                print "Storm Shooter==========================>UAV %d shot at Target %d" % (self._id, self._target_id)
                #self._last_target = None
                #self._got_target = False

        #else:
            # Start at the safe waypoint
            #self._wp = self._safe_waypoint

        return True
예제 #29
0
    def step_autonomy(self, t, dt):

        # Reset the action and target ID every loop
        self._action = ["None", 0]
        self._target_id = -1
        ############################################################
        # If self._target_id is not None and in the shot group
        # then reset to None, otherwise set to last_target
        ############################################################

        min_dist = 500  #self._target_dist    # np.inf
        #print 'ID: {} min_dist {}'.format(self._id, min_dist)
        for uav in self._reds.values():
            if uav.vehicle_id not in self._shot and (
                    uav.game_status == enums.GAME_ACTIVE_DEFENSE
                    or uav.game_status == enums.GAME_ACTIVE_OFFENSE):
                uav_lat = uav.state.pose.pose.position.lat
                uav_lon = uav.state.pose.pose.position.lon
                uav_alt = uav.state.pose.pose.position.rel_alt
                d = gps.gps_distance(self._own_pose.pose.pose.position.lat,\
                                     self._own_pose.pose.pose.position.lon,\
                                     uav_lat, uav_lon)

                if d < min_dist:
                    min_dist = d
                    self._target_dist = d
                    self._target_id = uav.vehicle_id

        if self._target_id in self._shot:
            self._target_id = -1
            self._target_last_id = -1
            self._target_dist = np.inf
            self._target_lat = None
            self._target_lon = None
            self._target_heading = None
            self._target_speed = None

        # If a target has been identified, move towards it
        if self._target_id > 0:
            #print "ID: %d   Target: %d  Last Target: %d" % (self._id, self._target_id, self._target_last_id)
            own_lat = self._own_pose.pose.pose.position.lat
            own_lon = self._own_pose.pose.pose.position.lon
            own_alt = self._own_pose.pose.pose.position.rel_alt  # added to keep from changing alt

            if self._last_lat is not None:
                self._speed = gps.gps_distance(own_lat, own_lon,\
                                     self._last_lat, self._last_lon) / 0.1
                self._heading = gps.normalize_angle(
                    gps.gps_bearing(self._last_lat, self._last_lon, own_lat,
                                    own_lon)) * RAD2DEG

            self._last_lat = own_lat
            self._last_lon = own_lon

            target_pos = self._reds[self._target_id].state.pose.pose.position
            tgt_lat = target_pos.lat
            tgt_lon = target_pos.lon
            tgt_alt = target_pos.rel_alt

            d = gps.gps_distance(own_lat, own_lon, tgt_lat, tgt_lon)

            #print 'UAV: {} tgt_lat: {} tgt_lon: {} last_lat: {} last_lon: {}'.format(self._id, tgt_lat, tgt_lon,\
            #self._target_last_lat, self._target_last_lon)
            if (self._target_id
                    == self._target_last_id) and (self._target_last_lat
                                                  is not None):

                self._target_speed = gps.gps_distance(tgt_lat, tgt_lon,\
                                     self._target_last_lat, self._target_last_lon) / 0.1
                self._target_heading = gps.normalize_angle(
                    gps.gps_bearing(self._target_last_lat,
                                    self._target_last_lon, tgt_lat,
                                    tgt_lon)) * RAD2DEG
                #print "ID: %d Speed: %f Head: %f  Target: %d Dist: %f Speed: %f Head: %f" % (self._id, self._speed, self._heading, self._target_id, self._target_dist, self._target_speed, self._target_heading)
                #print "Lat: %f  Lon: %f  Head: %f   T_lat: %f  T_lon %f  T_head: %f" % (own_lat, own_lon, self._heading, \
                #tgt_lat, tgt_lon, self._target_heading)
            else:
                self._target_dist = np.inf
                self._target_lat = None
                self._target_lon = None
                self._target_heading = None
                self._target_speed = None

            self._target_last_id = self._target_id  # set last target id to current id
            self._target_last_lat = tgt_lat
            self._target_last_lon = tgt_lon
            #############################################################################
            # Calc intercept point
            # Reference:  http://jaran.de/goodbits/2011/07/17/calculating-an-intercept-course-to-a-target-with-constant-direction-and-velocity-in-a-2-dimensional-plane/
            # Translated from Java to Python
            #############################################################################
            t = None
            if self._target_heading is not None:
                s = self._speed
                ox = tgt_lat - own_lat
                oy = tgt_lon - own_lon
                vx = self._target_speed * math.cos(self._target_heading)  # sin
                vy = self._target_speed * math.sin(self._target_heading)  # cos
                h1 = vx**2 + vy**2 - s**2
                h2 = ox * vx + oy * vy

                if h1 == 0:
                    t = -(ox**2 + oy**2) / (2 * h2)
                else:
                    minusPHalf = -h2 / h1
                    disc = minusPHalf**2 - (ox**2 + oy**2) / h1
                    if disc < 0:
                        t = None
                    else:
                        root = math.sqrt(disc)
                        t1 = minusPHalf + root
                        t2 = minusPHalf - root
                        tmin = t1 if t1 < t2 else t2
                        tmax = t1 if t1 > t2 else t2

                        t = tmin if tmin > 0 else tmax

                        if t < 0:  # or d < self._max_range:  # close enough so go right to him (switch to greedy shooter)
                            t = None
                        else:
                            t *= 1.0  #1.53

            if t is not None:
                int_lat = tgt_lat + vx * t
                int_lon = tgt_lon + vy * t
                int_dist = gps.gps_distance(own_lat, own_lon, int_lat, int_lon)
                bearing = gps.gps_bearing(own_lat, own_lon, int_lat, int_lon)
                lat, lon = gps.gps_newpos(own_lat, own_lon, bearing,
                                          int_dist + 100)
                #print "ID: %d using intercept bearing %f to Lat: %f  Lon: %f  Dist: %f to UAV: %d" % (self._id, bearing, lat, lon, int_dist, self._target_id)  #  I_lat: %f  I_lon: %f  t: %f
            else:
                bearing = gps.gps_bearing(own_lat, own_lon, tgt_lat, tgt_lon)
                dist = gps.gps_distance(own_lat, own_lon, tgt_lat, tgt_lon)
                lat, lon = gps.gps_newpos(own_lat, own_lon, bearing,
                                          dist + 100)  # range was 1000
                #print "ID: %d using direct bearing %f to Lat: %f  Lon: %f to UAV: %d" % (self._id, bearing, lat, lon, self._target_id)

            # Set the waypoint past the current target, so we don't go into a loiter mode

            self._wp = np.array([lat, lon, own_alt])  # don't use tgt_alt

            # Determine if the target is within firing parameters
            if gps.hitable(self._own_pose.pose.pose.position.lat, \
                           self._own_pose.pose.pose.position.lon, \
                           self._own_pose.pose.pose.position.rel_alt, \
                           (self._own_pose.pose.pose.orientation.x, \
                            self._own_pose.pose.pose.orientation.y, \
                            self._own_pose.pose.pose.orientation.z, \
                            self._own_pose.pose.pose.orientation.w ), \
                           self._max_range, self._fov_width, self._fov_height,\
                           tgt_lat, tgt_lon, tgt_alt):
                self._action = ["Fire", self._target_id]
                print "GS Int=============================>ID: %d shot at Target %d" % (
                    self._id, self._target_id)

        else:
            # If a target hasn't been identified, return to the safe waypoint
            self._target_id = None
            self._target_last_id = -1
            self._target_dist = np.inf
            self._target_lat = None
            self._target_lon = None
            self._target_heading = None
            self._target_speed = None
            self._wp = self._safe_waypoint
            #print 'ID: {} has no target!'.format(self._id)
        return True
예제 #30
0
    def step_autonomy(self, t, dt):

        # Reset the action and target ID every loop
        self._action = ["None", 0]
        self._target_id = None

        # Search for the closest target every frame
        min_dist = self._min_dist  # np.inf

        own_pos = self._own_pose.pose.pose.position
        own_orientation = self._own_pose.pose.pose.orientation
        own_lat = own_pos.lat
        own_lon = own_pos.lon
        own_alt = own_pos.rel_alt

        for uav in self._reds.values():
            if uav.vehicle_id not in self._shot and (
                    uav.game_status == enums.GAME_ACTIVE_DEFENSE
                    or uav.game_status == enums.GAME_ACTIVE_OFFENSE):
                target_pos = self._reds[
                    uav.vehicle_id].state.pose.pose.position
                tgt_lat = target_pos.lat
                tgt_lon = target_pos.lon
                tgt_alt = target_pos.rel_alt
                d = gps.gps_distance(own_lat, own_lon, tgt_lat, tgt_lon)

                if d <= self._max_range:
                    if gps.hitable(own_lat, own_lon, own_alt, \
                           (own_orientation.x, own_orientation.y, \
                           own_orientation.z, own_orientation.w ), \
                           self._max_range, self._fov_width, self._fov_height,\
                           tgt_lat, tgt_lon, tgt_alt):
                        self._action = ["Fire", uav.vehicle_id]
                        print 'GSA========(in loop)===========> ID: {} shot at UAV: {}'.format(
                            self._id, uav.vehicle_id)
                        #self._action = ["None", 0]
                if d < min_dist:
                    min_dist = d
                    self._target_id = uav.vehicle_id

        if self._target_id in self._shot:
            self._target_id = None

        if self._last_target_id == self._target_id:
            total_count = self._max_count * (
                1 + self._chase_safe) / self._chase_safe
            if d < self._target_dist:  # how close do we have to be before I call chasing
                self._target_count += 1
                if self._target_count < self._max_count:
                    pass
                    #print 'ID: {} chasing UAV: {} for {} iterations'.format(self._id, self._target_id, self._target_count)
                elif self._target_count < total_count:
                    pass
                    #print 'ID: {} going to safe wp for {} iterations'.format(self._id, total_count - self._target_count)
                else:
                    self._target_count = 0
                    self._target_id = None

        # If a target has been identified, move towards it
        if self._target_id != None and self._target_count < self._max_count:
            self._last_target_id = self._target_id
            target_pos = self._reds[self._target_id].state.pose.pose.position
            tgt_lat = target_pos.lat
            tgt_lon = target_pos.lon
            tgt_alt = target_pos.rel_alt

            lat = tgt_lat
            lon = tgt_lon

            if self._vehicle_type == enums.AC_FIXED_WING:
                # When using fixed wing, Set the waypoint past the current
                # target, so we don't go into a loiter mode
                bearing = gps.gps_bearing(own_lat, own_lon, tgt_lat, tgt_lon)
                lat, lon = gps.gps_newpos(own_lat, own_lon, bearing, 1000)

            self._wp = np.array([lat, lon, target_pos.rel_alt])

            # Determine if the target is within firing parameters
            if gps.hitable(own_lat, own_lon, own_alt, \
                   (own_orientation.x, own_orientation.y, \
                   own_orientation.z, own_orientation.w ), \
                   self._max_range, self._fov_width, self._fov_height,\
                   tgt_lat, tgt_lon, tgt_alt):
                self._action = ["Fire", self._target_id]
                print 'GSA============================> ID: {} shot at UAV: {}'.format(
                    self._id, self._target_id)
        else:
            # If a target hasn't been identified, return to the safe waypoint
            self._wp = self._safe_waypoint

        # Maintain altitude
        self._wp[2] = self._last_ap_wp[2]

        return True
예제 #31
0
    def step_autonomy(self, t, dt):

        # Reset the action and target ID every loop
        self._action = ["None", 0]
        #self._change = False
        self._target_range = np.inf
        self._target_score = np.inf
        del self._tmp_list[:]  # clear the search lists
        del self._target_list[:]

        # Search for the closest target every frame
        min_dist = MIN_DIST  # range to start looking for enemy
        min_score = MIN_SCORE
        for uav in self._reds.values():
            if (uav.vehicle_id not in self._shot):
                target_pos = self._reds[
                    uav.vehicle_id].state.pose.pose.position
                own_lat = self._own_pose.pose.pose.position.lat
                own_lon = self._own_pose.pose.pose.position.lon
                own_alt = self._own_pose.pose.pose.position.rel_alt
                own_orientation = self._own_pose.pose.pose.orientation
                tgt_lat = target_pos.lat
                tgt_lon = target_pos.lon
                tgt_alt = target_pos.rel_alt

                # get distance and bearing to potential enemy
                d = gps.gps_distance(own_lat, own_lon, tgt_lat, tgt_lon)
                bearing = gps.gps_bearing(own_lat, own_lon, tgt_lat, tgt_lon)

                # Convert absolute angles to relative (shooter to target)
                pose_quat = (own_orientation.x, own_orientation.y,
                             own_orientation.z, own_orientation.w)
                rpy = qmath.quat_to_euler(pose_quat)
                rel_bearing = math.fabs(
                    gps.normalize_angle(bearing - rpy[2])) * RAD2DEG
                #print 'UAV {} to enemy {}:  Dist: {}  Bearing {}'.format(self._id, uav.vehicle_id), d, rel_bearing)

                # is the target UAV in front of me?
                score = d * rel_bearing  # lower is better
                if uav.vehicle_id not in self._tmp_list:
                    self._tmp_list.append((uav.vehicle_id, d, rel_bearing))
                    #print 'UAV {} to enemy {}:  Dist: {}  Bearing {}  Score {}'.format(self._id, uav.vehicle_id, d, rel_bearing, score)

        self._target_list = sorted(self._tmp_list,
                                   key=lambda tgts: tgts[1],
                                   reverse=True)
        target_list_len = len(self._target_list) - 1

        for uav in self._target_list:
            if uav[0] in self._shot:
                self._target_list.remove(uav)

        if target_list_len < 0:
            self._target_id = None
        else:
            self._target_id = self._target_list[target_list_len][0]
            self._target_dist = self._target_list[target_list_len][1]
            self._target_bearing = self._target_list[target_list_len][2]

        #print 'UAV {} target list = {}'.format(self._id, self._target_list)

        # If a target has been identified, move towards it
        if self._target_id != None:
            target_pos = self._reds[self._target_id].state.pose.pose.position
            own_lat = self._own_pose.pose.pose.position.lat
            own_lon = self._own_pose.pose.pose.position.lon
            own_alt = self._own_pose.pose.pose.position.rel_alt
            own_orientation = self._own_pose.pose.pose.orientation
            tgt_lat = target_pos.lat
            tgt_lon = target_pos.lon
            tgt_alt = target_pos.rel_alt
            d = gps.gps_distance(own_lat, own_lon, tgt_lat, tgt_lon)
            bearing = gps.gps_bearing(own_lat, own_lon, tgt_lat, tgt_lon)

            msg = apmsg.MsgStat()
            msg.id = self._target_id
            msg.count = int(self._target_dist)
            msg.latency = self._target_bearing
            self.pubs['score'].publish(msg)
            #print '{} targeting UAV {} at distance {} bearing {}'.format(self._id, self._target_id, self._target_dist, self._target_bearing)

            # Set the waypoint past the current target, so we don't go into a
            # loiter mode
            lat, lon = gps.gps_newpos(own_lat, own_lon, bearing, 10)

            self._wp = np.array([
                lat, lon, own_alt
            ])  # don't climb or dive to target (was target_pos.rel_alt)

            # Determine if the target is within firing parameters
            if gps.hitable(own_lat, own_lon, own_alt, \
                           (own_orientation.x, \
                            own_orientation.y, \
                            own_orientation.z, \
                            own_orientation.w ), \
                           self._max_range, self._fov_width, self._fov_height,\
                           tgt_lat, tgt_lon, tgt_alt):
                self._action = ["Fire", self._target_id]
                print "=============> Wing %d shot at Target %d" % (
                    self._id, self._target_id)
        else:
            # If a target hasn't been identified, return to the safe waypoint
            print 'UAV {} has no target ID!'.format(self._id)
            self._wp = self._safe_waypoint
        self._change = False
        return True
예제 #32
0
    def step_autonomy(self, t, dt):

        # Reset the action and target ID every loop
        self._action = ["None", 0]
        self._target_id = None
        self._target_range = np.inf
        self._target_score = np.inf
        del self._t_id[:]  # clear the search lists
        del self._t_score[:]

        # Search for the closest target every frame
        min_dist = MIN_DIST  # range to start looking for enemy
        min_score = MIN_SCORE
        for uav in self._reds.values():
            if (uav.vehicle_id not in self._shot):
                target_pos = self._reds[
                    uav.vehicle_id].state.pose.pose.position
                own_lat = self._own_pose.pose.pose.position.lat
                own_lon = self._own_pose.pose.pose.position.lon
                own_alt = self._own_pose.pose.pose.position.rel_alt
                own_orientation = self._own_pose.pose.pose.orientation
                tgt_lat = target_pos.lat
                tgt_lon = target_pos.lon
                tgt_alt = target_pos.rel_alt

                # get distance and bearing to potential enemy
                d = gps.gps_distance(own_lat, own_lon, tgt_lat, tgt_lon)
                bearing = gps.gps_bearing(own_lat, own_lon, tgt_lat, tgt_lon)

                # Convert absolute angles to relative (shooter to target)
                pose_quat = (own_orientation.x, own_orientation.y,
                             own_orientation.z, own_orientation.w)
                rpy = qmath.quat_to_euler(pose_quat)
                rel_bearing = math.fabs(gps.normalize_angle(bearing - rpy[2]))
                #print 'UAV {} to enemy {}:  Dist: {}  Bearing {}'.format(self._id, uav.vehicle_id), d, rel_bearing)

                # is the target UAV in front of me?
                score = d * rel_bearing  # lower is better
                print 'UAV {} to enemy {}:  Dist: {}  Bearing {}  Score {}'.format(
                    self._id, uav.vehicle_id, d, rel_bearing, score)
                if score < min_score:
                    min_score = score
                    #self._target_score = score
                    #self._target_id = uav.vehicle_id
                    #self._target_range = d
                    if uav.vehicle_id not in self._t_id:
                        self._t_id.append(uav.vehicle_id)
                        self._t_score.append(score)  # whoops!  was d!
                        self._target_id = uav.vehicle_id
                        self._target_score = score
                        self._target_range = d
                        #print 'UAV {} to enemy {}:  Dist: {}  Bearing {}  Score {}'.format(self._id, uav.vehicle_id, d, rel_bearing, score)

        # If a target has been identified, move towards it
        if self._target_id != None:
            msg = apmsg.MsgStat()
            msg.id = self._id
            msg.count = self._target_id
            msg.latency = self._target_score
            self.pubs['score'].publish(msg)
            #print '{} targeting UAV {} with a score of of {}'.format(self._id, self._target_id, self._target_score)

            target_pos = self._reds[self._target_id].state.pose.pose.position
            own_lat = self._own_pose.pose.pose.position.lat
            own_lon = self._own_pose.pose.pose.position.lon
            own_alt = self._own_pose.pose.pose.position.rel_alt
            own_orientation = self._own_pose.pose.pose.orientation
            tgt_lat = target_pos.lat
            tgt_lon = target_pos.lon
            tgt_alt = target_pos.rel_alt

            # Set the waypoint past the current target, so we don't go into a
            # loiter mode
            bearing = gps.gps_bearing(own_lat, own_lon, tgt_lat, tgt_lon)
            lat, lon = gps.gps_newpos(own_lat, own_lon, bearing, 1000)

            self._wp = np.array([lat, lon, target_pos.rel_alt])

            # Determine if the target is within firing parameters
            if gps.hitable(own_lat, own_lon, own_alt, \
                           (own_orientation.x, \
                            own_orientation.y, \
                            own_orientation.z, \
                            own_orientation.w ), \
                           self._max_range, self._fov_width, self._fov_height,\
                           tgt_lat, tgt_lon, tgt_alt):
                self._action = ["Fire", self._target_id]
                print "=============> Wing %d shot at Target %d" % (
                    self._id, self._target_id)
        else:
            # If a target hasn't been identified, return to the safe waypoint
            self._wp = self._safe_waypoint
        return True
예제 #33
0
    def step_autonomy(self, t, dt):

        # Reset the action and target ID every loop
        self._action = ["None", 0]
        self._target_id = self._last_target

        # Search for the closest target every frame if you don't already have one
        min_dist = np.inf  # self._min_dist
        if self._got_target is False:
            for uav in self._reds.values():
                if uav.vehicle_id not in self._shot:
                    d = gps.gps_distance(self._own_pose.pose.pose.position.lat,\
                                     self._own_pose.pose.pose.position.lon,\
                                     uav.state.pose.pose.position.lat,\
                                     uav.state.pose.pose.position.lon)

                    if d < min_dist:
                        min_dist = d
                        self._target_id = uav.vehicle_id
                        self._last_target = self._target_id

                        if d < MIN_DIST:
                            self._got_target = True
                        else:
                            self._got_target = False

        else:
            self._got_target = False
            self._last_target = None
            for uav in self._reds.values():
                if uav.vehicle_id not in self._shot:
                    if self._target_id == uav.vehicle_id:
                        self._last_target = self._target_id
                        self._got_target = True

        # If a target has been identified, move towards it
        if self._target_id != None:
            target_pos = self._reds[self._target_id].state.pose.pose.position
            # print "*************************************"
            print "ID: %d   Target ID: %d\n" % (self._id, self._target_id)

            own_lat = self._own_pose.pose.pose.position.lat
            own_lon = self._own_pose.pose.pose.position.lon
            tgt_lat = target_pos.lat
            tgt_lon = target_pos.lon
            tgt_alt = target_pos.rel_alt

            # Set the waypoint past the current target, so we don't go into a
            # loiter mode
            bearing = gps.gps_bearing(own_lat, own_lon, tgt_lat, tgt_lon)
            lat, lon = gps.gps_newpos(own_lat, own_lon, bearing, 1000)

            self._wp = np.array([lat, lon, tgt_alt
                                 ])  # np.array([lat, lon, target_pos.rel_alt])

            # Determine if the target is within firing parameters
            if gps.hitable(self._own_pose.pose.pose.position.lat, \
                           self._own_pose.pose.pose.position.lon, \
                           self._own_pose.pose.pose.position.rel_alt, \
                           (self._own_pose.pose.pose.orientation.x, \
                            self._own_pose.pose.pose.orientation.y, \
                            self._own_pose.pose.pose.orientation.z, \
                            self._own_pose.pose.pose.orientation.w ), \
                           self._max_range, self._fov_width, self._fov_height,\
                           target_pos.lat, target_pos.lon, target_pos.rel_alt):
                self._action = ["Fire", self._target_id]
                self._last_target = None
                self._got_target = False

        else:
            # Start at the safe waypoint
            self._wp = self._safe_waypoint

        return True
예제 #34
0
    def step_autonomy(self, t, dt):

        # Reset the action every loop
        self._action = ["None", 0]
        self._target_id = None

        own_lat = self._own_pose.pose.pose.position.lat
        own_lon = self._own_pose.pose.pose.position.lon
        own_alt = 400

        if self._state == States.new_start:
            self.ordered_corners = self.closestCorners()
            lat, lon = self.fixed_wing_waypoint(own_lat, own_lon,
                                                self.ordered_corners[0][0],
                                                self.ordered_corners[0][1])
            if gps.gps_distance(own_lat, own_lon, self.ordered_corners[0][0],
                                self.ordered_corners[0][1]) < 50:
                #print("Starting patrol!")
                self.ordered_corners = self.closestCorners()
                self._state = States.patrol
                self.check_for_supply_route()

        elif self._state == States.patrol:
            lat, lon = self.fixed_wing_waypoint(
                own_lat, own_lon, self.ordered_corners[2][0],
                self.ordered_corners[2][1])  #At the time of ordering,
            #3rd closes waypoint is next in path,
            #1st closest is waypoint that you're currently at,
            #2nd closest is waypoint you visited previously
            if gps.gps_distance(own_lat, own_lon, self.ordered_corners[2][0],
                                self.ordered_corners[2][1]) < 25:
                #print("Reached Waypoint at %f,%f!" % (lat, lon))
                self.ordered_corners = self.closestCorners()
                self.check_for_supply_route()

        elif self._state == States.kill_supply:
            lat, lon = self.fixed_wing_waypoint(own_lat, own_lon,
                                                self.ordered_corners[1][0],
                                                self.ordered_corners[1][1])
            if gps.gps_distance(own_lat, own_lon, self.ordered_corners[1][0],
                                self.ordered_corners[1][1]) < 50:
                #print("Reached supply point at %f,%f!" % (lat, lon))
                self.ordered_corners = self.closestCorners()

        ######################################################################
        #If a target is in range, pursue and fire
        # Reset the action and target ID every loop
        self._action = ["None", 0]
        self._target_id = None

        # Search for the closest target every frame
        min_dist = self._weapons_range + 30
        for uav in self._reds.values():
            if uav.vehicle_id not in self._shot:
                d = gps.gps_distance(self._own_pose.pose.pose.position.lat,\
                                     self._own_pose.pose.pose.position.lon,\
                                     uav.state.pose.pose.position.lat,\
                                     uav.state.pose.pose.position.lon)

                if d < min_dist:
                    #We also want to constrain our pursuits to enemies in front of us
                    if gps.hitable(self._own_pose.pose.pose.position.lat, \
                                   self._own_pose.pose.pose.position.lon, \
                                   self._own_pose.pose.pose.position.rel_alt, \
                                   (self._own_pose.pose.pose.orientation.x, \
                                    self._own_pose.pose.pose.orientation.y, \
                                    self._own_pose.pose.pose.orientation.z, \
                                    self._own_pose.pose.pose.orientation.w), \
                                   min_dist, self._fov_width*2, self._fov_height, \
                                   uav.state.pose.pose.position.lat, \
                                   uav.state.pose.pose.position.lon, \
                                   uav.state.pose.pose.position.alt):
                        min_dist = d
                        self._target_id = uav.vehicle_id

        # If a target has been identified, move towards it
        if self._target_id != None:
            #print("Target Aquired!")
            target_pos = self._reds[self._target_id].state.pose.pose.position

            own_lat = self._own_pose.pose.pose.position.lat
            own_lon = self._own_pose.pose.pose.position.lon
            tgt_lat = target_pos.lat
            tgt_lon = target_pos.lon

            lat = tgt_lat
            lon = tgt_lon

            if self._vehicle_type == enums.AC_FIXED_WING:
                # When using fixed wing, Set the waypoint past the current
                # target, so we don't go into a loiter mode
                bearing = gps.gps_bearing(own_lat, own_lon, tgt_lat, tgt_lon)
                lat, lon = gps.gps_newpos(own_lat, own_lon, bearing, 1000)

            # Determine if the target is within firing parameters
            if gps.hitable(self._own_pose.pose.pose.position.lat, \
                           self._own_pose.pose.pose.position.lon, \
                           self._own_pose.pose.pose.position.rel_alt, \
                           (self._own_pose.pose.pose.orientation.x, \
                            self._own_pose.pose.pose.orientation.y, \
                            self._own_pose.pose.pose.orientation.z, \
                            self._own_pose.pose.pose.orientation.w ), \
                           self._weapons_range, self._fov_width, self._fov_height,\
                           target_pos.lat, target_pos.lon, target_pos.rel_alt):
                self._action = ["Fire", self._target_id]

        #################################################################################
        #Safety to make sure you don't fly out of bounds
        rpy = qmath.quat_to_euler((self._own_pose.pose.pose.orientation.x,\
                                   self._own_pose.pose.pose.orientation.y, \
                                   self._own_pose.pose.pose.orientation.z, \
                                   self._own_pose.pose.pose.orientation.w))
        own_bearing = rpy[2]
        left_lat, left_lon = gps.gps_newpos(
            own_lat, own_lon, gps.normalize(own_bearing - (math.pi / 2)), 20)
        right_lat, right_lon = gps.gps_newpos(
            own_lat, own_lon, gps.normalize(own_bearing + (math.pi / 2)), 20)
        front_lat, front_lon = gps.gps_newpos(
            own_lat, own_lon, gps.normalize(own_bearing + (math.pi / 2)), 50)
        if not self._bboxes[0].contains(left_lat, left_lon, own_alt) or \
                not self._bboxes[0].contains(right_lat, right_lon, own_alt) or \
                not self._bboxes[0].contains(front_lat, front_lon, own_alt):
            lat, lon = self.box_center

        self._wp = np.array([lat, lon, own_alt])

        return True
예제 #35
0
    def run_behavior(self):
        ''' Runs one iteration of the behavior
        '''
        self._sorter.send_requested()
        with self._swarm_lock:

            # Make sure the aircraft this one is following is still valid
            # If it is not, need to figure out a new aircraft to follow
            if (((self._leader_id not in self._subswarm_keys) or \
                 (self._leader_id in self._crashed_keys)) and \
                (self._behavior_state != NEGOTIATE_ORDER) and \
                (self._behavior_state != ON_FINAL) and \
                (self._swarm[self._leader_id].swarm_state != enums.LANDING)):
                self._negotiate_landing_order()

            # Newly activated behavior--determine landing sequence first
            if self._behavior_state == NEGOTIATE_ORDER:
                if self._negotiate_landing_order():
                    self._behavior_state = START_TRANSIT

            # Sequence computed, but need to send the transit waypoint
            elif self._behavior_state == START_TRANSIT:
                self.publishWaypoint(self.wp_msg)
                self._behavior_state = IN_TRANSIT
                self.log_dbug("transit to landing stack location initiated")
                return

            # Transiting to the landing stack location
            elif self._behavior_state == IN_TRANSIT:
                state = self._swarm[self._ownID]
                d = gps.gps_distance(state.state.pose.pose.position.lat, \
                                    state.state.pose.pose.position.lon, \
                                    self.wp_msg.lat, self.wp_msg.lon)
                if gps.gps_distance(state.state.pose.pose.position.lat, \
                                    state.state.pose.pose.position.lon, \
                                    self.wp_msg.lat, self.wp_msg.lon) < LAND_WP_DIST:
                    self.log_dbug("transit to landing stack location complete")
                    self._behavior_state = STACK_ARRIVAL
                    self._stack_time = rospy.Time.now()
                else:
                    return  # Not there yet

            elif self._behavior_state == STACK_ARRIVAL:
                if (rospy.Time.now() - self._stack_time) > STACK_LOITER_TIME:
                    self._behavior_state = IN_STACK

            # In the landing stack--descend after the leader to block 0, then land
            elif self._behavior_state == IN_STACK:
                ldrState = self._swarm[self._leader_id]
                if ldrState.swarm_state == enums.LANDING:
                    self._leader_id = self._ownID

                # It's this aircraft's turn to land
                if self._leader_id == self._ownID:
                    ldg_wp_cmd = stdmsg.UInt16()
                    ldg_wp_cmd.data = self._ldg_wpt_index
                    self._behavior_state = ON_FINAL
                    self._ldg_wp_publisher.publish(ldg_wp_cmd)
                    self.log_info("landing waypoint ordered")
                    return

                # Determine what altitude block we need to be in
                block = int((ldrState.state.pose.pose.position.rel_alt - enums.BASE_REL_ALT) + \
                            (enums.ALT_BLOCK_SIZE - ALT_BLOCK_CAPTURE)) / int(enums.ALT_BLOCK_SIZE)
                block = max(0, block + 1)    # Our block is leaderBlock+1
                if block != self._alt_block: # New order only rqd on change
                    self.wp_msg.alt = enums.BASE_REL_ALT + enums.ALT_BLOCK_SIZE * block
                    self.log_dbug("ordered to altitude block %d (%f meters)"\
                                  %(self._alt_block, self.wp_msg.alt))
                    self._alt_block = block
                    self.publishWaypoint(self.wp_msg)

            # If landing has already been ordered, we're done
            elif self._behavior_state == ON_FINAL:
                return

            # Invalid state--should never get here
            else:
                self._log_warn("invalid behavior state: %d" %self._behavior_state)
                self._behavior_state = None
                self.set_ready_state(False)