Exemple #1
0
    def __init__(self,
                 roadBuilder=None,
                 straightRoadLen=10,
                 minAngle=np.pi / 6,
                 maxAngle=None,
                 country=CountryCodes.US,
                 random_seed=39):

        self.config = Configuration()
        self.roadBuilder = roadBuilder

        if self.roadBuilder is None:
            self.roadBuilder = RoadBuilder()

        self.straightRoadBuilder = StraightRoadBuilder()
        self.laneBuilder = LaneBuilder()

        self.straightRoadLen = straightRoadLen

        self.minAngle = minAngle
        self.maxAngle = maxAngle

        if self.maxAngle == np.pi:
            self.maxAngle = 0.99 * np.pi

        self.laneWidth = self.config.get("default_lane_width")
        self.minConnectionLength = self.config.get("min_connection_length")
        self.maxConnectionLength = self.config.get("max_connection_length")
        self.curveBuilder = CurveRoadBuilder(country=country)
        self.connectionBuilder = ConnectionBuilder()
        self.countryCode = country
        np.random.seed(random_seed)
        pass
Exemple #2
0
 def setUp(self):
     
     self.configuration = Configuration()
     self.esminiPath = self.configuration.get("esminipath")
     self.harvester = StraightRoadHarvester(outputDir="./output", outputPrefix="harvest-straight-", lastId=0, straightRoadLen=10, esminiPath=self.esminiPath)
     self.straightRoadBuilder = StraightRoadBuilder()
     self.pp = pprint.PrettyPrinter(indent=4)
    def __init__(self, 
                outputDir, 
                outputPrefix, 
                lastId=0,
                straightRoadBuilder=None,
                straightRoadLen = 2,
                esminiPath = None, 
                saveImage = False
                ):
        
        self.destinationPrefix = os.path.join(outputDir, outputPrefix)
        self.configuration = Configuration()
        self.lastId = lastId
        self.straightRoadLen = straightRoadLen

        self.straightRoadBuilder = straightRoadBuilder
        if straightRoadBuilder is None:
            self.straightRoadBuilder = StraightRoadBuilder()

        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
Exemple #4
0
    def setUp(self):

        self.configuration = Configuration()
        self.roadBuilder = junctions.RoadBuilder()

        self.straightRoadBuilder = StraightRoadBuilder()
        self.roadLinker = RoadLinker()
    def setUp(self):

        self.configuration = Configuration()
        self.esminiPath = self.configuration.get("esminipath")
        self.roadBuilder = RoadBuilder()
        self.laneBuilder = LaneBuilder()
        self.laneLinker = LaneLinker()
        self.straightRoadBuilder = StraightRoadBuilder()
    def setUp(self):

        self.configuration = Configuration()
        self.esminipath = self.configuration.get("esminipath")
        self.roadBuilder = junctions.RoadBuilder()

        self.straightRoadBuilder = StraightRoadBuilder()
        self.roadLinker = RoadLinker()
        self.connectionBuilder = ConnectionBuilder()
        self.curveRoadBuilder = CurveRoadBuilder()
Exemple #7
0
    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
Exemple #8
0
class test_LaneLinker(unittest.TestCase):
    def setUp(self):

        self.configuration = Configuration()
        self.esminiPath = self.configuration.get("esminipath")
        self.roadBuilder = RoadBuilder()
        self.laneBuilder = LaneBuilder()
        self.laneLinker = LaneLinker()
        self.straightRoadBuilder = StraightRoadBuilder()
        self.roadLinker = RoadLinker()

    def test_normalRoadLinks(self):

        roads = []
        roads.append(self.straightRoadBuilder.create(0))
        roads.append(
            self.roadBuilder.curveBuilder.createSimple(1,
                                                       np.pi / 4,
                                                       False,
                                                       curvature=0.2))
        roads.append(self.straightRoadBuilder.create(2))

        RoadLinker.createExtendedPredSuc(predRoad=roads[0],
                                         predCp=pyodrx.ContactPoint.end,
                                         sucRoad=roads[1],
                                         sucCP=pyodrx.ContactPoint.start)

        RoadLinker.createExtendedPredSuc(predRoad=roads[1],
                                         predCp=pyodrx.ContactPoint.end,
                                         sucRoad=roads[2],
                                         sucCP=pyodrx.ContactPoint.start)

        odrName = "test_connectionRoad"
        odr = extensions.createOdrByPredecessor(odrName, roads, [])

        # self.laneBuilder.addRightTurnLaneUS(roads[0], 3)
        # self.laneBuilder.addRightLaneUS(roads[1])

        # odr.resetAndReadjust(byPredecessor=True)

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

    def test_DifferentCPs(self):

        # same cps
        roads = []
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(0,
                                                              length=20,
                                                              junction=-1,
                                                              n_lanes_left=2,
                                                              n_lanes_right=1))
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(1,
                                                              length=10,
                                                              junction=-1,
                                                              n_lanes_left=1,
                                                              n_lanes_right=2))

        roads[0].addExtendedSuccessor(roads[1], 0, pyodrx.ContactPoint.start)
        roads[1].addExtendedPredecessor(roads[0], 0, pyodrx.ContactPoint.start)

        odrName = "test_DifferentCPs1"
        odr = extensions.createOdrByPredecessor(odrName, roads, [])

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

        xmlPath = f"output/test_DifferentCPs1.xodr"
        odr.write_xml(xmlPath)

        # same cps 2
        roads = []
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(0,
                                                              length=20,
                                                              junction=-1,
                                                              n_lanes_left=2,
                                                              n_lanes_right=1))
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(1,
                                                              length=10,
                                                              junction=-1,
                                                              n_lanes_left=2,
                                                              n_lanes_right=1))

        roads[0].addExtendedSuccessor(roads[1], 0, pyodrx.ContactPoint.start)
        roads[1].addExtendedPredecessor(roads[0], 0, pyodrx.ContactPoint.end)

        odrName = "test_DifferentCPs2"
        odr = extensions.createOdrByPredecessor(odrName, roads, [])

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

        xmlPath = f"output/test_DifferentCPs2.xodr"
        odr.write_xml(xmlPath)
class test_ExtendedRoad(unittest.TestCase):
    def setUp(self):

        self.configuration = Configuration()
        self.esminipath = self.configuration.get("esminipath")
        self.roadBuilder = junctions.RoadBuilder()

        self.straightRoadBuilder = StraightRoadBuilder()
        self.roadLinker = RoadLinker()
        self.connectionBuilder = ConnectionBuilder()
        self.curveRoadBuilder = CurveRoadBuilder()

    def test_createSingleLaneConnectionRoad(self):

        roads = []

        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(0,
                                                              length=10,
                                                              junction=-1,
                                                              n_lanes_left=2,
                                                              n_lanes_right=2))
        roads.append(
            self.curveRoadBuilder.createSimple(1,
                                               np.pi / 3,
                                               isJunction=True,
                                               n_lanes=2))
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(2,
                                                              length=10,
                                                              junction=-1,
                                                              n_lanes_left=2,
                                                              n_lanes_right=2))

        RoadLinker.createExtendedPredSuc(predRoad=roads[0],
                                         predCp=pyodrx.ContactPoint.end,
                                         sucRoad=roads[1],
                                         sucCP=pyodrx.ContactPoint.start)
        RoadLinker.createExtendedPredSuc(predRoad=roads[1],
                                         predCp=pyodrx.ContactPoint.end,
                                         sucRoad=roads[2],
                                         sucCP=pyodrx.ContactPoint.start)

        odrName = "test_createSingleLaneConnectionRoad"
        odr = extensions.createOdrByPredecessor(odrName, roads, [])

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

        newConnection = self.connectionBuilder.createSingleLaneConnectionRoad(
            3, roads[0], roads[2], -2, -2, pyodrx.ContactPoint.end,
            pyodrx.ContactPoint.start)
        RoadLinker.createExtendedPredSuc(predRoad=roads[0],
                                         predCp=pyodrx.ContactPoint.end,
                                         sucRoad=newConnection,
                                         sucCP=pyodrx.ContactPoint.start)
        RoadLinker.createExtendedPredSuc(predRoad=newConnection,
                                         predCp=pyodrx.ContactPoint.end,
                                         sucRoad=roads[2],
                                         sucCP=pyodrx.ContactPoint.start)
        newConnection.updatePredecessorOffset(-1)

        roads.append(newConnection)
        odr.add_road(newConnection)

        newConnection = self.connectionBuilder.createSingleLaneConnectionRoad(
            4, roads[2], roads[0], 2, 2, pyodrx.ContactPoint.start,
            pyodrx.ContactPoint.end)
        RoadLinker.createExtendedPredSuc(predRoad=roads[2],
                                         predCp=pyodrx.ContactPoint.start,
                                         sucRoad=newConnection,
                                         sucCP=pyodrx.ContactPoint.start)
        RoadLinker.createExtendedPredSuc(predRoad=newConnection,
                                         predCp=pyodrx.ContactPoint.end,
                                         sucRoad=roads[0],
                                         sucCP=pyodrx.ContactPoint.end)
        newConnection.updatePredecessorOffset(1)

        roads.append(newConnection)
        odr.add_road(newConnection)

        odr.resetAndReadjust(byPredecessor=True)
        extensions.printRoadPositions(odr)

        extensions.view_road(odr, os.path.join('..', self.esminipath))
        xmlPath = f"output/test_createSingleLaneConnectionRoad.xodr"
        odr.write_xml(xmlPath)
class test_RoadLiner(unittest.TestCase):
    def setUp(self):

        self.configuration = Configuration()
        self.esminiPath = self.configuration.get("esminipath")
        self.roadBuilder = RoadBuilder()
        self.laneBuilder = LaneBuilder()
        self.laneLinker = LaneLinker()
        self.straightRoadBuilder = StraightRoadBuilder()
        self.curveBuilder = CurveRoadBuilder()
        self.roadLinker = RoadLinker()

    def test_getAngleBetweenStraightRoads(self):
        roads = []
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(0,
                                                              10,
                                                              n_lanes_left=1,
                                                              n_lanes_right=1))
        connectionRoad = self.curveBuilder.create(1,
                                                  np.pi / 4,
                                                  isJunction=True,
                                                  curvature=0.2,
                                                  n_lanes=1)
        roads.append(connectionRoad)
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(2,
                                                              10,
                                                              n_lanes_left=1,
                                                              n_lanes_right=2))

        connectionRoad2 = self.curveBuilder.create(3,
                                                   np.pi / 2,
                                                   isJunction=True,
                                                   curvature=0.1,
                                                   n_lanes=1)
        roads.append(connectionRoad2)
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(4,
                                                              10,
                                                              n_lanes_left=1,
                                                              n_lanes_right=1))

        roads[0].addExtendedSuccessor(roads[1], 0, pyodrx.ContactPoint.start)

        roads[1].addExtendedPredecessor(roads[0], 0, pyodrx.ContactPoint.end)
        roads[1].addExtendedSuccessor(roads[2], 0, pyodrx.ContactPoint.start)

        roads[2].addExtendedPredecessor(roads[1], 0, pyodrx.ContactPoint.end)
        roads[2].addExtendedSuccessor(roads[3], 0, pyodrx.ContactPoint.start)

        roads[3].addExtendedPredecessor(roads[2], 0, pyodrx.ContactPoint.start)
        roads[3].addExtendedSuccessor(roads[4], 0, pyodrx.ContactPoint.start)

        roads[4].addExtendedPredecessor(roads[3], 0, pyodrx.ContactPoint.end)

        self.laneBuilder.createLanesForConnectionRoad(connectionRoad, roads[0],
                                                      roads[2])
        self.laneBuilder.createLanesForConnectionRoad(connectionRoad2,
                                                      roads[2], roads[4])

        odrName = "test_DifferentLaneConfigurations"
        odr = extensions.createOdrByPredecessor(odrName, roads, [])

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

        print(
            math.degrees(
                self.roadLinker.getAngleBetweenStraightRoads(
                    roads[0], roads[2])))
        print(
            math.degrees(
                self.roadLinker.getAngleBetweenStraightRoads(
                    roads[0], roads[4])))
        print(
            math.degrees(
                self.roadLinker.getAngleBetweenStraightRoads(
                    roads[2], roads[4])))

        # xmlPath = f"output/test_DifferentLaneConfigurations.xodr"
        # odr.write_xml(xmlPath)

    def test_StartEnd(self):
        roads = []
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(0,
                                                              10,
                                                              n_lanes_left=1,
                                                              n_lanes_right=1))
        connectionRoad = self.curveBuilder.create(1,
                                                  np.pi / 4,
                                                  isJunction=True,
                                                  curvature=0.1,
                                                  n_lanes=1)
        roads.append(connectionRoad)
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(2,
                                                              10,
                                                              n_lanes_left=1,
                                                              n_lanes_right=1))

        roads[0].addExtendedSuccessor(roads[1], 0, pyodrx.ContactPoint.start)

        roads[1].addExtendedPredecessor(roads[0], 0, pyodrx.ContactPoint.start)
        roads[1].addExtendedSuccessor(roads[2], 0, pyodrx.ContactPoint.start)

        roads[2].addExtendedPredecessor(roads[1], 0, pyodrx.ContactPoint.end)

        self.laneBuilder.createLanesForConnectionRoad(connectionRoad, roads[0],
                                                      roads[2])

        odrName = "test_StartEnd"
        odr = extensions.createOdrByPredecessor(odrName, roads, [])

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

        print(
            math.degrees(
                self.roadLinker.getAngleBetweenStraightRoads(
                    roads[0], roads[2])))

        xmlPath = f"output/test_StartEnd.xodr"
        odr.write_xml(xmlPath)

    def test_fails(self):
        roads = []
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(0,
                                                              10,
                                                              n_lanes_left=1,
                                                              n_lanes_right=1))
        connectionRoad = self.curveBuilder.create(1,
                                                  np.pi / 4,
                                                  isJunction=True,
                                                  curvature=0.2,
                                                  n_lanes=1)
        roads.append(connectionRoad)
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(2,
                                                              10,
                                                              n_lanes_left=1,
                                                              n_lanes_right=2))

        connectionRoad2 = self.curveBuilder.create(3,
                                                   np.pi / 2,
                                                   isJunction=True,
                                                   curvature=0.1,
                                                   n_lanes=1)
        roads.append(connectionRoad2)
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(4,
                                                              10,
                                                              n_lanes_left=1,
                                                              n_lanes_right=3))

        roads[0].addExtendedSuccessor(roads[1], 0, pyodrx.ContactPoint.start)

        roads[1].addExtendedPredecessor(roads[0], 0, pyodrx.ContactPoint.end)
        roads[1].addExtendedSuccessor(roads[2], 0, pyodrx.ContactPoint.start)

        roads[2].addExtendedPredecessor(roads[1], 0, pyodrx.ContactPoint.end)
        roads[2].addExtendedSuccessor(roads[3], 0, pyodrx.ContactPoint.start)

        roads[3].addExtendedPredecessor(roads[2], 0, pyodrx.ContactPoint.start)
        roads[3].addExtendedSuccessor(roads[4], 0, pyodrx.ContactPoint.start)

        roads[4].addExtendedPredecessor(roads[3], 0, pyodrx.ContactPoint.end)

        self.laneBuilder.createLanesForConnectionRoad(connectionRoad, roads[0],
                                                      roads[2])
        self.laneBuilder.createLanesForConnectionRoad(connectionRoad2,
                                                      roads[2], roads[4])

        odrName = "test_DifferentLaneConfigurations"
        odr = extensions.createOdrByPredecessor(odrName, roads, [])

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

        print(
            math.degrees(
                self.roadLinker.getAngleBetweenStraightRoads(
                    roads[0], roads[2])))
        print(
            math.degrees(
                self.roadLinker.getAngleBetweenStraightRoads(
                    roads[0], roads[4])))
        print(
            math.degrees(
                self.roadLinker.getAngleBetweenStraightRoads(
                    roads[2], roads[4])))
class test_AngleCurvatureMap(unittest.TestCase):
    def setUp(self):

        self.configuration = Configuration()
        self.esminipath = self.configuration.get("esminipath")
        self.roadBuilder = junctions.RoadBuilder()

        self.straightRoadBuilder = StraightRoadBuilder()
        self.roadLinker = RoadLinker()
        self.connectionBuilder = ConnectionBuilder()
        self.curveRoadBuilder = CurveRoadBuilder()

    def test_getCurvatureForAngleAndLength(self):

        numberofLanes = 5
        laneOffset = 3
        # angle = np.pi * .75
        # angle = np.pi * (5/6)
        # length = 15

        # maxCurve = AngleCurvatureMap.getMaxCurvatureMaxRoadWidth(angle, numberofLanes * laneOffset)
        # curve = AngleCurvatureMap.getCurvatureForAngleBetweenRoadAndLength(angle, length, StandardCurveTypes.Simple)

        # # curve = 0.066666667

        # print(f"max curve {maxCurve}, current curve {curve}")

        # roads = []
        # roads.append(self.straightRoadBuilder.createWithDifferentLanes(0, length=10, junction=-1, n_lanes_left=numberofLanes, n_lanes_right=numberofLanes))
        # # roads.append(self.curveRoadBuilder.createSimpleCurveWithLongArc(1, angleBetweenEndpoints = angle, curvature=curve, isJunction=True, n_lanes=numberofLanes))
        # roads.append(self.curveRoadBuilder.createSimple(1, angleBetweenEndpoints = angle, curvature=curve, isJunction=True, n_lanes=numberofLanes))
        # roads.append(self.straightRoadBuilder.createWithDifferentLanes(2, length=10, junction=-1, n_lanes_left=numberofLanes, n_lanes_right=numberofLanes))

        # RoadLinker.createExtendedPredSuc(predRoad=roads[0], predCp=pyodrx.ContactPoint.end, sucRoad=roads[1], sucCP=pyodrx.ContactPoint.start)
        # RoadLinker.createExtendedPredSuc(predRoad=roads[1], predCp=pyodrx.ContactPoint.end, sucRoad=roads[2], sucCP=pyodrx.ContactPoint.start)

        # odrName = "test_createSingleLaneConnectionRoad"
        # odr = extensions.createOdrByPredecessor(odrName, roads, [])
        # # extensions.printRoadPositions(odr)

        # road = roads[1]
        # print(f"{road.id} has length {road.planview.get_total_length()}")

        # # for geom in road.planview._adjusted_geometries:
        # #     print(geom.length)

        # assert round(road.planview.get_total_length(), 0) == length
        # extensions.view_road(odr, os.path.join('..', self.esminipath))

        angle = 0.5
        while angle < np.pi:

            length = 100

            while length > 0:

                curve = AngleCurvatureMap.getCurvatureForAngleBetweenRoadAndLength(
                    angle, length, StandardCurveTypes.Simple)
                roads = []
                curve = AngleCurvatureMap.getCurvatureForAngleBetweenRoadAndLength(
                    angle, length, StandardCurveTypes.Simple)
                roads.append(
                    self.straightRoadBuilder.createWithDifferentLanes(
                        0,
                        length=10,
                        junction=-1,
                        n_lanes_left=numberofLanes,
                        n_lanes_right=numberofLanes))
                roads.append(
                    self.curveRoadBuilder.createSimple(
                        1,
                        angleBetweenEndpoints=angle,
                        curvature=curve,
                        isJunction=True,
                        n_lanes=numberofLanes))
                roads.append(
                    self.straightRoadBuilder.createWithDifferentLanes(
                        2,
                        length=10,
                        junction=-1,
                        n_lanes_left=numberofLanes,
                        n_lanes_right=numberofLanes))

                RoadLinker.createExtendedPredSuc(
                    predRoad=roads[0],
                    predCp=pyodrx.ContactPoint.end,
                    sucRoad=roads[1],
                    sucCP=pyodrx.ContactPoint.start)
                RoadLinker.createExtendedPredSuc(
                    predRoad=roads[1],
                    predCp=pyodrx.ContactPoint.end,
                    sucRoad=roads[2],
                    sucCP=pyodrx.ContactPoint.start)
                odrName = "test_createSingleLaneConnectionRoad"
                odr = extensions.createOdrByPredecessor(odrName, roads, [])
                road = roads[1]

                assert round(road.planview.get_total_length(), 0) == length

                curve = AngleCurvatureMap.getCurvatureForAngleBetweenRoadAndLength(
                    angle, length, StandardCurveTypes.Simple)
                roads = []
                curve = AngleCurvatureMap.getCurvatureForAngleBetweenRoadAndLength(
                    angle, length, StandardCurveTypes.Simple)
                roads.append(
                    self.curveRoadBuilder.createSimpleCurveWithLongArc(
                        1,
                        angleBetweenEndpoints=angle,
                        curvature=curve,
                        isJunction=True,
                        n_lanes=numberofLanes))
                roads.append(
                    self.curveRoadBuilder.createSimple(
                        1,
                        angleBetweenEndpoints=angle,
                        curvature=curve,
                        isJunction=True,
                        n_lanes=numberofLanes))
                roads.append(
                    self.straightRoadBuilder.createWithDifferentLanes(
                        2,
                        length=10,
                        junction=-1,
                        n_lanes_left=numberofLanes,
                        n_lanes_right=numberofLanes))

                RoadLinker.createExtendedPredSuc(
                    predRoad=roads[0],
                    predCp=pyodrx.ContactPoint.end,
                    sucRoad=roads[1],
                    sucCP=pyodrx.ContactPoint.start)
                RoadLinker.createExtendedPredSuc(
                    predRoad=roads[1],
                    predCp=pyodrx.ContactPoint.end,
                    sucRoad=roads[2],
                    sucCP=pyodrx.ContactPoint.start)
                odrName = "test_createSingleLaneConnectionRoad"
                odr = extensions.createOdrByPredecessor(odrName, roads, [])
                road = roads[1]

                assert round(road.planview.get_total_length(), 0) == length

                length -= 10

            angle += 0.25

    def test_getMaxCurvatureMaxRoadWidth(self):

        roads = []

        numberofLanes = 1
        laneOffset = 3
        angle = np.pi * .75

        maxCurve = AngleCurvatureMap.getMaxCurvatureAgainstMaxRoadWidth(
            angle, numberofLanes * laneOffset)

        curve = maxCurve * 1.1

        print(f"max curve {maxCurve}, current curve {curve}")

        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(
                0,
                length=10,
                junction=-1,
                n_lanes_left=numberofLanes,
                n_lanes_right=numberofLanes))
        roads.append(
            self.curveRoadBuilder.createSimpleCurveWithLongArc(
                1,
                angleBetweenEndpoints=angle,
                curvature=curve,
                isJunction=True,
                n_lanes=numberofLanes))
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(
                2,
                length=10,
                junction=-1,
                n_lanes_left=numberofLanes,
                n_lanes_right=numberofLanes))

        RoadLinker.createExtendedPredSuc(predRoad=roads[0],
                                         predCp=pyodrx.ContactPoint.end,
                                         sucRoad=roads[1],
                                         sucCP=pyodrx.ContactPoint.start)
        RoadLinker.createExtendedPredSuc(predRoad=roads[1],
                                         predCp=pyodrx.ContactPoint.end,
                                         sucRoad=roads[2],
                                         sucCP=pyodrx.ContactPoint.start)

        odrName = "test_createSingleLaneConnectionRoad"
        odr = extensions.createOdrByPredecessor(odrName, roads, [])
        # extensions.printRoadPositions(odr)

        road = roads[1]
        print(f"{road.id} has length {road.planview.get_total_length()}")

        for geom in road.planview._adjusted_geometries:
            print(geom.length)

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

    def test_getLength(self):

        angleBetweenEndpoints = 1.5708
        curvature = 0.333333
        curveType = StandardCurveTypes.Simple
        currentLength = AngleCurvatureMap.getLength(angleBetweenEndpoints,
                                                    curvature, curveType)

        print(f"test length: {currentLength}")

        numberofLanes = 5
        laneOffset = 3

        angle = angleBetweenEndpoints
        length = currentLength

        maxCurve = AngleCurvatureMap.getCurvatureForAngleBetweenRoadAndLength(
            angle, numberofLanes * laneOffset, curveType=curveType)
        curve = AngleCurvatureMap.getCurvatureForAngleBetweenRoadAndLength(
            angle, length, curveType=curveType)

        # curve = 0.066666667

        print(f"max curve {maxCurve}, current curve {curve}")

        roads = []
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(
                0,
                length=10,
                junction=-1,
                n_lanes_left=numberofLanes,
                n_lanes_right=numberofLanes))
        # roads.append(self.curveRoadBuilder.createSimpleCurveWithLongArc(1, angleBetweenEndpoints = angle, curvature=curve, isJunction=True, n_lanes=numberofLanes))
        roads.append(
            self.curveRoadBuilder.createSimple(1,
                                               angleBetweenEndpoints=angle,
                                               curvature=curve,
                                               isJunction=True,
                                               n_lanes=numberofLanes))
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(
                2,
                length=10,
                junction=-1,
                n_lanes_left=numberofLanes,
                n_lanes_right=numberofLanes))

        RoadLinker.createExtendedPredSuc(predRoad=roads[0],
                                         predCp=pyodrx.ContactPoint.end,
                                         sucRoad=roads[1],
                                         sucCP=pyodrx.ContactPoint.start)
        RoadLinker.createExtendedPredSuc(predRoad=roads[1],
                                         predCp=pyodrx.ContactPoint.end,
                                         sucRoad=roads[2],
                                         sucCP=pyodrx.ContactPoint.start)

        odrName = "test_createSingleLaneConnectionRoad"
        odr = extensions.createOdrByPredecessor(odrName, roads, [])
        # extensions.printRoadPositions(odr)

        road = roads[1]
        print(f"{road.id} has length {road.planview.get_total_length()}")

        # for geom in road.planview._adjusted_geometries:
        #     print(geom.length)

        assert round(road.planview.get_total_length(), 0) == round(length, 0)
Exemple #12
0
    def setUp(self):

        self.configuration = Configuration()

        self.straightRoadBuilder = StraightRoadBuilder()
Exemple #13
0
class test_StraightRoadHarvester(unittest.TestCase):
    
    def setUp(self):
        
        self.configuration = Configuration()
        self.esminiPath = self.configuration.get("esminipath")
        self.harvester = StraightRoadHarvester(outputDir="./output", outputPrefix="harvest-straight-", lastId=0, straightRoadLen=10, esminiPath=self.esminiPath)
        self.straightRoadBuilder = StraightRoadBuilder()
        self.pp = pprint.PrettyPrinter(indent=4)

    
    def test_getPossibleTurnsWRTLaneOnRight(self):
        possibleTurns = self.harvester.getPossibleTurnsWRTLaneOnRight(TurnTypes.RIGHT)
        assert len(possibleTurns) == 6

        possibleTurns = self.harvester.getPossibleTurnsWRTLaneOnRight(TurnTypes.STRAIGHT_RIGHT)
        assert len(possibleTurns) == 3

        possibleTurns = self.harvester.getPossibleTurnsWRTLaneOnRight(TurnTypes.STRAIGHT)
        print(possibleTurns)
        assert len(possibleTurns) == 3

        possibleTurns = self.harvester.getPossibleTurnsWRTLaneOnRight(TurnTypes.STRAIGHT_LEFT)
        print(possibleTurns)
        assert len(possibleTurns) == 1
        possibleTurns = self.harvester.getPossibleTurnsWRTLaneOnRight(TurnTypes.LEFT)
        print(possibleTurns)
        assert len(possibleTurns) == 1
        possibleTurns = self.harvester.getPossibleTurnsWRTLaneOnRight(TurnTypes.ALL)
        print(possibleTurns)
        assert len(possibleTurns) == 1
    

    def test_getLaneTurnCombinations(self):

        combinations = self.harvester.getLaneTurnCombinations(1)
        # self.pp.pprint(combinations)
        assert len(combinations) == 6

        combinations = self.harvester.getLaneTurnCombinations(2)
        self.pp.pprint(combinations)
        print(len(combinations))
        assert len(combinations) == 15

    
    def test_applyTurnCombinationOnLanes(self):
        
        road = self.straightRoadBuilder.createWithDifferentLanes(0, length=10, n_lanes_left=2, n_lanes_right=2)
        leftCombinations = self.harvester.getLaneTurnCombinations(2)
        rightCombinations = leftCombinations

        laneSectionForLeft = road.getFirstLaneSection()
        laneSectionForRight = road.getLastLaneSection()

        self.harvester.applyTurnCombinationOnLanes(laneSectionForLeft.leftlanes, leftCombinations[0])

        self.harvester.applyTurnCombinationOnLanes(laneSectionForRight.rightlanes, rightCombinations[0])

        assert laneSectionForLeft.leftlanes[0].turnType == leftCombinations[0][0]
        assert laneSectionForLeft.leftlanes[0].turnType == rightCombinations[0][0]

    
    def test_harvestUS(self):

        odrs = self.harvester.harvestUS(2, 2, False)

        print(len(odrs))

    
    def test_harvest(self):
        self.harvester.harvest(maxLeftLanes=2, maxRightLanes=2, countryCode=CountryCodes.US)
class StraightRoadHarvester:

    def __init__(self, 
                outputDir, 
                outputPrefix, 
                lastId=0,
                straightRoadBuilder=None,
                straightRoadLen = 2,
                esminiPath = None, 
                saveImage = False
                ):
        
        self.destinationPrefix = os.path.join(outputDir, outputPrefix)
        self.configuration = Configuration()
        self.lastId = lastId
        self.straightRoadLen = straightRoadLen

        self.straightRoadBuilder = straightRoadBuilder
        if straightRoadBuilder is None:
            self.straightRoadBuilder = StraightRoadBuilder()

        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 harvest(self, maxLeftLanes=2, maxRightLanes=2, countryCode=CountryCodes.US, show=False):
        """[summary]

        Args:
            maxLeftLanes (int, optional): [description]. Defaults to 2.
            maxRightLanes (int, optional): [description]. Defaults to 2.
            countryCode ([type], optional): [description]. Defaults to CountryCodes.US.
            show (bool, optional): [description]. Defaults to False.

        Raises:
            NotImplementedError: [description]
        
        Returns: dic with keys like "n_lanes_left-n_lanes_right" and list of odrs per key
        """

        if countryCode != CountryCodes.US:
            raise NotImplementedError("Only US is implemented")

        # permutations
        # no merge or extension
        # each lane can have one of the 5 traffic direction.

        odrs = {} # values are a list of odrs for each key

        for l in range(maxLeftLanes + 1):
            for r in range(maxRightLanes + 1):
                if l == 0 and r == 0:
                    continue
                odrs[f"{l}-{r}"] = self.harvestUS(l, r, show) # do not change the key convention
        
        # Save the odrs

        objectPath = self.destinationPrefix + f"{countryCode.value}.dill"
        with(open(objectPath, "wb")) as f:
            dill.dump(odrs, f)
            print("Odr objects saved to " + objectPath)

        print(f"keys {odrs.keys()}")

        return objectPath

    
    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
        
    
    def applyTurnCombinationOnLanes(self, lanes, combination):

        for i in range(len(lanes)):
            lanes[i].turnType = combination[i]

        pass

    def getLaneTurnCombinations(self, n):
        """[summary]

        Args:
            n ([type]): [description]

        Returns:
            [type]: List of combinations. each combination is an ordered list
        """

    

        # from left to right

        if n == 0:
            return []

        if n == 1:
            return [[i] for i in TurnTypes.getAll()]

        combinations = []

        childrenCombinations = self.getLaneTurnCombinations(n-1)

        for childComb in childrenCombinations:
            possibleTurns = self.getPossibleTurnsWRTLaneOnRight(childComb[0])
            # push into child comb
            for possibleTurn in possibleTurns:
                childCopy = childComb.copy()
                childCopy.insert(0, possibleTurn)
                combinations.append(childCopy)
        
        return combinations
        

    
    def getPossibleTurnsWRTLaneOnRight(self, turnOnRight):

        if turnOnRight == TurnTypes.RIGHT:
            return TurnTypes.getAll()
        if turnOnRight in [TurnTypes.STRAIGHT_RIGHT, TurnTypes.STRAIGHT]:
            return (TurnTypes.LEFT, TurnTypes.STRAIGHT_LEFT, TurnTypes.STRAIGHT)
        
        return (TurnTypes.LEFT, ) # for ALL or LEFT types
Exemple #15
0
class JunctionBuilder:
    def __init__(self,
                 roadBuilder=None,
                 straightRoadLen=10,
                 minAngle=np.pi / 6,
                 maxAngle=None,
                 country=CountryCodes.US,
                 random_seed=39):

        self.config = Configuration()
        self.roadBuilder = roadBuilder

        if self.roadBuilder is None:
            self.roadBuilder = RoadBuilder()

        self.straightRoadBuilder = StraightRoadBuilder()
        self.laneBuilder = LaneBuilder()

        self.straightRoadLen = straightRoadLen

        self.minAngle = minAngle
        self.maxAngle = maxAngle

        if self.maxAngle == np.pi:
            self.maxAngle = 0.99 * np.pi

        self.laneWidth = self.config.get("default_lane_width")
        self.minConnectionLength = self.config.get("min_connection_length")
        self.maxConnectionLength = self.config.get("max_connection_length")
        self.curveBuilder = CurveRoadBuilder(country=country)
        self.connectionBuilder = ConnectionBuilder()
        self.countryCode = country
        np.random.seed(random_seed)
        pass

    def createJunctionForASeriesOfRoads(self, roads, id=0):
        """[summary]

        Args:
            roads ([type]): even indices are roads, odd indices are connection roads  of the junction

        Returns:
            [type]: [description]
        """

        # TODO it does not support all lanes.
        # ID is wrong
        junction = pyodrx.Junction("spiderJunction", id)

        connectionId = 1

        while (connectionId < len(roads)):

            print(f"connecting roads {connectionId-1} {connectionId}")
            connectionL = pyodrx.Connection(connectionId - 1, connectionId,
                                            pyodrx.ContactPoint.start)
            connectionL.add_lanelink(-1, -1)

            # if (connectionId + 1) < len(roads):
            #     connectionR = pyodrx.Connection(connectionId+1, connectionId, pyodrx.ContactPoint.end)
            # else:
            #     connectionR = pyodrx.Connection(0, connectionId, pyodrx.ContactPoint.end)

            # connectionR.add_lanelink(1,1)

            junction.add_connection(connectionL)
            # junction.add_connection(connectionR)

            connectionId += 2

        return junction

    def createLastConnectionForLastAndFirstRoad(self,
                                                nextRoadId,
                                                roads,
                                                junction,
                                                cp1=pyodrx.ContactPoint.end,
                                                cp2=pyodrx.ContactPoint.start):

        lastConnectionId = nextRoadId
        lastConnection = self.roadBuilder.getConnectionRoadBetween(
            lastConnectionId, roads[-1], roads[0], cp2, cp1)

        RoadLinker.createExtendedPredSuc(predRoad=roads[-1],
                                         predCp=cp2,
                                         sucRoad=lastConnection,
                                         sucCP=pyodrx.ContactPoint.start)
        RoadLinker.createExtendedPredSuc(predRoad=lastConnection,
                                         predCp=pyodrx.ContactPoint.end,
                                         sucRoad=roads[0],
                                         sucCP=cp1)

        connectionL = pyodrx.Connection(roads[-1].id, lastConnectionId,
                                        pyodrx.ContactPoint.start)
        connectionL.add_lanelink(-1, -1)
        junction.add_connection(connectionL)

        # roads.append(lastConnection) # dangerous. do not add the road

        return lastConnection

    def createConnectionFor2Roads(self,
                                  nextRoadId,
                                  road1,
                                  road2,
                                  junction,
                                  cp1,
                                  cp2,
                                  n_lanes=1,
                                  lane_offset=3,
                                  laneSides=LaneSides.BOTH):
        """Does not modify predecessor or successor of the given roads.

        Args:
            junction: the junction object to add links.

        Returns:
            [type]: connection road with first road as the predecessor and second road as the successor
        """

        newConnectionId = nextRoadId
        newConnectionRoad = self.roadBuilder.getConnectionRoadBetween(
            newConnectionId,
            road1,
            road2,
            cp1,
            cp2,
            isJunction=True,
            n_lanes=n_lanes,
            lane_offset=lane_offset,
            laneSides=laneSides)

        RoadLinker.createExtendedPredSuc(predRoad=road1,
                                         predCp=cp1,
                                         sucRoad=newConnectionRoad,
                                         sucCP=pyodrx.ContactPoint.start)
        RoadLinker.createExtendedPredSuc(predRoad=newConnectionRoad,
                                         predCp=pyodrx.ContactPoint.end,
                                         sucRoad=road2,
                                         sucCP=cp2)

        if junction is not None:
            if laneSides == LaneSides.LEFT or laneSides == LaneSides.BOTH:
                connectionL = pyodrx.Connection(road2.id, newConnectionId,
                                                pyodrx.ContactPoint.end)
                connectionL.add_lanelink(-1, -1)
                junction.add_connection(connectionL)
            else:
                connectionL = pyodrx.Connection(road1.id, newConnectionId,
                                                pyodrx.ContactPoint.start)
                connectionL.add_lanelink(1, 1)
                junction.add_connection(connectionL)

        return newConnectionRoad

    def createInternalConnectionsForConnectionSeres(self, roads,
                                                    connectionSeres, junction):
        """Assumes last road has the largest id. Used to create internal connections inside a junction. Assumes a connection series has middle roads which are connected by an internal connection road. Normally each series will have 3 roads.

        Args:
            roads ([type]): [description]
            connectionSeres ([type]): list of ConnectionSeries type
        """

        # for each last road in a series, connect with the next first road
        length = len(connectionSeres)
        nextRoadId = connectionSeres[-1].getLast().id + 1  # last id so far.

        for i in range(length):
            currentConnectionS = connectionSeres[i]

            if (i + 1) < length:
                nextConnectionS = connectionSeres[i + 1]
            else:
                nextConnectionS = connectionSeres[0]

            # traffic will go from current to next

            fromRoad = currentConnectionS.getMiddle()
            toRoad = nextConnectionS.getMiddle()

            print(
                f"creating internal connection from {fromRoad.id} to {toRoad.id}"
            )

            newConnection = self.createConnectionFor2Roads(
                nextRoadId,
                fromRoad,
                toRoad,
                cp1=pyodrx.ContactPoint.end,
                cp2=pyodrx.ContactPoint.start,
                junction=junction,
                laneSides=LaneSides.RIGHT)

            roads.append(newConnection)

            nextRoadId += 1

        return nextRoadId

    def buildSimpleRoundAbout(self,
                              odrId=0,
                              numRoads=4,
                              radius=10,
                              cp1=pyodrx.ContactPoint.start,
                              direction=CircularDirection.COUNTERCLOCK_WISE):
        """In a simple roundabout, there is a circle inside the junction, the connection roads reside in the circle.

        Args:
            numRoads (int, optional): [description]. Defaults to 4.
            radius : in meters.
            cp1: contact point on the first road.
        """

        anglePerRoad = (np.pi * 2) / numRoads

        roads = []
        roads.append(
            self.straightRoadBuilder.create(0, length=self.straightRoadLen))
        nextRoadId = 1

        roadsCreated = 1

        connectionSeres = [
        ]  # holds all the connection road series so that we can create internal connections later.

        while roadsCreated < numRoads:
            previousRoadId = nextRoadId - 1
            newConnectionId = nextRoadId

            # 1. create a new connection road series and increase nextRoadId
            newConnectionSeries = self.roadBuilder.createRoundAboutConnection(
                newConnectionId, anglePerRoad, radius)
            connectionSeres.append(newConnectionSeries)

            nextRoadId += newConnectionSeries.length()
            newRoadId = nextRoadId
            nextRoadId += 1

            # 2. create a road
            newRoad = self.straightRoadBuilder.create(
                newRoadId, length=self.straightRoadLen)

            # 3 add new roads
            roads += newConnectionSeries.getAll()
            roads.append(newRoad)

            roads[previousRoadId].addExtendedSuccessor(
                newConnectionSeries.getFirst(), 0, pyodrx.ContactPoint.start)

            if newConnectionSeries.getFirst().id == 1:
                newConnectionSeries.getFirst().addExtendedPredecessor(
                    roads[previousRoadId], 0, cp1)
                # TODO this is a hack. It will not eventually work because outgoing roads' ends will come to join other junctions.
            else:
                newConnectionSeries.getFirst().addExtendedPredecessor(
                    roads[previousRoadId], 0, pyodrx.ContactPoint.start)

            RoadLinker.createExtendedPredSuc(
                predRoad=newConnectionSeries.getLast(),
                predCp=pyodrx.ContactPoint.end,
                sucRoad=newRoad,
                sucCP=pyodrx.ContactPoint.start)

            # 6 get next action
            roadsCreated += 1

            pass

        lastRoad = roads[-1]
        # 3. create connections and junction

        junction = self.createJunctionForASeriesOfRoads(roads)

        # print(f"number of roads created {len(roads)}")
        odrName = 'Simple-Roundabout-' + str(numRoads) + '_L2_' + str(odrId)
        odr = extensions.createOdrByPredecessor(odrName, roads, [junction])

        # The last connection and resetting odr

        finalConnectionSeries = self.roadBuilder.createRoundAboutConnection(
            nextRoadId, anglePerRoad, radius)
        connectionSeres.append(finalConnectionSeries)

        roads += finalConnectionSeries.getAll()

        RoadLinker.createExtendedPredSuc(
            predRoad=lastRoad,
            predCp=pyodrx.ContactPoint.start,
            sucRoad=finalConnectionSeries.getFirst(),
            sucCP=pyodrx.ContactPoint.start)
        RoadLinker.createExtendedPredSuc(
            predRoad=finalConnectionSeries.getLast(),
            predCp=pyodrx.ContactPoint.end,
            sucRoad=roads[0],
            sucCP=cp1)

        odr.updateRoads(roads)
        odr.resetAndReadjust(byPredecessor=True)

        # Last step, link connection series by curves

        self.createInternalConnectionsForConnectionSeres(
            roads, connectionSeres, junction)

        odr.updateRoads(roads)
        odr.resetAndReadjust(byPredecessor=True)

        return odr

    def createConnectionRoads(self,
                              roads,
                              adjusted=False,
                              areaType=JunctionAreaTypes.SQUARE):

        if adjusted is False:
            # set up x,y positions and headings for the roads around the boundary of the area

            if areaType == JunctionAreaTypes.SQUARE:
                # maximum roads to connect to a side
                maxRoadsPerSide = math.floor(len(roads) / 4) + 1

    def createWithRandomLaneConfigurations(self, numRoads=3):

        raise NotImplementedError()
Exemple #16
0
class test_ExtendedRoad(unittest.TestCase):
    def setUp(self):

        self.configuration = Configuration()
        self.roadBuilder = junctions.RoadBuilder()

        self.straightRoadBuilder = StraightRoadBuilder()
        self.roadLinker = RoadLinker()

    def test_getArcAngle(self):

        for _ in range(1, 10):
            for i in range(1, 10):
                inputAngle = (np.pi * i) / 10
                road = self.roadBuilder.createRandomCurve(0, inputAngle)

                if road.curveType == StandardCurveTypes.S:
                    continue

                outputAngle = road.getArcAngle()
                deviation = abs(inputAngle - outputAngle) * 100 / inputAngle

                print(
                    f"curveType: {road.curveType} inputAngle: {math.degrees(inputAngle)} outputAngle: {math.degrees(outputAngle)} deviation: {deviation}"
                )
                assert deviation < 50.0

    def test_getBorderDistanceOfLane(self):

        roads = []

        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(0,
                                                              length=10,
                                                              junction=-1,
                                                              n_lanes_left=1,
                                                              n_lanes_right=1))
        roads.append(
            self.straightRoadBuilder.createWithRightTurnLanesOnLeft(
                1,
                length=10,
                n_lanes=1,
                junction=1,
                isLeftTurnLane=True,
                isRightTurnLane=True,
                numberOfRightTurnLanesOnLeft=2,
                mergeLaneOnTheOppositeSideForInternalTurn=False))
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(2,
                                                              length=10,
                                                              junction=-1,
                                                              n_lanes_left=4,
                                                              n_lanes_right=2))
        self.roadLinker.linkConsecutiveRoadsWithNoBranches(roads)

        assert roads[0].getBorderDistanceOfLane(1,
                                                pyodrx.ContactPoint.start) == 3
        assert roads[0].getBorderDistanceOfLane(-1,
                                                pyodrx.ContactPoint.start) == 3
        assert roads[1].getBorderDistanceOfLane(1,
                                                pyodrx.ContactPoint.start) == 3
        assert roads[1].getBorderDistanceOfLane(2,
                                                pyodrx.ContactPoint.end) == 6
        assert roads[1].getBorderDistanceOfLane(3,
                                                pyodrx.ContactPoint.end) == 9
        assert roads[1].getBorderDistanceOfLane(4,
                                                pyodrx.ContactPoint.end) == 12
        assert roads[1].getBorderDistanceOfLane(-1,
                                                pyodrx.ContactPoint.start) == 3

        roads[1].updatePredecessorOffset(-1)

        odrName = "test_getBorderDistanceOfLane"
        odr = extensions.createOdrByPredecessor(odrName, roads, [])

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

        xmlPath = f"output/test_getBorderDistanceOfLane.xodr"
        odr.write_xml(xmlPath)

        roads = []

        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(0,
                                                              length=10,
                                                              junction=-1,
                                                              n_lanes_left=2,
                                                              n_lanes_right=2))
        roads.append(
            self.straightRoadBuilder.createWithRightTurnLanesOnLeft(
                1,
                length=10,
                n_lanes=2,
                junction=1,
                isLeftTurnLane=True,
                isRightTurnLane=True,
                numberOfRightTurnLanesOnLeft=2,
                mergeLaneOnTheOppositeSideForInternalTurn=False))
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(2,
                                                              length=10,
                                                              junction=-1,
                                                              n_lanes_left=5,
                                                              n_lanes_right=3))
        self.roadLinker.linkConsecutiveRoadsWithNoBranches(roads)

        roads[1].updatePredecessorOffset(-2)

        odrName = "test_getBorderDistanceOfLane"
        odr = extensions.createOdrByPredecessor(odrName, roads, [])

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

        xmlPath = f"output/test_getBorderDistanceOfLane.xodr"
        odr.write_xml(xmlPath)

    def test_getLanePosition(self):

        roads = []

        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(0,
                                                              length=10,
                                                              junction=-1,
                                                              n_lanes_left=2,
                                                              n_lanes_right=2))
        roads.append(
            self.straightRoadBuilder.createWithRightTurnLanesOnLeft(
                1,
                length=10,
                n_lanes=2,
                junction=1,
                isLeftTurnLane=True,
                isRightTurnLane=True,
                numberOfRightTurnLanesOnLeft=2,
                mergeLaneOnTheOppositeSideForInternalTurn=False))
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(2,
                                                              length=10,
                                                              junction=-1,
                                                              n_lanes_left=5,
                                                              n_lanes_right=3))
        self.roadLinker.linkConsecutiveRoadsWithNoBranches(roads)

        roads[1].updatePredecessorOffset(-2)

        odrName = "test_getBorderDistanceOfLane"
        odr = extensions.createOdrByPredecessor(odrName, roads, [])

        extensions.printRoadPositions(odr)

        print(roads[0].getLanePosition(0, pyodrx.ContactPoint.end))
        print(roads[0].getLanePosition(1, pyodrx.ContactPoint.end))
        print(roads[0].getLanePosition(2, pyodrx.ContactPoint.end))

        positionLeftMost = roads[0].getLanePosition(2, pyodrx.ContactPoint.end)
        assert positionLeftMost[0] == 10.0
        assert positionLeftMost[1] == 6.0
        assert positionLeftMost[2] == 0

        extensions.view_road(
            odr, os.path.join('..', self.configuration.get("esminipath")))
Exemple #17
0
class test_LaneConfiguration(unittest.TestCase):
    def setUp(self):

        self.configuration = Configuration()

        self.straightRoadBuilder = StraightRoadBuilder()

    def test_getLaneLinksByMergingEdge(self):

        # 1
        centerLane = ExtendedLane(pyodrx.LaneType.median)
        section1 = ExtendedLaneSection(0, centerLane)
        section2 = ExtendedLaneSection(0, centerLane)

        section1.add_left_lane(ExtendedLane(a=3))
        section1.add_right_lane(ExtendedLane(a=3))

        section2.add_left_lane(ExtendedLane(a=3))

        ls, rs = LaneConfiguration.getLaneLinksByMergingEdge(
            section1, section2, False)

        assert len(ls) == max(len(section1.leftlanes), len(section2.leftlanes))
        assert len(rs) == 0

        # [(1, 1, False)]
        assert ls[0][0] == 1 and ls[0][1] == 1 and ls[0][2] == False

        print("test 1")
        print(ls)
        print(rs)

        #2

        section2.add_right_lane(ExtendedLane(a=3))
        ls, rs = LaneConfiguration.getLaneLinksByMergingEdge(
            section1, section2, False)
        assert len(ls) == max(len(section1.leftlanes), len(section2.leftlanes))
        assert len(rs) == max(len(section1.rightlanes),
                              len(section2.rightlanes))
        assert ls[0][0] == 1 and ls[0][1] == 1 and ls[0][2] == False
        assert rs[0][0] == -1 and rs[0][1] == -1 and rs[0][2] == False

        print("test 2")
        print(ls)
        print(rs)

        section1.add_left_lane(ExtendedLane(a=3))
        section1.add_left_lane(ExtendedLane(a=3))

        ls, rs = LaneConfiguration.getLaneLinksByMergingEdge(
            section1, section2, False)
        print("test 3")
        print(ls)
        print(rs)
        assert len(ls) == max(len(section1.leftlanes), len(section2.leftlanes))
        assert len(rs) == max(len(section1.rightlanes),
                              len(section2.rightlanes))
        assert ls[0][0] == 1 and ls[0][1] == 1 and ls[0][2] == False
        assert rs[0][0] == -1 and rs[0][1] == -1 and rs[0][2] == False

        section2.add_right_lane(ExtendedLane(a=3))

        ls, rs = LaneConfiguration.getLaneLinksByMergingEdge(
            section1, section2, False)
        print("test 4")
        print(ls)
        print(rs)
        assert len(ls) == max(len(section1.leftlanes), len(section2.leftlanes))
        assert len(rs) == max(len(section1.rightlanes),
                              len(section2.rightlanes))
        assert ls[0][0] == 1 and ls[0][1] == 1 and ls[0][2] == False
        assert rs[0][0] == -1 and rs[0][1] == -1 and rs[0][2] == False

        section2.add_left_lane(ExtendedLane(a=3))
        section2.add_left_lane(ExtendedLane(a=3))
        section2.add_left_lane(ExtendedLane(a=3))
        section2.add_left_lane(ExtendedLane(a=3))
        section1.add_right_lane(ExtendedLane(a=3))
        section1.add_right_lane(ExtendedLane(a=3))

        ls, rs = LaneConfiguration.getLaneLinksByMergingEdge(
            section1, section2, False)
        print("test 5")
        print(ls)
        print(rs)
        assert len(ls) == max(len(section1.leftlanes), len(section2.leftlanes))
        assert len(rs) == max(len(section1.rightlanes),
                              len(section2.rightlanes))
        assert ls[0][0] == 1 and ls[0][1] == 1 and ls[0][2] == False
        assert rs[0][0] == -1 and rs[0][1] == -1 and rs[0][2] == False

        straightLanesLeft = set([i for i, _, conType in ls if conType == 0])
        print(straightLanesLeft)

    def test_getIntersectionLinks1ToMany(self):

        incomingLanes = ['1:-1', '1:-2']
        outgoingLanes = ['2:1']

        try:
            LaneConfiguration.getIntersectionLinks1ToMany(
                incomingLanes, outgoingLanes)
            assert False
        except Exception as e:
            print(e)
            pass

        incomingLanes = ['1:-1', '1:-2']
        outgoingLanes = ['2:1', '2:2']

        try:
            connections = LaneConfiguration.getIntersectionLinks1ToMany(
                incomingLanes, outgoingLanes)
            assert connections[0][0] == '1:-1'
            assert connections[0][1] == '2:1'
            assert connections[0][2] == 0
            assert connections[1][0] == '1:-2'
            assert connections[1][1] == '2:2'
            assert connections[1][2] == 0
            # print(connections)
        except Exception as e:
            print(e)
            assert False

        incomingLanes = ['1:-1', '1:-2']
        outgoingLanes = ['2:1', '2:2', '3:1']

        try:
            connections = LaneConfiguration.getIntersectionLinks1ToMany(
                incomingLanes, outgoingLanes)
            assert connections[0][0] == '1:-1'
            assert connections[0][1] == '2:1'
            assert connections[0][2] == 0
            assert connections[1][0] == '1:-2'
            assert connections[1][1] == '2:2'
            assert connections[1][2] == 0
            assert connections[2][0] == '1:-2'
            assert connections[2][1] == '3:1'
            assert connections[2][2] == 2
            print(connections)
        except Exception as e:
            print(e)
            assert False

    def test_getUniqueLaneIds(self):

        roads = []
        roads.append(self.straightRoadBuilder.create(0, length=10, n_lanes=2))
        laneIds = LaneConfiguration.getUniqueLaneIds(
            roads[0],
            roads[0].getLaneSectionByCP(pyodrx.ContactPoint.start).leftlanes)
        # print(laneIds)
        assert laneIds[0] == '0:1'
        assert laneIds[1] == '0:2'

        laneIds = LaneConfiguration.getUniqueLaneIds(
            roads[0],
            roads[0].getLaneSectionByCP(pyodrx.ContactPoint.start).rightlanes)
        assert laneIds[0] == '0:-1'
        assert laneIds[1] == '0:-2'

    def test_getOutgoingLanesFromARoad(self):

        roads = []
        roads.append(
            self.straightRoadBuilder.create(0,
                                            length=10,
                                            n_lanes_left=2,
                                            n_lanes_right=2))
        roads.append(
            self.straightRoadBuilder.create(1,
                                            length=10,
                                            n_lanes_left=1,
                                            n_lanes_right=1))
        roads.append(
            self.straightRoadBuilder.create(2,
                                            length=10,
                                            n_lanes_left=2,
                                            n_lanes_right=2))

        inLanes = LaneConfiguration.getIncomingLaneIdsOnARoad(
            roads[0], pyodrx.ContactPoint.end, CountryCodes.US)
        outLanes = LaneConfiguration.getOutgoingLanesIdsFromARoad(
            roads[0],
            roads,
            cp1=pyodrx.ContactPoint.end,
            countryCode=CountryCodes.US)
        assert inLanes[0] == '0:-1'
        assert inLanes[1] == '0:-2'
        assert outLanes[0] == '1:-1'
        assert outLanes[1] == '2:-1'
        assert outLanes[2] == '2:-2'

        inLanes = LaneConfiguration.getIncomingLaneIdsOnARoad(
            roads[1], pyodrx.ContactPoint.start, CountryCodes.US)
        outLanes = LaneConfiguration.getOutgoingLanesIdsFromARoad(
            roads[1],
            roads,
            cp1=pyodrx.ContactPoint.end,
            countryCode=CountryCodes.US)
        print(inLanes)
        print(outLanes)
        assert inLanes[0] == '1:1'
        assert outLanes[0] == '2:-1'
        assert outLanes[1] == '2:-2'
        assert outLanes[2] == '0:1'
        assert outLanes[3] == '0:2'

        inLanes = LaneConfiguration.getIncomingLaneIdsOnARoad(
            roads[2], pyodrx.ContactPoint.start, CountryCodes.US)
        outLanes = LaneConfiguration.getOutgoingLanesIdsFromARoad(
            roads[2],
            roads,
            cp1=pyodrx.ContactPoint.end,
            countryCode=CountryCodes.US)
        print(inLanes)
        print(outLanes)
        assert inLanes[0] == '2:1'
        assert inLanes[1] == '2:2'
        assert outLanes[0] == '0:1'
        assert outLanes[1] == '0:2'
        assert outLanes[2] == '1:-1'

        linkConfig = LaneConfiguration.getIntersectionLinks1ToMany(
            inLanes, outLanes)

        print(linkConfig)

    def test_get1To1Connections(self):

        incomingLanes = ['1:-1', '1:-2']
        outgoingLanes = ['2:1', '2:2']

        connections = LaneConfiguration.get1To1Connections(
            incomingLanes, outgoingLanes, True)
        assert connections[0][0] == '1:-1'
        assert connections[0][1] == '2:1'
        assert connections[0][2] == 0
        assert connections[1][0] == '1:-2'
        assert connections[1][1] == '2:2'
        assert connections[1][2] == 0

        incomingLanes = ['1:-1', '1:-2']
        outgoingLanes = ['2:1', '2:2', '3:1']
        connections = LaneConfiguration.get1To1Connections(
            incomingLanes, outgoingLanes, True)

        assert len(connections) == 2
        assert connections[0][0] == '1:-1'
        assert connections[0][1] == '2:1'
        assert connections[0][2] == 0
        assert connections[1][0] == '1:-2'
        assert connections[1][1] == '2:2'
        assert connections[1][2] == 0
        connections = LaneConfiguration.get1To1Connections(
            incomingLanes, outgoingLanes, False)

        # print(connections)
        assert len(connections) == 2
        assert connections[0][0] == '1:-1'
        assert connections[0][1] == '2:2'
        assert connections[0][2] == 0
        assert connections[1][0] == '1:-2'
        assert connections[1][1] == '3:1'
        assert connections[1][2] == 0

        incomingLanes = ['1:-1']
        outgoingLanes = ['2:1', '2:2', '3:1']
        connections = LaneConfiguration.get1To1Connections(
            incomingLanes, outgoingLanes, False)

        # print(connections)
        assert len(connections) == 1
        assert connections[0][0] == '1:-1'
        assert connections[0][1] == '3:1'
        assert connections[0][2] == 0

    def test_getIntersectionLinks1ToManyBySplittingFirst(self):

        incomingLanes = ['1:-1', '1:-2']
        outgoingLanes = ['2:1', '2:2']

        connections = LaneConfiguration.getIntersectionLinks1ToManyBySplittingFirst(
            incomingLanes, outgoingLanes)
        assert connections[0][0] == '1:-1'
        assert connections[0][1] == '2:1'
        assert connections[0][2] == 0
        assert connections[1][0] == '1:-2'
        assert connections[1][1] == '2:2'
        assert connections[1][2] == 0

        incomingLanes = ['1:-1', '1:-2']
        outgoingLanes = ['2:1', '2:2', '3:1']
        connections = LaneConfiguration.getIntersectionLinks1ToManyBySplittingFirst(
            incomingLanes, outgoingLanes)

        print(connections)
        assert len(connections) == 3
        assert connections[0][0] == '1:-1'
        assert connections[0][1] == '2:1'
        assert connections[0][2] == 2
        assert connections[1][0] == '1:-1'
        assert connections[1][1] == '2:2'
        assert connections[1][2] == 0
        assert connections[2][0] == '1:-2'
        assert connections[2][1] == '3:1'
        assert connections[2][2] == 0
class test_LaneBuilder(unittest.TestCase):
    def setUp(self):

        self.configuration = Configuration()
        self.esminiPath = self.configuration.get("esminipath")
        self.roadBuilder = RoadBuilder()
        self.laneBuilder = LaneBuilder()
        self.laneLinker = LaneLinker()
        self.straightRoadBuilder = StraightRoadBuilder()

    def test_RightLane(self):
        # test scenario for connection road

        roads = []
        roads.append(pyodrx.create_straight_road(0, 10))
        # roads.append(self.roadBuilder.createSimpleCurve(1, np.pi/4, True, curvature = 0.2))
        # 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, pyodrx.ContactPoint.end)

        odrName = "test_connectionRoad"
        odr = extensions.createOdrByPredecessor(odrName, roads, [])

        self.laneBuilder.addRightTurnLaneUS(roads[0], 3)
        # self.laneBuilder.addRightLaneUS(roads[1])

        odr.resetAndReadjust(byPredecessor=True)

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

        xmlPath = f"output/test-RightLane.xodr"
        odr.write_xml(xmlPath)

    def test_DifferentLaneConfigurations(self):
        roads = []
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(0,
                                                              10,
                                                              n_lanes_left=1,
                                                              n_lanes_right=1))
        connectionRoad = self.straightRoadBuilder.createWithDifferentLanes(
            1, 10, n_lanes_left=2, n_lanes_right=2)
        roads.append(connectionRoad)
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(2,
                                                              10,
                                                              n_lanes_left=1,
                                                              n_lanes_right=2))

        roads[0].addExtendedSuccessor(roads[1], 0, pyodrx.ContactPoint.start)

        roads[1].addExtendedPredecessor(roads[0], 0, pyodrx.ContactPoint.end)
        roads[1].addExtendedSuccessor(roads[2], 0, pyodrx.ContactPoint.start)

        roads[2].addExtendedPredecessor(roads[1], 0, pyodrx.ContactPoint.end)

        self.laneBuilder.createLanesForConnectionRoad(connectionRoad, roads[0],
                                                      roads[2])

        odrName = "test_DifferentLaneConfigurations"
        odr = extensions.createOdrByPredecessor(odrName, roads, [])

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

        xmlPath = f"output/test_DifferentLaneConfigurations.xodr"
        odr.write_xml(xmlPath)

    def test_addMedianIslandsToAllSections(self):
        roads = []
        roads.append(
            self.straightRoadBuilder.createWithDifferentLanes(0,
                                                              10,
                                                              n_lanes_left=1,
                                                              n_lanes_right=1))
        self.laneBuilder.addMedianIslandsToAllSections(
            roads[0], self.configuration.get('default_lane_width'))
        odrName = "test_DifferentLaneConfigurations"
        odr = extensions.createOdrByPredecessor(odrName, roads, [])

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

        xmlPath = f"output/test_addMedianIslandsToAllSections.xodr"
        odr.write_xml(xmlPath)

    def test_addMedianIslandsTo3Sections(self):

        road = self.straightRoadBuilder.create(1,
                                               n_lanes_left=1,
                                               n_lanes_right=1,
                                               length=20,
                                               force3Section=False)

        try:
            self.laneBuilder.addMedianIslandsTo2Of3Sections(
                road, 20, skipEndpoint=pyodrx.ContactPoint.start, width=3)
            assert False
        except:
            assert True

        road = self.straightRoadBuilder.create(1,
                                               n_lanes_left=1,
                                               n_lanes_right=1,
                                               length=20,
                                               force3Section=True)
        self.laneBuilder.addMedianIslandsTo2Of3Sections(
            road, 20, skipEndpoint=pyodrx.ContactPoint.start, width=3)

        assert len(road.lanes.lanesections[0].leftlanes) == 1
        assert len(road.lanes.lanesections[0].rightlanes) == 1
        assert len(road.lanes.lanesections[1].leftlanes) == 2
        assert len(road.lanes.lanesections[1].rightlanes) == 2
        assert len(road.lanes.lanesections[2].leftlanes) == 2
        assert len(road.lanes.lanesections[2].rightlanes) == 2

        road = self.straightRoadBuilder.create(1,
                                               n_lanes_left=1,
                                               n_lanes_right=1,
                                               length=20,
                                               force3Section=True)
        self.laneBuilder.addMedianIslandsTo2Of3Sections(
            road, 20, skipEndpoint=pyodrx.ContactPoint.end, width=3)

        assert len(road.lanes.lanesections[0].leftlanes) == 2
        assert len(road.lanes.lanesections[0].rightlanes) == 2
        assert len(road.lanes.lanesections[1].leftlanes) == 2
        assert len(road.lanes.lanesections[1].rightlanes) == 2
        assert len(road.lanes.lanesections[2].leftlanes) == 1
        assert len(road.lanes.lanesections[2].rightlanes) == 1

        odrName = "test_DifferentLaneConfigurations"
        odr = extensions.createOdrByPredecessor(odrName, [road], [])

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

        xmlPath = f"output/test_addMedianIslandsTo3Sections.xodr"
        odr.write_xml(xmlPath)