Ejemplo n.º 1
0
    def max_score(self):
        xc_score = 0
        xc_distance = 0
        xc_type = None
        xc_points = []

        for v1 in self._groups[0].vertices:
            for v2 in self._groups[1].vertices:
                for v3 in self._groups[2].vertices:
                    legs = [
                        distance(v1, v2),
                        distance(v2, v3),
                        distance(v3, v1)
                    ]
                    dist = sum(legs)
                    if self.is_closed(tol=0.05 * dist):
                        if min(legs) / dist > 0.28:  # TODO check coefficient ?
                            current_score = 0.0014 * dist
                            current_type = 'FAI triangle'
                        else:
                            current_score = 0.0012 * dist
                            current_type = 'flat triangle'
                    else:
                        current_score = 0.001 * dist
                        current_type = '3 points'

                    if current_score > xc_score:
                        xc_score = current_score
                        xc_type = current_type
                        xc_distance = dist
                        xc_points = [v1, v2, v3]

        return xc_points, xc_distance, xc_type, xc_score
Ejemplo n.º 2
0
 def __init__(self, lat, lon, p1=None, p2=None, radius=None):
     self.lat = lat
     self.lon = lon
     if radius is not None:
         self.radius = radius
         self.start_angle = -180
         self.end_angle = 180
     else:
         # why these two distances are not necessary equal is a mystery
         self.radius = max(distance(self, p1), distance(self, p2))
         # FIXME maybe angles are ordered and should not be exchanged, check clockwise argument
         p1_heading = heading(self, p1)
         p2_heading = heading(self, p2)
         self.start_angle = min(p1_heading, p2_heading)
         self.end_angle = max(p1_heading, p2_heading)
Ejemplo n.º 3
0
 def is_closed(self, tol=2000):
     if self._closed:
         return True
     for p1 in self._before:
         for p2 in self._after:
             if distance(p1, p2) < tol:
                 self._closed = True
                 return True
     return False
Ejemplo n.º 4
0
def tasklen(angles, position, waypoints):
    dist = 0

    for theta, wp in zip(angles, waypoints):
        proj = destination(wp, wp.radius, theta)
        dist += distance(proj, position)
        position = proj

    return dist
Ejemplo n.º 5
0
def optimize(position, waypoints, prev_opti=None):
    x0 = np.zeros(len(waypoints)) if prev_opti is None else prev_opti
    result = minimize(tasklen, x0, args=(position, waypoints), tol=OPTIMIZER_PRECISION)

    distances = []
    fast_waypoints = [Turnpoint(position.lat, position.lon)]

    for theta, wp in zip(result.x, waypoints):
        proj = destination(wp, wp.radius, theta)
        distances.append(distance(proj, fast_waypoints[-1]))
        fast_waypoints.append(Turnpoint(proj[0], proj[1]))

    return Opti(sum(distances), distances, fast_waypoints, result.x)
Ejemplo n.º 6
0
    def __init__(self, task):

        # try to base64 decode the task
        if not os.path.isfile(task):
            try:
                task = base64.b64decode(task)
                task = json.loads(task)
            except TypeError:
                logging.debug(f'Task is not base64')

        else:
            with open(task, 'r') as f:
                task = json.load(f)

        # try to parse with every implemented format, raise if no match
        for task_format in [taskparse.XCTask, taskparse.PWCATask, taskparse.RawTask, taskparse.IGCLIBTask]:
            try:
                task = task_format(task)
                break
            except (KeyError, TypeError):
                logging.debug(f'Task format does not fit into {task_format}')

        if not hasattr(task, 'takeoff'):
            raise NotImplementedError('Task format not recognized')

        self.__dict__.update(task.__dict__)

        # if the goal is a line, we need a to compute its validation with the following technique
        # we compute the heading between the goal and the first previous turnpoint which has a different center
        # during validation, we compute the heading between the pilot and the goal center
        # when the absolute difference between these two headings is greater than 90~ish° (and is inside the goal radius), the goal is validated
        # not only does this allow us to validate goal line, but it also helps drawing goal lines in TaskCreator by directly having the line normal direction
        if self.goal_style == 'LINE':
            index_last_turnpoint = -2
            while distance(self.turnpoints[index_last_turnpoint], self.turnpoints[-1]) < 1:
                index_last_turnpoint -= 1
            self.last_leg_heading = heading(self.turnpoints[index_last_turnpoint], self.turnpoints[-1])

        self.opti = optimize(self.takeoff, self.turnpoints)
Ejemplo n.º 7
0
 def __eq__(self, other):
     return distance(*self.bounds) == distance(*other.bounds)
Ejemplo n.º 8
0
 def __gt__(self, other):
     return distance(*self.bounds) > distance(*other.bounds)
Ejemplo n.º 9
0
 def __lt__(self, other):
     return distance(*self.bounds) < distance(*other.bounds)
Ejemplo n.º 10
0
 def __contains__(self, point):
     return (distance(self, point) < self.radius) and (
         self.start_angle <= heading(self, point) <= self.end_angle)
Ejemplo n.º 11
0
 def __contains__(self, point):
     return distance(self, point) < self.radius
Ejemplo n.º 12
0
 def close_enough(self, wpt):
     # TODO delete when proper task validation
     return abs(distance(self, wpt) -
                wpt.radius) < 10 + wpt.radius * TOLERANCE
Ejemplo n.º 13
0
def triangle_length(points, flight):
    total_distance = distance(flight[points[0]], flight[points[1]])
    total_distance += distance(flight[points[1]], flight[points[2]])
    total_distance += distance(flight[points[2]], flight[points[0]])
    return -total_distance