Пример #1
0
def vertex_list():
    from searchspace.geometry import Point

    vertices = list()
    vertices.append(Point(1, 5))
    vertices.append(Point(4, 5))
    vertices.append(Point(4, 1))
    vertices.append(Point(1, 1))

    return vertices
Пример #2
0
def test_construct_from_two_points():
    """test_construct_from_two_points
    """

    from searchspace.geometry import Point, Line

    p1 = Point(0, 0)
    p2 = Point(1, 0)
    l = Line.construct_from_two_points(p1, p2)
    assert l.slope == 0
    assert l.y_intercept == 0
    assert l.x is None
Пример #3
0
def test_points_distance():
    """test_points_distance()
    """

    from searchspace.geometry import Point
    from searchspace.geometry import points_distance

    p1 = Point(1, 1)
    p2 = Point(1, 15)
    p3 = Point(1, 1)
    assert points_distance(p1, p1) == 0.0
    assert points_distance(p1, p3) == 0.0
    assert points_distance(p1, p2) == 14.0
Пример #4
0
def boundary_vertices():
    """boundary_vertices

    Fixture to provide search boundary vertices.
    """

    from searchspace.geometry import Point

    boundary_vertices = list()
    boundary_vertices.append(Point(18.1, -37.1))
    boundary_vertices.append(Point(18.1, -37.0))
    boundary_vertices.append(Point(18.0, -37.0))
    boundary_vertices.append(Point(18.0, -37.1))

    return boundary_vertices
Пример #5
0
def _starting_waypt():
    """_starting_waypt()

    Retrieve the starting position UTM coordinates from
    the config file and return the position as a Point.
    """

    auv_position = config['starting']['auv_position_utm'].split(',')
    logging.debug('_starting_waypt(): Setting AUV position {0}'.format(
        auv_position))
    return Point(float(auv_position[0]),
                 float(auv_position[1]))
Пример #6
0
def test_formula_from_points():
    """test_formula_from_points
    """

    from searchspace.geometry import formula_from_points, Point

    p1 = Point(0, 0)
    p2 = Point(1, 0)
    slope, y_intercept, x = formula_from_points(p1, p2)
    assert slope == 0
    assert y_intercept == 0
    assert x is None

    p2 = Point(0, 1)
    slope, y_intercept, x = formula_from_points(p1, p2)
    assert slope == float("inf")
    assert y_intercept == 0
    assert x == 0

    p1 = Point(1, 0)
    p2 = Point(1, 0)
    slope, y_intercept, x = formula_from_points(p1, p2)
    assert slope == float("inf")
    assert y_intercept is None
    assert x == 1

    p1 = Point(0, 0)
    p2 = Point(1, 1)
    slope, y_intercept, x = formula_from_points(p1, p2)
    assert slope == 1
    assert y_intercept == 0
    assert x is None

    p1 = Point(0, 0)
    p2 = Point(1, -1)
    slope, y_intercept, x = formula_from_points(p1, p2)
    assert slope == -1
    assert y_intercept == 0
    assert x is None
Пример #7
0
def test_point_is_inside(vertex_list):
    """test_point_is_inside
    """

    from searchspace.geometry import Point, Polygon

    inside_pt = Point(3, 4)
    outside_pt = Point(5, 7)
    on_the_edge_pt = Point(4, 3)
    rectangle = Polygon(vertex_list)

    assert rectangle.point_is_inside(inside_pt)
    assert not rectangle.point_is_inside(outside_pt)
    assert rectangle.point_is_inside(on_the_edge_pt)

    polygon = Polygon([Point(1, 5), Point(4, 5), Point(3, 1), Point(2, 1)])
    outside_pt = Point(1, 1)

    assert polygon.point_is_inside(inside_pt)
    assert not polygon.point_is_inside(outside_pt)
Пример #8
0
    def geo_to_cartesian(self, geo_position):
        """geo_to_cartesian()

        Convert the lat and lon from position to x and y
        in the local area. Cartesian (0, 0) is equivalent
        to Geo (_west_lon, _south_lat).
        """

        lat = geo_position[0]
        lon = geo_position[1]
        if (lat < self._south_lat or
            lat > self._north_lat or
            lon < self._west_lon or
            lon > self._east_lon):

            raise Exception('Position is outside the defined area.')

        x = lon_degrees_to_meters(lon - self._west_lon, self._center_lat)
        y = lat_degrees_to_meters(lat - self._south_lat, self._center_lat)

        return Point(x, y)
Пример #9
0
def test_construct_from_heading():
    """test_construct_from_heading
    """

    from searchspace.geometry import Point, Line

    p1 = Point(0, 1)
    l = Line.construct_from_heading(p1, 90)
    assert l.slope == 0
    assert l.y_intercept == 1
    assert l.x is None

    l = Line.construct_from_heading(p1, 0)
    assert l.slope == float("inf")
    assert l.y_intercept == 0
    assert l.x is 0

    l = Line.construct_from_heading(p1, 45)
    assert l.slope == pytest.approx(1.0, rel=0.0000001)
    assert l.y_intercept == 1
    assert l.x is None
Пример #10
0
def test_inside_the_boundaries(monkeypatch):
    """test_inside_the_boundaries()
    """
    from searchspace.searchspace import SearchSpace
    from searchspace.geometry import Point, Polygon

    s = SearchSpace()
    monkeypatch.setattr(
        s, '_boundary_polygon',
        Polygon(
            [Point(10, 300),
             Point(100, 300),
             Point(100, 100),
             Point(10, 100)]))

    inside_pt = Point(80, 150)
    outside_pt = Point(80, 310)
    on_the_edge = Point(99, 150)

    assert s._inside_the_boundaries(inside_pt)
    assert not s._inside_the_boundaries(outside_pt)
    assert s._inside_the_boundaries(on_the_edge)
Пример #11
0
    def move_toward_waypoint(self, waypoint):
        """move_toward_waypoint()

        Compare the current position of the AUV to the given
        waypoint. Calculate the distance and the bearing to
        the waypoint. If either is greater than the tolerance
        parameters, calculate the appropriate amounts to adjust
        the heading, depth, and speed of the AUV and effect
        those adjustments. Return 'MORE' to indicate the AUV
        is not yet close enough.

        Otherwise, if the AUV is within the tolerances for
        the waypoint, return 'DONE'.
        """

        self._current_waypoint['x'] = waypoint[0]
        self._current_waypoint['y'] = waypoint[1]
        self._current_waypoint['depth'] = waypoint[2]
        # Ignore waypoint[3]

        if self.distance_to_waypoint() > float(config['auv']['distance_tolerance']):
            logging.debug('move_toward_waypoint(): Moving toward the waypoint')
            bearing = bearing_to_point(
                Point(self._auv_data[config['variables']['easting_x']],
                      self._auv_data[config['variables']['northing_y']]),
                Point(self._current_waypoint['x'],
                      self._current_waypoint['y']))
            self.auv_control.publish_variable(
                config['variables']['set_heading'],
                bearing,
                -1)
            self.auv_control.publish_variable(
                config['variables']['set_depth'],
                self._current_waypoint['depth'] - self.altitude_safety(),
                -1)
            self.auv_control.publish_variable(
                config['variables']['set_speed'],
                float(config['auv']['max_speed']),
                -1)

            return 'MORE'

        elif (abs((self._current_waypoint['depth'] - self.altitude_safety()) -
                    self._auv_data[config['variables']['depth']]) >
                float(config['auv']['depth_tolerance'])):
            logging.debug('move_toward_waypoint(): Moving toward the depth')

            heading = self.turn_toward_heading(
                    int(self._auv_data[config['variables']['heading']]),
                    int(config['starting']['set']))
            self.auv_control.publish_variable(
                config['variables']['set_heading'],
                heading,
                -1)
            self.auv_control.publish_variable(
                config['variables']['set_depth'],
                self._current_waypoint['depth'] - self.altitude_safety(),
                -1)
            self.auv_control.publish_variable(
                config['variables']['set_speed'],
                float(config['auv']['depth_speed']),
                -1)

            return 'MORE'

        else:
            logging.debug('move_toward_waypoint(): Reached the waypoint and depth')
            return 'DONE'
Пример #12
0
def test_bearing_to_point():
    """test_bearing_to_point()
    """

    from math import tan
    from searchspace.geometry import Point
    from searchspace.geometry import bearing_to_point

    p1 = Point(1, 1)
    p2 = Point(1, 1)
    assert bearing_to_point(p1, p2) is None

    p1 = Point(1, 1)
    p2 = Point(10, 10)
    assert bearing_to_point(p1, p2) == 45

    p1 = Point(1, 1)
    p2 = Point(1, 10)
    assert bearing_to_point(p1, p2) == 0
    assert bearing_to_point(p2, p1) == 180

    p1 = Point(1, 1)
    p2 = Point(-5, 7)
    assert bearing_to_point(p1, p2) == 315

    p1 = Point(1, 1)
    p2 = Point(10, 1)
    assert bearing_to_point(p1, p2) == 90

    p1 = Point(1, 1)
    p2 = Point(-5, 1)
    assert bearing_to_point(p1, p2) == 270
Пример #13
0
def test_next_track_heading_and_waypt(monkeypatch):
    """test_next_track_heading_and_waypt

    """

    from searchspace.searchspace import SearchSpace
    from auv_bonus_xprize.settings import config
    from searchspace.geometry import Point, Line, Polygon

    config['starting']['auv_position_utm'] = '80,150'
    config['starting']['northwest_utm'] = '10,300'
    config['starting']['northeast_utm'] = '100,300'
    config['starting']['southeast_utm'] = '100,100'
    config['starting']['southwest_utm'] = '10,100'

    s = SearchSpace()
    monkeypatch.setattr(
        s, '_boundary_polygon',
        Polygon(
            [Point(10, 300),
             Point(100, 300),
             Point(100, 100),
             Point(10, 100)]))

    monkeypatch.setattr(
        s, '_northern_boundary',
        Line.construct_from_two_points(Point(10, 300), Point(100, 300)))

    monkeypatch.setattr(
        s, '_eastern_boundary',
        Line.construct_from_two_points(Point(100, 300), Point(100, 100)))
    monkeypatch.setattr(
        s, '_southern_boundary',
        Line.construct_from_two_points(Point(100, 100), Point(10, 100)))
    monkeypatch.setattr(
        s, '_western_boundary',
        Line.construct_from_two_points(Point(10, 100), Point(10, 300)))

    monkeypatch.setattr(s, '_current_set', 90)

    heading, waypt = s._next_track_heading_and_waypt(Point(80, 150))
    assert waypt.x == 80 and waypt.y == 300
    assert heading == 0

    monkeypatch.setattr(s, '_current_set', 270)
    heading, waypt = s._next_track_heading_and_waypt(Point(80, 150))
    assert waypt.x == 80 and waypt.y == 300
    assert heading == 0

    monkeypatch.setattr(s, '_current_set', 0)
    heading, waypt = s._next_track_heading_and_waypt(Point(80, 150))
    assert waypt.x == 10 and waypt.y == 150
    assert heading == 270

    monkeypatch.setattr(s, '_current_set', 135)
    heading, waypt = s._next_track_heading_and_waypt(Point(80, 105))
    assert waypt.x == 100 and waypt.y == 125
    assert heading == 45

    monkeypatch.setattr(s, '_current_set', 225)
    heading, waypt = s._next_track_heading_and_waypt(Point(80, 105))
    assert waypt.x == 10 and waypt.y == 175
    assert heading == 315
Пример #14
0
    def set_search_boundaries(self):
        """set_search_boundaries

        Calculate the horizontal search boundaries as lines offset
        from the configured contest boundaries by a buffer. The
        definition of the contest area vertices, as well as the
        buffer at the boundary, come from the configuration file.

        The results of this method are saved as instance variables
        named like _northern_boundary and are lines defined to
        work with UTM positions.

        https://www.latlong.net/lat-long-utm.html

        https://stackoverflow.com/questions/343865/how-to-convert-from-utm-to-latlng-in-python-or-javascript
        """

        boundary_buffer = round(float(config['search']['boundary_buffer_meters']))

        vertex_list = list()

        northwest_utm = config['starting']['northwest_utm'].split(',')
        northwest_vertex = Point(round(float(northwest_utm[0])) + boundary_buffer,
                                 round(float(northwest_utm[1])) - boundary_buffer)
        vertex_list.append(northwest_vertex)

        northeast_utm = config['starting']['northeast_utm'].split(',')
        northeast_vertex = Point(round(float(northeast_utm[0])) - boundary_buffer,
                                 round(float(northeast_utm[1])) - boundary_buffer)
        vertex_list.append(northeast_vertex)

        southeast_utm = config['starting']['southeast_utm'].split(',')
        southeast_vertex = Point(round(float(southeast_utm[0])) - boundary_buffer,
                                 round(float(southeast_utm[1])) + boundary_buffer)
        vertex_list.append(southeast_vertex)

        southwest_utm = config['starting']['southwest_utm'].split(',')
        southwest_vertex = Point(round(float(southwest_utm[0])) + boundary_buffer,
                                 round(float(southwest_utm[1])) + boundary_buffer)
        vertex_list.append(southwest_vertex)

        self._boundary_polygon = Polygon(vertex_list)

        self._northern_boundary = Line.construct_from_two_points(
            northwest_vertex,
            northeast_vertex)
        self._perimeter_length = points_distance(
            northwest_vertex,
            northeast_vertex)

        self._eastern_boundary = Line.construct_from_two_points(
            northeast_vertex,
            southeast_vertex)
        self._perimeter_length += points_distance(
            northeast_vertex,
            southeast_vertex)

        self._southern_boundary = Line.construct_from_two_points(
            southeast_vertex,
            southwest_vertex)
        self._perimeter_length += points_distance(
            southeast_vertex,
            southwest_vertex)

        self._western_boundary = Line.construct_from_two_points(
            southwest_vertex,
            northwest_vertex)
        self._perimeter_length += points_distance(
            southwest_vertex,
            northwest_vertex)