def test_triangle(self):
        triang = pycrcc.Triangle(0, 0, 10, 0, 4, 5)
        circ1 = pycrcc.Circle(2.5, 6, 7)
        self.assertEqual(triang.collide(circ1), 0)
        circ2 = pycrcc.Circle(2.5, 5, 7)
        self.assertEqual(triang.collide(circ2), 1)
        obb3 = pycrcc.RectOBB(1, 2, 0.6, 9, 3)
        self.assertEqual(triang.collide(obb3), 0)
        obb4 = pycrcc.RectOBB(1, 2, 0.4, 9, 3)
        self.assertEqual(triang.collide(obb4), 1)

        triang = pycrcc.Triangle(0, 0, 10, 0, 4, 5)

        triang2 = pycrcc.Triangle(10, 2, 2, 2, 5, 5)

        obb5 = pycrcc.RectOBB(1, 1.3, 0.6, 10.8, 0.8)

        self.assertEqual(triang.collide(obb5), 0)
        self.assertEqual(triang2.collide(obb5), 0)

        obb6 = pycrcc.RectOBB(1, 1.3, 0.6, 10.6, 0.6)
        self.assertEqual(triang.collide(obb6), 1)

        obb7 = pycrcc.RectOBB(1, 1.3, 0.6, 10.8, 0.6)
        self.assertEqual(triang.collide(obb7), 1)
        self.assertEqual(triang2.collide(obb7), 0)

        obb8 = pycrcc.RectOBB(1, 1.3, 0.6, 10.6, 1)

        self.assertEqual(triang.collide(obb8), 0)
        self.assertEqual(triang2.collide(obb8), 1)
    def test_OBBCircle(self):
        obb1 = pycrcc.RectOBB(1, 2, 0.2, 9, 10)
        obb2 = pycrcc.RectOBB(1, 2, 0.1, 9, 10)
        circ = pycrcc.Circle(2.5, 6, 7)

        self.assertEqual(obb1.collide(circ), 0)
        self.assertEqual(obb2.collide(circ), 1)
    def test_AABBCircle(self):
        aabb = pycrcc.RectAABB(2, 3, 3, 1.8)
        aabb2 = pycrcc.RectAABB(2, 3, 3, 1.7)
        circ = pycrcc.Circle(2.5, 6, 7)

        self.assertEqual(aabb.collide(circ), 1)
        self.assertEqual(aabb2.collide(circ), 0)
    def test_cc(self):

        aabb = pycrcc.RectAABB(2, 3, 3, 1.8)
        aabb2 = pycrcc.RectAABB(2, 3, 3, 1.7)
        circ = pycrcc.Circle(2.5, 6, 7)

        cc = pycrcc.CollisionChecker()
        cc.add_collision_object(aabb)
        obb1 = pycrcc.RectOBB(2, 1, 1.5, 6.0, 0)
        obb2 = pycrcc.RectOBB(2, 1, 1.5, 6.0, 20)

        self.assertEqual(cc.collide(circ), 1)

        tvo1 = pycrcc.TimeVariantCollisionObject(1)
        tvo1.append_obstacle(pycrcc.RectOBB(2, 1, 0.0, 2.0, 5))  # time step 1
        tvo1.append_obstacle(pycrcc.RectOBB(2, 1, 0.0, 2.5, 5))  # time step 2
        tvo1.append_obstacle(pycrcc.RectOBB(2, 1, 0.0, 3, 5))  # time step 3
        tvo1.append_obstacle(pycrcc.RectOBB(2, 1, 0.0, 3.5, 5))  # time step 4
        tvo1.append_obstacle(pycrcc.RectOBB(2, 1, 0.0, 4, 5))  # time step 5
        tvo1.append_obstacle(pycrcc.RectOBB(2, 1, 0.0, 4.5, 5))  # time step 6
        tvo1.append_obstacle(pycrcc.RectOBB(2, 1, 0.0, 5, 5))  # time step 7
        tvo1.append_obstacle(pycrcc.RectOBB(2, 1, 0.0, 5.5, 5))  # time step 8

        # Time variant obstacle that starts at time 4
        tvo2 = pycrcc.TimeVariantCollisionObject(4)
        tvo2.append_obstacle(pycrcc.RectOBB(2, 1, 1.5, 6.0, 0))  # time step 4
        tvo2.append_obstacle(pycrcc.RectOBB(2, 1, 1.5, 6.0, 2))  # time step 5
        tvo2.append_obstacle(pycrcc.RectOBB(2, 1, 1.5, 6.0, 3))  # time step 6
        tvo2.append_obstacle(pycrcc.RectOBB(2, 1, 1.5, 6.0, 4))  # time step 7
        tvo2.append_obstacle(pycrcc.RectOBB(2, 1, 1.5, 6.0, 5))  # time step 8
        tvo2.append_obstacle(pycrcc.RectOBB(2, 1, 1.5, 6.0, 6))  # time step 9
        tvo2.append_obstacle(pycrcc.RectOBB(2, 1, 1.5, 6.0, 7))  # time step 10

        cc = pycrcc.CollisionChecker()
        cc.add_collision_object(tvo2)
        obb1 = pycrcc.RectOBB(2, 1, 1.5, 6.0, 0)
        obb2 = pycrcc.RectOBB(2, 1, 1.5, 6.0, 20)
        self.assertEqual(tvo2.collide(obb1), 1)
        self.assertEqual(cc.collide(obb1), 1)
        self.assertEqual(cc.collide(obb2), 0)

        cc2 = pycrcc.CollisionChecker()

        cc2.add_collision_object(obb2)

        self.assertEqual(cc2.collide(tvo2), 0)

        cc2.add_collision_object(obb1)

        self.assertEqual(cc2.collide(tvo2), 1)

        cc3 = pycrcc.CollisionChecker()

        cc3.add_collision_object(tvo1)

        self.assertEqual(cc3.collide(tvo2), 1)

        tvo3 = pycrcc.TimeVariantCollisionObject(12)
        tvo3.append_obstacle(pycrcc.RectOBB(2, 1, 1.5, 6.0, 0))
        tvo3.append_obstacle(pycrcc.RectOBB(2, 1, 1.5, 6.0, 2))

        cc4 = pycrcc.CollisionChecker()
        cc4.add_collision_object(tvo2)
        cc4.add_collision_object(pycrcc.RectOBB(2, 1, 1.5, 6.0, 0))
        self.assertEqual(cc4.collide(tvo3), 1)
Example #5
0
def create_collision_object_circle(circle,
                                   params=None,
                                   collision_object_func=None):
    return pycrcc.Circle(circle.radius, circle.center[0], circle.center[1])
 def create_random_sphere(self):
     center = self.generate_random_vector()
     rad = abs(self.generate_random_xvalue())
     return pycrcc.Circle(rad, center[0], center[1])
def triangulate(bounds, vertices, input_triangles, output_triangles, params):
    """Fill the scenario with triangles using the Triangle Library by Jonathan Richard Shewchuk:
        https://www.cs.cmu.edu/~quake/triangle.html

        To use it, Triangle is called from the wrapper library "triangle"
        Step 1: Write the vertices and edges of the lane boundaries
        Step 2: Call Triangle
        Step 3: Read the triangles, construct them as collision objects, remove triangles that are in the road

    """

    #steiner_ratio: determines the maximum amount of steiner points based on the number of vertices of the input
    #eg: steiner_ratio = 0.1, 100 vertices => 0.1*100 = 10 steiner points allowed at most
    steiner_ratio = params.get('steiner_ratio', 0.1)
    steiner_max = (len(bounds) + len(vertices)) * steiner_ratio

    # Triangle call string, default options used:
    # - q quality mesh generation with minimal 20 degrees for each triangle
    # - S no additional steiner points
    # - c the points are enclosed by their convex hull, by default the option is only enabled if single vertices without
    #     edges are given
    # for further options see
    # http://dzhelil.info/triangle/index.html#api and https://www.cs.cmu.edu/~quake/triangle.switch.html
    # eg. call_options: 'S1000q25'
    defaul_calloptions = 'qS' + str(steiner_max)

    # Build triangles in the convex hull defined by the vertices, if vertices without edges are given as input
    if vertices:
        defaul_calloptions += 'c'
    call_options = 'p' + params.get('call_options' , defaul_calloptions)

    #Parameter that determines if the hole areas are written to file
    #Can be problematic when using section triangle representation
    input_holes = params.get('input_holes', False)

    #radius of the circles that are used for filtering triangles in the road
    #value of 0 leads to a point
    #a bigger radius can be used if some triangles between lanelets are not filtered
    #a small radius can be used if small triangles near the road are filtered unwarrented
    filter_radius = params.get('filter_radius', 0)

    # Make sets for nodes, segments, holes
    # The sets eliminate all duplicate elements, so each node/segment/hole is written to file only once.
    nodeset = set()
    segset = set()
    holeset = set()

    def addnode(vertex):
        # The required format for nodes is:  x, y
        # The index is added to each entry after all nodes have been added.
        nodeset.add((*vertex,))
     #Input all individual vertices, that don't have an edge
    for v in vertices:
        addnode(v)


    def addseg(v1, v2):
        # The required format for segments is: v1_index, v2_index
        # The frozenset makes sure that there are no duplicate edges with different order of vertices, ie. (v,w) and (w,v).
        t = tuple([tuple([*v1]), tuple([*v2])]) #wrapping vertices for frozenset
        segset.add(frozenset(t))

    def addedge(v1, v2):
        addnode(v1)
        addnode(v2)
        addseg(v1, v2)
    # Input all edges from the lanelet boundaries
    for bound in bounds:
        addedge(*bound)

    def addhole(v1, v2, v3):
        # The required format for holes is: x, y
        # A hole marks an area where no triangles should be generated.
        # In this case, each input triangles defines a hole area, so that the road is not triangulated.
        center = (v1 + v2 + v3) / 3
        holeset.add((*center,))

    # Input holes from input_triangles
    if input_holes:
        for t in input_triangles.unpack():
            vertices = t.vertices()
            vertices = [np.array(v) for v in vertices]
            addhole(*vertices)

    # Convert each set so that they apply to the required format
    def map_segment(entry, vertices):
        v1, v2 = entry
        v1_index = [i for i, entry in enumerate(vertices) if entry == v1][0]
        v2_index = [i for i, entry in enumerate(vertices) if entry == v2][0]
        return (v1_index, v2_index)

    vertices = [node for node in nodeset]
    #the if condition eliminates edges that have two identical vertices as endpoints
    segset = set([map_segment(entry, vertices) for entry in segset if len(entry) == 2])
    vertices = np.array(vertices)
    segments = np.array([seg for seg in segset])
    holes = np.array([hole for hole in holeset])

    if(holes):
        output = triangle.triangulate({'vertices': vertices, 'segments': segments, 'holes': holes}, call_options)
    else:
        output = triangle.triangulate({'vertices': vertices, 'segments': segments}, call_options)

    vertices = output.get('vertices')
    tris  = output.get('triangles')

    for t in tris:
        points = [vertices[index] for index in t]
        a, b, c = (points[0], points[1], points[2])
        collision_triangle = pycrcc.Triangle(*a, *b, *c)

        # remove problem spots:
        middle = (a + b + c) / 3
        if filter_radius == 0:
            middle_point = pycrcc.Point(*middle)
        else:
            middle_point = pycrcc.Circle(filter_radius, *middle)

        # uncomment for drawing middle points
        # draw_object(middle_point, draw_params={'collision': {'circle': {'facecolor': '#1f78b4', 'zorder': 30, 'edgecolor' :'#000000'}}})
        if not input_triangles or not middle_point.collide(input_triangles):
            output_triangles.add_shape(collision_triangle)