def test_createMShape(self): roads = [] roads.append(pyodrx.create_straight_road(0, 10)) roads.append(self.roadBuilder.createMShape(1, 1, np.pi / 1.5, 10)) roads.append(pyodrx.create_straight_road(2, 10)) roads[0].add_successor(pyodrx.ElementType.junction, 1) roads[1].add_predecessor(pyodrx.ElementType.road, 0, pyodrx.ContactPoint.end) # roads[1].add_predecessor(pyodrx.ElementType.road,0,pyodrx.ContactPoint.start) roads[1].add_successor(pyodrx.ElementType.road, 2, pyodrx.ContactPoint.start) roads[2].add_predecessor(pyodrx.ElementType.junction, 1) junction = self.junctionBuilder.createJunctionForASeriesOfRoads(roads) odrName = "test_connectionRoad" odr = extensions.createOdr(odrName, roads, [junction]) extensions.view_road( odr, os.path.join('..', self.configuration.get("esminipath"))) xmlPath = f"output/m-shape.xodr" odr.write_xml(xmlPath) extensions.saveRoadImageFromFile(xmlPath, self.esminiPath)
def test_buildSimpleRoundAboutAndCheckInternalConnection(self): numRoads = 3 odr = self.junctionBuilder.buildSimpleRoundAbout( odrId=0, numRoads=numRoads, radius=10, cp1=pyodrx.ContactPoint.end) xmlPath = f"output/test-SimpleRoundAbout-{numRoads}.xodr" odr.write_xml(xmlPath) extensions.printRoadPositions(odr) extensions.saveRoadImageFromFile(xmlPath, self.esminiPath) extensions.view_road(odr, os.path.join('..', self.esminiPath)) # what's the problem with internal connections? internalConnection = odr.roads['12'].shallowCopy() internalConnection.clearRoadLinks() odr = extensions.createOdr("12 only", [internalConnection], []) xmlPath = f"output/test-SimpleRoundAbout-{numRoads}-road-12.xodr" odr.write_xml(xmlPath) extensions.printRoadPositions(odr) extensions.saveRoadImageFromFile(xmlPath, self.esminiPath) extensions.view_road(odr, os.path.join('..', self.esminiPath))
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 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
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 test_buildSimpleRoundAbout(self): numRoads = 6 odr = self.junctionBuilder.buildSimpleRoundAbout( odrId=0, numRoads=numRoads, radius=10, cp1=pyodrx.ContactPoint.end) xmlPath = f"output/test-SimpleRoundAbout-{numRoads}.xodr" odr.write_xml(xmlPath) extensions.printRoadPositions(odr) extensions.saveRoadImageFromFile(xmlPath, self.esminiPath) extensions.view_road(odr, os.path.join('..', self.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 merge2R2L(self, odrs, save=True): # 1 find connectionRoad in the first, it's predecessor is first road, successor is the second road. connectionRoadsFirst = extensions.getConnectionRoads( odrs[0].roads, odrs[0].junctions[0]) connectionRoadFirst = connectionRoadsFirst[0].shallowCopy() connectionRoadsSecond = extensions.getConnectionRoads( odrs[1].roads, odrs[1].junctions[0]) connectionRoadSecond = connectionRoadsSecond[0].shallowCopy() if self.canMerge(connectionRoadFirst, connectionRoadSecond) is False: raise IncompatibleRoadsException( "incompatible junctions to merge.") roadFirstPred = extensions.getRoadFromRoadDic( odrs[0].roads, connectionRoadFirst.predecessor.element_id).shallowCopy() roadFirstSuc = extensions.getRoadFromRoadDic( odrs[0].roads, connectionRoadFirst.successor.element_id).shallowCopy() roadSecondPred = extensions.getRoadFromRoadDic( odrs[1].roads, connectionRoadSecond.predecessor.element_id).shallowCopy() roadSecondSuc = extensions.getRoadFromRoadDic( odrs[1].roads, connectionRoadSecond.successor.element_id).shallowCopy() # case 1: remove roadSecondPred & rebuild links for roads in the first odr roadFirstPred.updateSuccessor(pyodrx.ElementType.junction, connectionRoadFirst.id) connectionRoadFirst.updatePredecessor( pyodrx.ElementType.road, roadFirstPred.id, pyodrx.ContactPoint.end ) # interestingly, this becomes the start point after merging. connectionRoadFirst.updateSuccessor(pyodrx.ElementType.road, roadFirstSuc.id, pyodrx.ContactPoint.start) roadFirstSuc.updatePredecessor(pyodrx.ElementType.junction, connectionRoadFirst.id) roadSecondSuc.updatePredecessor(pyodrx.ElementType.junction, connectionRoadFirst.id) roads = [] roads.append(roadFirstPred) roads.append(connectionRoadFirst) roads.append(roadFirstSuc) roads.append(connectionRoadSecond) roads.append(roadSecondSuc) # fix links for roadFirstSuc, connectionRoadSecond, roadSecondSuc self.regenAndMergeWithConnectionRoad(roadFirstSuc, connectionRoadSecond, roadSecondSuc) # create new junction junction = self.createJunctionFor2Connections(roadFirstPred, connectionRoadFirst, roadFirstSuc, connectionRoadSecond) # newOdr = self.mergeByRoad(self, commonRoads, ords) self.lastId += 1 # create the opendrive odr = pyodrx.OpenDrive("3R_2L_" + str(self.lastId)) for r in roads: odr.add_road(r) odr.add_junction(junction) print(f"starting adjustment. May freeze!!!!!!!!!!!!!") odr.adjust_roads_and_lanes() xmlPath = self.getOutputPath(odr.name) if save: odr.write_xml(xmlPath) if self.saveImage: extensions.saveRoadImageFromFile(xmlPath, self.esminiPath) return odr
def test_saveRoadImageFromFile(self): xodrPath = self.rootPath + "\\output\\test-RightLane.xodr" outputFile = extensions.saveRoadImageFromFile( xodrPath, self.configuration.get("esminipath")) assert os.path.isfile(outputFile)
def harvestUS(self, n_lanes_left=2, n_lanes_right=2, show=False): # incoming lanes in a junction are right lanes if end point is connected, left lanes if start point is connected. # 5x5x5x5 for 2, 2 print(f"harvestUS with {n_lanes_left} and {n_lanes_right}") odrs = [] # now iterate through lanes and set types. leftCombinations = self.getLaneTurnCombinations(n_lanes_left) rightCombinations = self.getLaneTurnCombinations(n_lanes_right) # for each combinations on left and right, create a new road for leftComb in leftCombinations: for rightComb in rightCombinations: road = self.straightRoadBuilder.createWithDifferentLanes(self.lastId, length=self.straightRoadLen, n_lanes_left=n_lanes_left, n_lanes_right=n_lanes_right) # right lanes, change last lane secion # left lanes, change first lane section. laneSectionForLeft = road.getFirstLaneSection() laneSectionForRight = road.getLastLaneSection() self.applyTurnCombinationOnLanes(laneSectionForLeft.leftlanes, leftComb) self.applyTurnCombinationOnLanes(laneSectionForRight.rightlanes, rightComb) name = f"straightRoad-{self.lastId}" self.lastId += 1 odr = extensions.createOdrByPredecessor(name, roads=[road], junctions=[]) # 1. save the xml file fname = odr.name xmlPath = self.getOutputPath(fname) odr.write_xml(xmlPath) # 2. save image if self.saveImage is True: extensions.saveRoadImageFromFile(xmlPath, self.esminiPath) if show: extensions.view_road(odr, os.path.join('..', self.esminiPath)) odrs.append(odr) # handle cases where we dont need right lanes if n_lanes_right == 0: for leftComb in leftCombinations: road = self.straightRoadBuilder.createWithDifferentLanes(self.lastId, length=self.straightRoadLen, n_lanes_left=n_lanes_left, n_lanes_right=n_lanes_right) # right lanes, change last lane secion # left lanes, change first lane section. laneSectionForLeft = road.getFirstLaneSection() self.applyTurnCombinationOnLanes(laneSectionForLeft.leftlanes, leftComb) name = f"straightRoad-{self.lastId}" self.lastId += 1 odr = extensions.createOdrByPredecessor(name, roads=[road], junctions=[]) # 1. save the xml file fname = odr.name xmlPath = self.getOutputPath(fname) odr.write_xml(xmlPath) # 2. save image if self.saveImage is True: extensions.saveRoadImageFromFile(xmlPath, self.esminiPath) if show: extensions.view_road(odr, os.path.join('..', self.esminiPath)) odrs.append(odr) # handle cases where we dont need left lanes if n_lanes_left == 0: for rightComb in rightCombinations: road = self.straightRoadBuilder.createWithDifferentLanes(self.lastId, length=self.straightRoadLen, n_lanes_left=n_lanes_left, n_lanes_right=n_lanes_right) # right lanes, change last lane secion # left lanes, change first lane section. laneSectionForRight = road.getLastLaneSection() self.applyTurnCombinationOnLanes(laneSectionForRight.rightlanes, rightComb) name = f"straightRoad-{self.lastId}" self.lastId += 1 odr = extensions.createOdrByPredecessor(name, roads=[road], junctions=[]) # 1. save the xml file fname = odr.name xmlPath = self.getOutputPath(fname) odr.write_xml(xmlPath) # 2. save image if self.saveImage is True: extensions.saveRoadImageFromFile(xmlPath, self.esminiPath) if show: extensions.view_road(odr, os.path.join('..', self.esminiPath)) odrs.append(odr) return odrs