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 JunctionHarvester: def __init__(self, outputDir, outputPrefix, lastId=0, minAngle = np.pi / 10, maxAngle = np.pi, straightRoadLen = 10, esminiPath = None, saveImage = True): """The angle between two connected roads are >= self.minAngle <= self.maxAngle Args: outputDir ([type]): [description] outputPrefix ([type]): [description] lastId (int, optional): [description]. Defaults to 0. minAngle ([type], optional): [description]. Defaults to np.pi/10. maxAngle ([type], optional): [description]. Defaults to np.pi. straightRoadLen : used both for normal and connection roads esminiPath: Path to esmini to generate images for roads. """ self.destinationPrefix = os.path.join(outputDir, outputPrefix) self.minAngle = minAngle self.maxAngle = maxAngle self.lastId = lastId self.straightRoadLen = straightRoadLen self.roadBuilder = RoadBuilder() self.straightRoadBuilder = StraightRoadBuilder() self.junctionBuilder = JunctionBuilder(self.roadBuilder) self.sequentialJunctionBuilder = SequentialJunctionBuilder(self.roadBuilder, self.straightRoadLen, minAngle=minAngle, maxAngle=maxAngle) self.junctionMerger = JunctionMerger(outputDir, outputPrefix, lastId) self.configuration = Configuration() if esminiPath is None: self.esminiPath = self.configuration.get("esminipath") else: self.esminiPath = esminiPath self.saveImage = saveImage if os.path.isdir(self.esminiPath) is False: logging.warn(f"Esmini path not found {self.esminiPath}. Will break if you try to save images using harvester.") pass def getOutputPath(self, fname): return self.destinationPrefix + fname + '.xodr' def createOdr(self, name, roads, junctions): return extensions.createOdr(name, roads, junctions) # odr = extensions.ExtendedOpenDrive(name) # for r in roads: # odr.add_road(r) # for junction in junctions: # odr.add_junction(junction) # print(f"starting adjustment. May freeze!!!!!!!!!!!!!") # odr.adjust_roads_and_lanes() # return odr def harvest2ways2Lanes(self, stepAngle=np.pi/20, maxTries = 100, seed=39): """We create junctions of two roads. Will create at least one road per angle. Args: stepAngle ([type], optional): used to generate angles between roads in conjunction with min and max angles. Defaults to np.pi/20. maxTries (int, optional): maximum number of junctions will be maxTries. Defaults to 1000. seed (int, optional): defaults to 39 """ np.random.seed(seed) # for each angle countCreated = 0 roadsPerAngle = self.getRoadsPerAngle(maxTries, stepAngle) angleBetweenRoads = self.minAngle odrObjectsPerAngle = {} # we will save the odrs keyed by angles while (countCreated < maxTries and angleBetweenRoads < self.maxAngle ): odrObjects = self.randomSome2ways2Lanes(angleBetweenRoads, roadsPerAngle) odrObjectsPerAngle[str(angleBetweenRoads)] = odrObjects countCreated += roadsPerAngle angleBetweenRoads += stepAngle print(f"created {countCreated} roads") # Save the odrs with(open(self.destinationPrefix + "harvested2R2LOrds.dill", "wb")) as f: dill.dump(odrObjectsPerAngle, f) print("Odr objects saved to " + self.destinationPrefix + "harvested2R2LOrds.dill" ) pass def getRoadsPerAngle(self, maxTries, stepAngle): roadsPerAngle = round((maxTries * stepAngle)/(self.maxAngle - self.minAngle)) if roadsPerAngle == 0: roadsPerAngle = 1 return roadsPerAngle def randomSome2ways2Lanes(self, angleBetweenRoads, numberOfRoads): """Creates 2way junctions where the connected roads have fixed angle Args: angleBetweenRoads ([type]): The angle between the roads. The connecting road is a curve that ensures the angle is preserved. numberOfRoads ([type]): number of roads to be generated Returns: [type]: [description] """ print( f"randomSome2ways2Lanes: creating {numberOfRoads} for angle: {math.degrees(angleBetweenRoads)}") odrObjects = [] for i in range( numberOfRoads): odr = self.random2ways2Lanes(angleBetweenRoads) odrObjects.append(odr) # 1. save the xml file fname = "2R2L_" + str(round(math.degrees(angleBetweenRoads))) + "_no" + str(i) xmlPath = self.getOutputPath(fname) odr.write_xml(xmlPath) # 2. save image if self.saveImage is True: extensions.saveRoadImageFromFile(xmlPath, self.esminiPath) return odrObjects def random2ways2Lanes(self, angleBetweenRoads): # print( f"random2ways2Lanes: creating a road network for angle: {math.degrees(angleBetweenRoads)}") roads = [] roads.append(pyodrx.create_straight_road(0, length=self.straightRoadLen)) # cannot reuse roads due to some references to links cannot be reinitialized with pyodrx lib. roads.append(self.createRandomConnectionConnectionRoad(1, angleBetweenRoads)) roads.append(pyodrx.create_straight_road(2, length=self.straightRoadLen)) self.link3RoadsWithMidAsJunction(roads) junction = self.create2RoadJunction(roads) self.lastId += 1 odrName = 'R2_L2_' + str(self.lastId) odr = self.createOdr(odrName, roads, [junction]) return odr def createRandomConnectionConnectionRoad(self, connectionRoadId, angleBetweenRoads): """The magic connectionRoad Args: angleBetweenRoads ([type]): The angle between the roads which this connectionRoad is suppose to connect together connectionRoadId ([type]): id to be assigned to the new connection road. """ if angleBetweenRoads > 3.05: # when it's greater than 174 degrees, create a straight road return pyodrx.create_straight_road(connectionRoadId, length=self.straightRoadLen, junction=1) connectionRoad = self.roadBuilder.createRandomCurve(connectionRoadId, angleBetweenRoads, isJunction=True) return connectionRoad def link3RoadsWithMidAsJunction(self, roads): roads[0].add_successor(pyodrx.ElementType.junction,1, pyodrx.ContactPoint.start) self.linkInsideRoad(roads[1], 0, 2) roads[2].add_predecessor(pyodrx.ElementType.junction,1, pyodrx.ContactPoint.end) def linkInsideRoad(self, connectionRoad, predecessorId, successorId): connectionRoad.add_predecessor(pyodrx.ElementType.road, predecessorId, pyodrx.ContactPoint.end) connectionRoad.add_successor(pyodrx.ElementType.road, successorId, pyodrx.ContactPoint.start) pass def create2RoadJunction(self, roads): """[summary] Args: roads ([type]): 3 roads with mid as the junction type. """ connection = self.connect2LaneRoads(0, 1) junction = pyodrx.Junction('test',1) junction.add_connection(connection) return junction def connect2LaneRoads(self, incomingRoadId, connectionRoadId,): """Assumes no center lane offset. Args: incomingRoadId ([type]): [description] connectionRoadId ([type]): [description] """ connection = pyodrx.Connection(incomingRoadId, connectionRoadId, pyodrx.ContactPoint.start) connection.add_lanelink(-1,-1) return connection def harvest3WayJunctionsFrom2Ways(self, ingredientsFile, maxTries = 100, randomizeAngleSelection = True): """Merges 2 way junctions into 3 ways. Args: ingredientsFile ([type]): [description] maxTries (int, optional): [description]. Defaults to 100. randomizeAngleSelection (bool, optional): If True it will pick 2R roads randomly without any angle filtering. If false, it will only connect 2R roads which have different angles. Defaults to True. Raises: NotImplementedError: [description] """ with(open(ingredientsFile, 'rb')) as f: odrDic = dill.load(f) selectedOdrs = None generatedOdrs = [] if randomizeAngleSelection: odrList = [] for angleOdrList in odrDic.values(): odrList += angleOdrList numberOfOds = len(odrList) for _ in range(maxTries): try: selectedOdrs = [odrList[np.random.choice(numberOfOds)], odrList[np.random.choice(numberOfOds)]] newOdr = self.junctionMerger.merge2R2L(selectedOdrs) generatedOdrs.append(newOdr) self.lastId += 1 except IncompatibleRoadsException: continue else: # TODO angle permutation for merging 2ways raise NotImplementedError("Angle permutation is not implemented yet") with(open(self.destinationPrefix + "harvested3R2LOrds.dill", "wb")) as f: dill.dump(generatedOdrs, f) print("Odr objects saved to " + self.destinationPrefix + "_harvested3R2LOrds.dill" ) pass def harvestByPainting2L(self, maxNumberOfRoadsPerJunction, triesPerRoadCount, show=False): """[summary] Args: maxNumberOfRoadsPerJunction ([type]): [description] triesPerRoadCount ([type]): number of junctions to be created for each set of roads. for 3 roads, we will try triesPerRoadCount, for 4 roads the same. save (bool, optional): [description]. Defaults to True. """ odrs = [] for numRoads in range(3, maxNumberOfRoadsPerJunction + 1): for _ in range(triesPerRoadCount): odr = self.sequentialJunctionBuilder.drawLikeAPainter2L(self.lastId, numRoads) self.lastId += 1 if show: extensions.view_road(odr, os.path.join('..', self.esminiPath)) xmlPath = self.getOutputPath(odr.name) odr.write_xml(xmlPath) # 2. save image if self.saveImage is True: extensions.saveRoadImageFromFile(xmlPath, self.esminiPath) odrs.append(odr) with(open(self.destinationPrefix + "harvestedByPainting2L.dill", "wb")) as f: dill.dump(odrs, f) print("Odr objects saved to " + self.destinationPrefix + "harvestedByPainting2L.dill" ) pass