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")))
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)
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