class test_Intersection(unittest.TestCase):
    def setUp(self):

        self.configuration = Configuration()
        outputDir = os.path.join(os.getcwd(), 'output')
        lastId = 0
        self.seed = 2
        self.builder = SequentialJunctionBuilder(minAngle=np.pi / 4,
                                                 maxAngle=np.pi * .75,
                                                 straightRoadLen=10,
                                                 probLongConnection=0.5,
                                                 probMinAngle=0.5,
                                                 probRestrictedLane=0.2,
                                                 maxConnectionLength=30,
                                                 minConnectionLength=12,
                                                 random_seed=self.seed)

        self.randomState = self.configuration.get("random_state")

        pass

    def test_getIncidentPoints(self):

        maxNumberOfRoadsPerJunction = 4
        path = self.configuration.get("harvested_straight_roads")
        intersection = self.builder.createWithRandomLaneConfigurations(
            path,
            0,
            maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
            maxLanePerSide=2,
            minLanePerSide=0,
            internalConnections=True,
            cp1=pyodrx.ContactPoint.end,
            internalLinkStrategy=LaneConfigurationStrategies.SPLIT_FIRST,
            getAsOdr=False)

        odr = intersection.odr

        xmlPath = f"output/test_getIncidentPoints-split-first-{maxNumberOfRoadsPerJunction}.xodr"
        odr.write_xml(xmlPath)

        incidentPoints = intersection.getIncidentPoints()
        translatedPoints = intersection.getIncidentPointsTranslatedToCenter()
        print(f"width and height: {intersection.getWH()}")
        print(incidentPoints)
        print(translatedPoints)

        extensions.printRoadPositions(odr)

        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))
Пример #2
0
class test_SequentialJunctionBuilder(unittest.TestCase):
    def setUp(self):

        self.configuration = Configuration()
        outputDir = os.path.join(os.getcwd(), 'output')
        lastId = 0
        self.seed = 2
        self.builder = SequentialJunctionBuilder(minAngle=np.pi / 10,
                                                 maxAngle=np.pi * .75,
                                                 straightRoadLen=5,
                                                 probLongConnection=0.5,
                                                 probMinAngle=0.5,
                                                 probRestrictedLane=0.2,
                                                 maxConnectionLength=50,
                                                 minConnectionLength=20,
                                                 random_seed=self.seed)

        self.randomState = self.configuration.get("random_state")
        self.validator = IntersectionValidator()

        pass

    def test_drawLikeAPainter2L(self):
        maxNumberOfRoadsPerJunction = 3
        odr = self.builder.drawLikeAPainter2L(
            odrId=0, maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction)
        extensions.printRoadPositions(odr)
        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))

        xmlPath = f"output/test_drawLikeAPainter2L-{maxNumberOfRoadsPerJunction}.xodr"
        odr.write_xml(xmlPath)

        maxNumberOfRoadsPerJunction = 4
        odr = self.builder.drawLikeAPainter2L(
            odrId=0, maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction)
        extensions.printRoadPositions(odr)
        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))

        xmlPath = f"output/test_drawLikeAPainter2L-{maxNumberOfRoadsPerJunction}.xodr"
        odr.write_xml(xmlPath)

        maxNumberOfRoadsPerJunction = 5
        odr = self.builder.drawLikeAPainter2L(
            odrId=0, maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction)
        extensions.printRoadPositions(odr)
        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))

        xmlPath = f"output/test_drawLikeAPainter2L-{maxNumberOfRoadsPerJunction}.xodr"
        odr.write_xml(xmlPath)

        maxNumberOfRoadsPerJunction = 6
        odr = self.builder.drawLikeAPainter2L(
            odrId=0, maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction)
        extensions.printRoadPositions(odr)
        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))

        xmlPath = f"output/test_drawLikeAPainter2L-{maxNumberOfRoadsPerJunction}.xodr"
        odr.write_xml(xmlPath)

    def test_drawLikeAPainter2LWihtoutInternalConnections(self):
        maxNumberOfRoadsPerJunction = 5
        odr = self.builder.drawLikeAPainter2L(
            odrId=0,
            maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
            internalConnections=False)
        extensions.printRoadPositions(odr)
        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))
        xmlPath = f"output/test_drawLikeAPainter2LWihtoutInternalConnections.xodr"
        odr.write_xml(xmlPath)

    def test_createWithRandomLaneConfigurations(self):

        maxNumberOfRoadsPerJunction = 4
        path = self.configuration.get("harvested_straight_roads")
        odr = self.builder.createWithRandomLaneConfigurations(
            path,
            0,
            maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
            maxLanePerSide=2,
            minLanePerSide=0,
            internalConnections=True,
            cp1=pyodrx.ContactPoint.end,
            internalLinkStrategy=LaneConfigurationStrategies.SPLIT_FIRST,
            restrictedLanes=True)

        xmlPath = f"output/test_createWithRandomLaneConfigurations-split-first-{maxNumberOfRoadsPerJunction}.xodr"
        odr.write_xml(xmlPath)

        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))

        maxNumberOfRoadsPerJunction = 3
        path = self.configuration.get("harvested_straight_roads")
        odr = self.builder.createWithRandomLaneConfigurations(
            path,
            0,
            maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
            maxLanePerSide=2,
            minLanePerSide=0,
            internalConnections=True,
            cp1=pyodrx.ContactPoint.end,
            internalLinkStrategy=LaneConfigurationStrategies.SPLIT_LAST,
            uTurnLanes=1,
            restrictedLanes=True)

        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))
        xmlPath = f"output/test_createWithRandomLaneConfigurations-split-last-{maxNumberOfRoadsPerJunction}.xodr"
        odr.write_xml(xmlPath)

        maxNumberOfRoadsPerJunction = 5
        path = self.configuration.get("harvested_straight_roads")
        odr = self.builder.createWithRandomLaneConfigurations(
            path,
            0,
            maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
            maxLanePerSide=2,
            minLanePerSide=0,
            internalConnections=True,
            cp1=pyodrx.ContactPoint.end,
            internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY,
            restrictedLanes=True)

        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))
        xmlPath = f"output/test_createWithRandomLaneConfigurations-split-any-{maxNumberOfRoadsPerJunction}.xodr"
        odr.write_xml(xmlPath)

        maxNumberOfRoadsPerJunction = 6
        path = self.configuration.get("harvested_straight_roads")
        odr = self.builder.createWithRandomLaneConfigurations(
            path,
            0,
            maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
            maxLanePerSide=2,
            minLanePerSide=0,
            internalConnections=True,
            cp1=pyodrx.ContactPoint.end,
            internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY)

        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))
        xmlPath = f"output/test_createWithRandomLaneConfigurations-split-any-{maxNumberOfRoadsPerJunction}.xodr"
        odr.write_xml(xmlPath)

        maxNumberOfRoadsPerJunction = 8
        path = self.configuration.get("harvested_straight_roads")
        odr = self.builder.createWithRandomLaneConfigurations(
            path,
            0,
            maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
            maxLanePerSide=2,
            minLanePerSide=0,
            internalConnections=True,
            cp1=pyodrx.ContactPoint.end,
            internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY)

        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))
        xmlPath = f"output/test_createWithRandomLaneConfigurations-split-any-{maxNumberOfRoadsPerJunction}.xodr"
        odr.write_xml(xmlPath)

    def test_equalAngles(self):

        maxNumberOfRoadsPerJunction = 4
        path = self.configuration.get("harvested_straight_roads")
        odr = self.builder.createWithRandomLaneConfigurations(
            path,
            0,
            maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
            maxLanePerSide=2,
            minLanePerSide=0,
            internalConnections=True,
            cp1=pyodrx.ContactPoint.end,
            internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY,
            equalAngles=True)

        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))
        xmlPath = f"output/test_createWithRandomLaneConfigurations-split-any-{maxNumberOfRoadsPerJunction}.xodr"
        odr.write_xml(xmlPath)

        maxNumberOfRoadsPerJunction = 4
        path = self.configuration.get("harvested_straight_roads")
        odr = self.builder.createWithRandomLaneConfigurations(
            path,
            0,
            maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
            maxLanePerSide=2,
            minLanePerSide=0,
            internalConnections=True,
            cp1=pyodrx.ContactPoint.end,
            internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY,
            equalAngles=True)

        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))
        xmlPath = f"output/test_createWithRandomLaneConfigurations-split-any-{maxNumberOfRoadsPerJunction}.xodr"
        odr.write_xml(xmlPath)

        maxNumberOfRoadsPerJunction = 3
        path = self.configuration.get("harvested_straight_roads")
        odr = self.builder.createWithRandomLaneConfigurations(
            path,
            0,
            maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
            maxLanePerSide=2,
            minLanePerSide=0,
            internalConnections=True,
            cp1=pyodrx.ContactPoint.end,
            internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY,
            equalAngles=True)

        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))
        xmlPath = f"output/test_createWithRandomLaneConfigurations-split-any-{maxNumberOfRoadsPerJunction}.xodr"
        odr.write_xml(xmlPath)

        maxNumberOfRoadsPerJunction = 5
        path = self.configuration.get("harvested_straight_roads")
        odr = self.builder.createWithRandomLaneConfigurations(
            path,
            0,
            maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
            maxLanePerSide=2,
            minLanePerSide=0,
            internalConnections=True,
            cp1=pyodrx.ContactPoint.end,
            internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY,
            equalAngles=True)

        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))
        xmlPath = f"output/test_createWithRandomLaneConfigurations-split-any-{maxNumberOfRoadsPerJunction}.xodr"
        odr.write_xml(xmlPath)

        maxNumberOfRoadsPerJunction = 6
        path = self.configuration.get("harvested_straight_roads")
        odr = self.builder.createWithRandomLaneConfigurations(
            path,
            0,
            maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
            maxLanePerSide=2,
            minLanePerSide=0,
            internalConnections=True,
            cp1=pyodrx.ContactPoint.end,
            internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY,
            equalAngles=True)

        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))
        xmlPath = f"output/test_createWithRandomLaneConfigurations-split-any-{maxNumberOfRoadsPerJunction}.xodr"
        odr.write_xml(xmlPath)

    def test_6PlusLanes(self):

        maxNumberOfRoadsPerJunction = 7
        path = self.configuration.get("harvested_straight_roads")
        odr = self.builder.createWithRandomLaneConfigurations(
            path,
            0,
            maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
            maxLanePerSide=2,
            minLanePerSide=0,
            internalConnections=True,
            cp1=pyodrx.ContactPoint.end,
            internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY)

        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))
        xmlPath = f"output/test_createWithRandomLaneConfigurations-split-any-{maxNumberOfRoadsPerJunction}.xodr"
        odr.write_xml(xmlPath)

        maxNumberOfRoadsPerJunction = 8
        path = self.configuration.get("harvested_straight_roads")
        odr = self.builder.createWithRandomLaneConfigurations(
            path,
            0,
            maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
            maxLanePerSide=2,
            minLanePerSide=0,
            internalConnections=True,
            cp1=pyodrx.ContactPoint.end,
            internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY)

        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))
        xmlPath = f"output/test_createWithRandomLaneConfigurations-split-any-{maxNumberOfRoadsPerJunction}.xodr"
        odr.write_xml(xmlPath)

        maxNumberOfRoadsPerJunction = 8
        path = self.configuration.get("harvested_straight_roads")
        odr = self.builder.createWithRandomLaneConfigurations(
            path,
            0,
            maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
            maxLanePerSide=2,
            minLanePerSide=0,
            internalConnections=True,
            cp1=pyodrx.ContactPoint.end,
            internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY,
            equalAngles=True)

        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))
        xmlPath = f"output/test_createWithRandomLaneConfigurations-split-any-{maxNumberOfRoadsPerJunction}.xodr"
        odr.write_xml(xmlPath)

        maxNumberOfRoadsPerJunction = 8
        path = self.configuration.get("harvested_straight_roads")
        odr = self.builder.createWithRandomLaneConfigurations(
            path,
            0,
            maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
            maxLanePerSide=2,
            minLanePerSide=0,
            internalConnections=True,
            cp1=pyodrx.ContactPoint.end,
            internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY)

        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))
        xmlPath = f"output/test_createWithRandomLaneConfigurations-split-any-{maxNumberOfRoadsPerJunction}.xodr"
        odr.write_xml(xmlPath)

        maxNumberOfRoadsPerJunction = 9
        path = self.configuration.get("harvested_straight_roads")
        odr = self.builder.createWithRandomLaneConfigurations(
            path,
            0,
            maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
            maxLanePerSide=2,
            minLanePerSide=0,
            internalConnections=True,
            cp1=pyodrx.ContactPoint.end,
            internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY)

        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))
        xmlPath = f"output/test_createWithRandomLaneConfigurations-split-any-{maxNumberOfRoadsPerJunction}.xodr"
        odr.write_xml(xmlPath)

    def test_TJunctions(self):

        maxNumberOfRoadsPerJunction = 3
        maxLanePerSide = 1
        minLanePerSide = 1

        for sl in range(5):
            path = self.configuration.get("harvested_straight_roads")
            odr = self.builder.createWithRandomLaneConfigurations(
                path,
                0,
                maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
                maxLanePerSide=maxLanePerSide,
                minLanePerSide=minLanePerSide,
                internalConnections=True,
                cp1=pyodrx.ContactPoint.end,
                internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY,
                uTurnLanes=0)

            # xmlPath = f"output/test_createWithRandomLaneConfigurations-split-any-{maxNumberOfRoadsPerJunction}-{sl}.xodr"
            xmlPath = f"output/seed-{self.seed}-{maxNumberOfRoadsPerJunction}-way-{sl}.xodr"
            odr.write_xml(xmlPath)

            extensions.view_road(
                odr, os.path.join('..', self.configuration.get("esminipath")))
            extensions.saveRoadImageFromFile(
                xmlPath, self.configuration.get("esminipath"))

    def test_4WayJunctions(self):

        maxNumberOfRoadsPerJunction = 4
        maxLanePerSide = 1
        minLanePerSide = 1

        for sl in range(5):
            path = self.configuration.get("harvested_straight_roads")
            intersection = self.builder.createWithRandomLaneConfigurations(
                path,
                sl,
                maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
                maxLanePerSide=maxLanePerSide,
                minLanePerSide=minLanePerSide,
                internalConnections=True,
                cp1=pyodrx.ContactPoint.end,
                internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY,
                getAsOdr=False)

            odr = intersection.odr
            # xmlPath = f"output/test_createWithRandomLaneConfigurations-split-any-{maxNumberOfRoadsPerJunction}-{sl}.xodr"
            xmlPath = f"output/seed-{self.seed}-{maxNumberOfRoadsPerJunction}-way-{sl}.xodr"
            odr.write_xml(xmlPath)
            isValid = self.validator.validateIncidentPoints(
                intersection, self.builder.minConnectionLength)
            # if isValid == False:
            #     print(f"{sl} is an invalid intersection")
            plt = extensions.view_road(
                odr,
                os.path.join('..', self.configuration.get("esminipath")),
                returnPlt=True)
            if isValid == False:
                plt.title("Invalid")
            else:
                plt.title("Valid")
            plt.show()
            extensions.saveRoadImageFromFile(
                xmlPath, self.configuration.get("esminipath"))

    def test_5WayJunctions(self):

        maxNumberOfRoadsPerJunction = 5
        maxLanePerSide = 3
        minLanePerSide = 0

        for sl in range(5):
            path = self.configuration.get("harvested_straight_roads")
            intersection = self.builder.createWithRandomLaneConfigurations(
                path,
                sl,
                maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
                maxLanePerSide=maxLanePerSide,
                minLanePerSide=minLanePerSide,
                internalConnections=True,
                cp1=pyodrx.ContactPoint.end,
                internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY,
                getAsOdr=False)

            odr = intersection.odr
            # xmlPath = f"output/test_createWithRandomLaneConfigurations-split-any-{maxNumberOfRoadsPerJunction}-{sl}.xodr"
            xmlPath = f"output/seed-{self.seed}-{maxNumberOfRoadsPerJunction}-way-{sl}.xodr"
            odr.write_xml(xmlPath)
            isValid = self.validator.validateIncidentPoints(
                intersection, self.builder.minConnectionLength)
            # if isValid == False:
            #     print(f"{sl} is an invalid intersection")
            plt = extensions.view_road(
                odr,
                os.path.join('..', self.configuration.get("esminipath")),
                returnPlt=True)
            if isValid == False:
                plt.title("Invalid")
            else:
                plt.title("Valid")
            plt.show()
            extensions.saveRoadImageFromFile(
                xmlPath, self.configuration.get("esminipath"))

    def test_6WayJunctions(self):

        maxNumberOfRoadsPerJunction = 6
        maxLanePerSide = 2
        minLanePerSide = 0

        for sl in range(5):
            path = self.configuration.get("harvested_straight_roads")
            intersection = self.builder.createWithRandomLaneConfigurations(
                path,
                sl,
                maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
                maxLanePerSide=maxLanePerSide,
                minLanePerSide=minLanePerSide,
                internalConnections=True,
                cp1=pyodrx.ContactPoint.end,
                internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY,
                getAsOdr=False)

            odr = intersection.odr
            # xmlPath = f"output/test_createWithRandomLaneConfigurations-split-any-{maxNumberOfRoadsPerJunction}-{sl}.xodr"
            xmlPath = f"output/seed-{self.seed}-{maxNumberOfRoadsPerJunction}-way-{sl}.xodr"
            odr.write_xml(xmlPath)
            extensions.printRoadPositions(odr)
            isValid = self.validator.validateIncidentPoints(
                intersection, self.builder.minConnectionLength)
            # if isValid == False:
            #     print(f"{sl} is an invalid intersection")
            plt = extensions.view_road(
                odr,
                os.path.join('..', self.configuration.get("esminipath")),
                returnPlt=True)
            if isValid == False:
                plt.title(f"Invalid - {xmlPath}")
            else:
                plt.title(f"Valid - {xmlPath}")
            plt.show()
            extensions.saveRoadImageFromFile(
                xmlPath, self.configuration.get("esminipath"))

    def test_7WayJunctions(self):

        maxNumberOfRoadsPerJunction = 7
        maxLanePerSide = 2
        minLanePerSide = 0

        for sl in range(5):
            path = self.configuration.get("harvested_straight_roads")
            intersection = self.builder.createWithRandomLaneConfigurations(
                path,
                sl,
                maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
                maxLanePerSide=maxLanePerSide,
                minLanePerSide=minLanePerSide,
                internalConnections=True,
                cp1=pyodrx.ContactPoint.end,
                internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY,
                getAsOdr=False)

            odr = intersection.odr
            # xmlPath = f"output/test_createWithRandomLaneConfigurations-split-any-{maxNumberOfRoadsPerJunction}-{sl}.xodr"
            xmlPath = f"output/seed-{self.seed}-{maxNumberOfRoadsPerJunction}-way-{sl}.xodr"
            odr.write_xml(xmlPath)
            extensions.printRoadPositions(odr)
            isValid = self.validator.validateIncidentPoints(
                intersection, self.builder.minConnectionLength)
            # if isValid == False:
            #     print(f"{sl} is an invalid intersection")
            plt = extensions.view_road(
                odr,
                os.path.join('..', self.configuration.get("esminipath")),
                returnPlt=True)
            if isValid == False:
                plt.title(f"Invalid - {xmlPath}")
            else:
                plt.title(f"Valid - {xmlPath}")
            plt.show()
            extensions.saveRoadImageFromFile(
                xmlPath, self.configuration.get("esminipath"))

    def test_7WayJunctionsEQA(self):

        maxNumberOfRoadsPerJunction = 7
        maxLanePerSide = 2
        minLanePerSide = 0

        for sl in range(5):
            path = self.configuration.get("harvested_straight_roads")
            intersection = self.builder.createWithRandomLaneConfigurations(
                path,
                sl,
                maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
                maxLanePerSide=maxLanePerSide,
                minLanePerSide=minLanePerSide,
                internalConnections=True,
                cp1=pyodrx.ContactPoint.end,
                internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY,
                equalAngles=True,
                getAsOdr=False)

            odr = intersection.odr
            # xmlPath = f"output/test_createWithRandomLaneConfigurations-split-any-{maxNumberOfRoadsPerJunction}-{sl}.xodr"
            xmlPath = f"output/seed-{self.seed}-{maxNumberOfRoadsPerJunction}-way-{sl}.xodr"
            odr.write_xml(xmlPath)
            extensions.printRoadPositions(odr)
            isValid = self.validator.validateIncidentPoints(
                intersection, self.builder.minConnectionLength)
            # if isValid == False:
            #     print(f"{sl} is an invalid intersection")
            plt = extensions.view_road(
                odr,
                os.path.join('..', self.configuration.get("esminipath")),
                returnPlt=True)
            if isValid == False:
                plt.title(f"Invalid - {xmlPath}")
            else:
                plt.title(f"Valid - {xmlPath}")
            plt.show()
            extensions.saveRoadImageFromFile(
                xmlPath, self.configuration.get("esminipath"))

    def test_8PlusWayJunctions(self):

        maxNumberOfRoadsPerJunction = 20
        maxLanePerSide = 2
        minLanePerSide = 0

        for sl in range(5):
            path = self.configuration.get("harvested_straight_roads")
            odr = self.builder.createWithRandomLaneConfigurations(
                path,
                0,
                maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
                maxLanePerSide=maxLanePerSide,
                minLanePerSide=minLanePerSide,
                internalConnections=True,
                cp1=pyodrx.ContactPoint.end,
                internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY)

            # xmlPath = f"output/test_createWithRandomLaneConfigurations-split-any-{maxNumberOfRoadsPerJunction}-{sl}.xodr"
            xmlPath = f"output/seed-{self.seed}-{maxNumberOfRoadsPerJunction}-way-{sl}.xodr"
            odr.write_xml(xmlPath)

            # extensions.view_road(odr,os.path.join('..',self.configuration.get("esminipath")))
            extensions.saveRoadImageFromFile(
                xmlPath, self.configuration.get("esminipath"))
            maxNumberOfRoadsPerJunction += 1

    def test_4WayJunctionsEqualAngles(self):

        maxNumberOfRoadsPerJunction = 4
        maxLanePerSide = 1
        minLanePerSide = 1

        for sl in range(5):
            path = self.configuration.get("harvested_straight_roads")
            odr = self.builder.createWithRandomLaneConfigurations(
                path,
                0,
                maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
                maxLanePerSide=maxLanePerSide,
                minLanePerSide=minLanePerSide,
                internalConnections=True,
                cp1=pyodrx.ContactPoint.end,
                internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY,
                equalAngles=True)

            # xmlPath = f"output/test_createWithRandomLaneConfigurations-split-any-{maxNumberOfRoadsPerJunction}-{sl}.xodr"
            xmlPath = f"output/seed-{self.seed}-{maxNumberOfRoadsPerJunction}-way-eq-{sl}.xodr"
            odr.write_xml(xmlPath)

            extensions.view_road(
                odr, os.path.join('..', self.configuration.get("esminipath")))
            extensions.saveRoadImageFromFile(
                xmlPath, self.configuration.get("esminipath"))

    def test_SafeMinConnectionLengthForEqualAngle(self):

        sl = 0

        maxNumberOfRoadsPerJunction = 8
        sl += 1
        path = self.configuration.get("harvested_straight_roads")
        odr = self.builder.createWithRandomLaneConfigurations(
            path,
            0,
            maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
            maxLanePerSide=3,
            minLanePerSide=0,
            internalConnections=True,
            cp1=pyodrx.ContactPoint.end,
            internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY,
            restrictedLanes=1,
            equalAngles=True)
        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))
        xmlPath = f"output/test_createWithRandomLaneConfigurations-split-any-{maxNumberOfRoadsPerJunction}-{sl}.xodr"
        odr.write_xml(xmlPath)

        maxNumberOfRoadsPerJunction = 8
        sl += 1
        path = self.configuration.get("harvested_straight_roads")
        odr = self.builder.createWithRandomLaneConfigurations(
            path,
            0,
            maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
            maxLanePerSide=2,
            minLanePerSide=0,
            internalConnections=True,
            cp1=pyodrx.ContactPoint.end,
            internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY,
            restrictedLanes=1,
            equalAngles=True)
        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))
        xmlPath = f"output/test_createWithRandomLaneConfigurations-split-any-{maxNumberOfRoadsPerJunction}-{sl}.xodr"
        odr.write_xml(xmlPath)

        maxNumberOfRoadsPerJunction = 8
        sl += 1
        path = self.configuration.get("harvested_straight_roads")
        odr = self.builder.createWithRandomLaneConfigurations(
            path,
            0,
            maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
            maxLanePerSide=2,
            minLanePerSide=0,
            internalConnections=True,
            cp1=pyodrx.ContactPoint.end,
            internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY,
            restrictedLanes=1,
            equalAngles=True)
        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))
        xmlPath = f"output/test_createWithRandomLaneConfigurations-split-any-{maxNumberOfRoadsPerJunction}-{sl}.xodr"
        odr.write_xml(xmlPath)

        maxNumberOfRoadsPerJunction = 8
        sl += 1
        path = self.configuration.get("harvested_straight_roads")
        odr = self.builder.createWithRandomLaneConfigurations(
            path,
            0,
            maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction,
            maxLanePerSide=2,
            minLanePerSide=0,
            internalConnections=True,
            cp1=pyodrx.ContactPoint.end,
            internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY,
            restrictedLanes=1,
            equalAngles=True)
        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))
        xmlPath = f"output/test_createWithRandomLaneConfigurations-split-any-{maxNumberOfRoadsPerJunction}-{sl}.xodr"
        odr.write_xml(xmlPath)
Пример #3
0
class HDMapBuilder:

    def __init__(self, nIntersections, p=[0.2, 0.7, 0.1, 0.1], startId=0, seed=0, mapSize=(500, 500), cellSize=(100, 100), debug=True) -> None:

        self.nIntersections = nIntersections
        self.p = p # probability distribution of 3-way, 4, 5, 6
        self.intersections = {} # DirectionIntersection -> intersection
        self.placedIntersections = {}
        self.rotation = {}
        self.nextIntersectionId = startId
        
        self.seed = seed
        self.builder = SequentialJunctionBuilder(
                                                    minAngle=np.pi/6, 
                                                    maxAngle=np.pi * .75,
                                                    straightRoadLen=1, 
                                                    probLongConnection=0.3,
                                                    probMinAngle=0.1,
                                                    probRestrictedLane=0,
                                                    maxConnectionLength=30,
                                                    minConnectionLength=12,
                                                    random_seed=self.seed)

        self.moreThan4Builder = SequentialJunctionBuilder(
                                                    minAngle=np.pi/10, 
                                                    maxAngle=np.pi * .75,
                                                    straightRoadLen=1, 
                                                    probLongConnection=0.5,
                                                    probMinAngle=0.5,
                                                    probRestrictedLane=0,
                                                    maxConnectionLength=50,
                                                    minConnectionLength=20,
                                                    random_seed=self.seed)


        self.validator = IntersectionValidator()
        self.intersectionAdapter = IntersectionAdapter()
        
        self.grid = Grid(size=mapSize, cellSize=cellSize)

        self.mapBuilder = MapBuilder(self.grid, [], random_seed=40)

        self.network = None

        self.debug = debug

        self.name = "HDMapBuilder"

        self.nextRoadId = 0

        pass


    def createIntersections(self):

        print(f"{self.name}: createIntersections")
        minLanePerSide = 1
        maxLanePerSide = 2
        self.nextRoadId = 0
        for sl in range(self.nIntersections):
            print(f"{self.name}: creating {sl + 1}")
            maxNumberOfRoadsPerJunction = np.random.choice([3, 4, 5], p=[0.6, 0.375, 0.025])
            intersection = self.createValidIntersection(sl, self.nextRoadId, maxNumberOfRoadsPerJunction, minLanePerSide, maxLanePerSide)
            
            self.nextRoadId = intersection.getLastRoadId() + 100
            directionIntersection = self.intersectionAdapter.intersectionTo4DirectionIntersection(intersection)
            self.intersections[directionIntersection] = intersection

    
    def createValidIntersection(self, id, firstRoadId, maxNumberOfRoadsPerJunction, minLanePerSide, maxLanePerSide, rotate=False):

        isEqualAngle = np.random.choice([False, True], p=[0.3, 0.7])
        minConnectionLength = self.builder.minConnectionLength

        if maxNumberOfRoadsPerJunction < 5:
            intersection = self.builder.createWithRandomLaneConfigurations("", 
                                id, 
                                firstRoadId=firstRoadId,
                                maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction, 
                                maxLanePerSide=maxLanePerSide, 
                                minLanePerSide=minLanePerSide, 
                                internalConnections=True, 
                                cp1=pyodrx.ContactPoint.end,
                                internalLinkStrategy = LaneConfigurationStrategies.SPLIT_ANY,
                                equalAngles=isEqualAngle,
                                getAsOdr=False)
        else:
            minConnectionLength = self.moreThan4Builder.minConnectionLength
            intersection = self.moreThan4Builder.createWithRandomLaneConfigurations("", 
                                id, 
                                firstRoadId=firstRoadId,
                                maxNumberOfRoadsPerJunction=maxNumberOfRoadsPerJunction, 
                                maxLanePerSide=maxLanePerSide, 
                                minLanePerSide=minLanePerSide, 
                                internalConnections=True, 
                                cp1=pyodrx.ContactPoint.end,
                                internalLinkStrategy = LaneConfigurationStrategies.SPLIT_ANY,
                                equalAngles=isEqualAngle,
                                getAsOdr=False)

        while (self.validator.validateIncidentPoints(intersection, minConnectionLength) == False):
            intersection = self.createValidIntersection(id, self.nextRoadId, maxNumberOfRoadsPerJunction, minLanePerSide, maxLanePerSide)

        if rotate:
            # self.rotation[intersection] = np.random.uniform(0, np.pi/10)
            self.rotation[intersection] = np.random.choice([np.pi/2, np.pi, np.pi * 1.5])
            intersection.transform(startX=0, startY=0, heading=self.rotation[intersection])
            
        return intersection


    def connectIntersectionsByCellAdjacency(self):
        
        self.network = Network(self.placedIntersections)
        for cell in self.grid.cellGenerator():
            if isinstance(cell.element, DirectionIntersection):
                couldConnect = False
                DI1 = cell.element
                # We need to check right and top only as left and bottoms are traversed before.
                if DI1.top.hasRoads():
                    DI2 = self.grid.topElement(cell)
                    if DI2 is not None and isinstance(DI2, DirectionIntersection):
                        if DI2.bot.hasRoads():
                            # We have a connection
                            quad1 = DI1.top
                            quad2 = DI2.bot
                            self.connectDirectionQuadrants(DI1, DI2, quad1, quad2)
                            couldConnect = True
                if DI1.right.hasRoads():
                    DI2 = self.grid.rightElement(cell)
                    if DI2 is not None and isinstance(DI2, DirectionIntersection):
                        if DI2.left.hasRoads():
                            # We have a connection
                            quad1 = DI1.right
                            quad2 = DI2.left
                            self.connectDirectionQuadrants(DI1, DI2, quad1, quad2)
                            couldConnect = True
                # if couldConnect == False:
                #     self.network.clusters.append(set([self.placedIntersections[DI1]]))


    def connectDirectionQuadrants(self, DI1, DI2, quad1, quad2):
        intersection1 = self.placedIntersections[DI1]
        intersection2 = self.placedIntersections[DI2]
        road1 = list(quad1.roads.keys())[0]
        cp1 = list(quad1.roads.values())[0]
        road2 = list(quad2.roads.keys())[0]
        cp2 = list(quad2.roads.values())[0]

        self.network.connect(self.nextRoadId, intersection1, road1, cp1, intersection2, road2, cp2, LaneSides.BOTH)
        self.nextRoadId += 1


    
    def adjustIntersectionPositions(self):
        odrList = []
        for cell in self.grid.cellGenerator():
            if isinstance(cell.element, DirectionIntersection):
                directionIntersection = cell.element
                x, y = self.grid.getAbsCellPosition(cell)
                # introduceNoise = np.random.choice([False, True], p=[0.1, 0.9])
                introduceNoise = True
                if introduceNoise:
                    # x = np.random.uniform(x, x + (cell.size[0] / 2))
                    # y = np.random.uniform(y, y + (cell.size[1] / 2))
                    # x = x + self.grid.cellNoises[cell] * cell.size[0]
                    # y = y + self.grid.cellNoises[cell] * cell.size[1]
                    x = x + self.grid.cellNoises[cell]
                    y = y + self.grid.cellNoises[cell]

                intersection = self.intersections[directionIntersection]
                if self.debug:
                    logging.info(f"Translating {intersection.id} to ({x}, {y})")

                rotation = 0
                if intersection in self.rotation:
                    rotation = self.rotation[intersection]

                intersection.transform(startX=x, startY=y, heading=rotation)
                # ODRHelper.transform(intersection.odr, startX=x, startY=y, heading=rotation)
                self.placedIntersections[directionIntersection] = intersection

                odrList.append(intersection.odr)
        return odrList

    
    def buildMap(self, name, plot=True):

        # 1 create intersections and direction intersections.
        if self.debug:
            logging.info(f"{self.name}: Building new HDMap")
        self.createIntersections()
        self.mapBuilder.setDirectionIntersections(list(self.intersections.keys()))
        self.mapBuilder.run(self.nIntersections * 2, plot=plot)

        # now each cell in the grid has reference to the direction intersection 
        if self.debug:
            logging.info(f"{self.name}: adjustIntersectionPositions")
        odrList = self.adjustIntersectionPositions()

        self.connectIntersectionsByCellAdjacency()

        combinedOdr = ODRHelper.combine(odrList, name)
        ODRHelper.addAdjustedRoads(combinedOdr, self.network.connectionRoads)

        if self.debug:
            logging.info(f"{self.name}: buildMap: number of clusters: {len(self.network.clusters)}")
            self.network.logClusters()
        return combinedOdr