def sub_recv_pose(msg):
    if msg.vehicle_id not in msg_rates:
        msg_rates[msg.vehicle_id] = ap_msg.MsgStat()
        msg_rates[msg.vehicle_id].id = msg.vehicle_id

    # Increment count of messages seen this period
    msg_rates[msg.vehicle_id].count += 1

    # Accumulate latency (will be averaged during re-publish)
    time_sent = msg.state.header.stamp
    time_rcvd = msg.received_at
    latency = float(str(time_rcvd - time_sent)) / 1e9
    msg_rates[msg.vehicle_id].latency += latency
Exemple #2
0
 def receive_msg_stat(self, msg):
     #print '{} received message from {} with latency {}'.format(self._id, msg.id, msg.latency)
     print '{} received message from {}:  Targeting {} at distance {}'.format(
         self._id, msg.id, msg.count, msg.latency)
     self._taken.add(msg.count)
     if msg.count == self._target_id:
         if msg.latency < self._target_range:
             #self._target_id = None
             #self._target_range = np.inf
             t_id.pop()
             l = t_id.len() - 1
             t_dist.pop()
             self._target_id = t_id[l]
             self._target_dist = t_dist[l]
             print '{} dropped UAV {} due to {} being closer at distance {}'.format(
                 self._id, msg.count, msg.id, msg.latency)
             msg = apmsg.MsgStat()
             msg.id = self._id
             msg.count = self._target_id
             msg.latency = self._target_range
             self.pubs['taken'].publish(msg)
         else:
             self._taken.discard(
                 msg.count)  # remove from my list if I am close
    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
    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
Exemple #5
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
Exemple #6
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
Exemple #7
0
    def step_autonomy(self, t, dt):

        # Get our current 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  # was just alt

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

        # Search for the closest target
        min_dist = MIN_DIST
        del t_id[:]
        del t_dist[:]
        for uav in self._reds.values():
            if (uav.vehicle_id not in self._shot) and (uav.vehicle_id
                                                       not in self._taken):
                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
                    self._bearing_adj = -(self._fov_width / 2)
                    self._target_range = d

        # 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

            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
            if distance_to_target <= self._engagement_range:
                self._bearing_adj += 2.5
                if self._bearing_adj > self._fov_width:
                    self._bearing_adj = -self._fov_width
                bearing += math.radians(
                    self._bearing_adj
                )  # bearing_adj in degrees; convert to radians
                lat, lon = gps.gps_newpos(own_lat, own_lon,
                                          gps.normalize(bearing),
                                          0.1)  # was - self._fov_width/2
                #print "UAV %d in engagement range with enemy %d bearing %f" % (self._id, self._target_id, math.degrees(bearing))
            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)
                #print "UAV %d in evasion range with enemy %d" % (self._id, self._target_id)
                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)
                    #print "UAV %d sidestepping right" % self._id
                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)
                    #print "UAV %d sidestepping left" % self._id
            else:
                lat, lon = gps.gps_newpos(own_lat, own_lon, bearing,
                                          100)  # was 1000

            self._wp = np.array([lat, lon, target_pos.rel_alt
                                 ])  # +random.randint(-10,10)]

            # 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]
                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