def test_SimpleCurve(self):

        roads = []
        roads.append(
            self.curveRoadBuilder.create(0,
                                         angleBetweenEndpoints=np.pi / 2,
                                         curvature=0.05,
                                         isLeftTurnLane=True))

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

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

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

        roads = []
        roads.append(
            self.curveRoadBuilder.create(0,
                                         angleBetweenEndpoints=np.pi / 2,
                                         curvature=0.05,
                                         isRightTurnLane=True))

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

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

        xmlPath = f"output/test_RightTurnLaneCurve.xodr"
        odr.write_xml(xmlPath)
Пример #2
0
    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)
    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)
Пример #4
0
    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_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_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_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)
    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)
Пример #9
0
    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")))
    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)
Пример #11
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)
Пример #12
0
    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 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)
    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 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 createWithRandomLaneConfigurations(self, 
                                            straightRoadsPath, 
                                            id, 
                                            maxNumberOfRoadsPerJunction, 
                                            firstRoadId=0,
                                            maxLanePerSide=2, 
                                            minLanePerSide=0, 
                                            internalConnections=True, 
                                            cp1=pyodrx.ContactPoint.end, 
                                            randomState=None,
                                            internalLinkStrategy = LaneConfigurationStrategies.SPLIT_ANY, 
                                            uTurnLanes=1,
                                            equalAngles=False,
                                            getAsOdr=True):
        """All the incoming roads, except for the first, will have their start endpoint connected to the junction.

        Args:
            straightRoadsPath ([type]): [description]
            odrId ([type]): [description]
            maxNumberOfRoadsPerJunction ([type]): [description]
            maxLanePerSide (int, optional): [description]. Defaults to 2.
            minLanePerSide (int, optional): [description]. Defaults to 0.
            internalConnections (bool, optional): [description]. Defaults to True.
            cp1 ([type], optional): [description]. Defaults to pyodrx.ContactPoint.start.
            randomState ([type], optional): [description]. Defaults to None.

        Raises:
            Exception: [description]

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


        if maxNumberOfRoadsPerJunction < 2:
            raise Exception("Please add more than 1 roads")

        if uTurnLanes > 1:
            raise Exception("U-turn from more than one lanes is not implemented")

        harvestedStraightRoads = []

        # if restrictedLanes:
        #     harvestedStraightRoads = []
        # else:
        #     harvestedStraightRoads = extensions.getObjectsFromDill(straightRoadsPath)

        if randomState is not None:
            np.random.set_state(randomState)

        incidentContactPoints = []
        outsideRoads = [] # all the incoming/outgoing roads in this junction
        geoConnectionRoads = [] # connections roads which are for geometric positions, having no lanes
        laneConnectionRoads = [] # connection roads that have lanes.
        roads = []

        if cp1 == pyodrx.ContactPoint.end:
            roads.append(self.createRandomStraightRoad(0, maxLanePerSide=maxLanePerSide, minLanePerSide=minLanePerSide, skipEndpoint=pyodrx.ContactPoint.start)) # first road
        else:
            roads.append(self.createRandomStraightRoad(0, maxLanePerSide=maxLanePerSide, minLanePerSide=minLanePerSide, skipEndpoint=pyodrx.ContactPoint.end)) # first road
        

        # if restrictedLanes:
        #     if cp1 == pyodrx.ContactPoint.end:
        #         roads.append(self.createRandomStraightRoad(0, maxLanePerSide=maxLanePerSide, minLanePerSide=minLanePerSide, skipEndpoint=pyodrx.ContactPoint.start)) # first road
        #     else:
        #         roads.append(self.createRandomStraightRoad(0, maxLanePerSide=maxLanePerSide, minLanePerSide=minLanePerSide, skipEndpoint=pyodrx.ContactPoint.end)) # first road
        # else:
        #     roads.append(self.getRandomHarvestedStraightRoad(0, harvestedStraightRoads, maxLanePerSide, minLanePerSide)) # first road

        roads[0].id = firstRoadId
        outsideRoads.append(roads[0])
        incidentContactPoints.append(cp1)

        availableAngle = 1.8 * np.pi # 360 degrees
        if equalAngles:
            availableAngle = np.pi * 2
        maxAnglePerConnection = availableAngle / maxNumberOfRoadsPerJunction
        action = self.actionAfterDrawingOne(roads, availableAngle, maxNumberOfRoadsPerJunction)
        nextRoadId = firstRoadId + 1
        otherContactPoints = pyodrx.ContactPoint.start
        nIncidentAdded = 1
        while (action != "end"):

            logging.debug(f"{self.name}: availableAngle {math.degrees(availableAngle)}, number of roads: {len(roads) / 2}")

            # 0. road id generation
            previousRoadId = nextRoadId - 1
            prevIncidentRoad = roads[-1]
            newConnectionId = nextRoadId
            nextRoadId += 1
            newRoadId = nextRoadId
            nextRoadId += 1
            prevCp = otherContactPoints
            if len(roads) == 1: # first road
                prevCp = cp1

            # 1. create a road
            # newRoad = self.getRandomHarvestedStraightRoad(newRoadId, harvestedStraightRoads, maxLanePerSide, minLanePerSide)
            newRoad = self.createRandomStraightRoad(newRoadId, maxLanePerSide, minLanePerSide, skipEndpoint=pyodrx.ContactPoint.end) 
            # if restrictedLanes:
            #     newRoad = self.createRandomStraightRoad(newRoadId, maxLanePerSide, minLanePerSide, skipEndpoint=pyodrx.ContactPoint.end) 
            # else:
            #     newRoad = self.getRandomHarvestedStraightRoad(newRoadId, harvestedStraightRoads, maxLanePerSide, minLanePerSide)

            outsideRoads.append(newRoad)
            incidentContactPoints.append(otherContactPoints)

            # 2. create a new connection road

            prevLanes, nextLanes = self.laneBuilder.getClockwiseAdjacentLanes(prevIncidentRoad, prevCp, newRoad, otherContactPoints)
            # maxLaneWidth = ((len(prevLanes) + len(nextLanes)) * self.laneWidth) / 2
            maxLaneWidth = max(len(prevLanes), len(nextLanes)) * self.laneWidth
            if len(prevLanes) == 0 or len(nextLanes) == 0:
                maxLaneWidth = ((len(prevLanes) + len(nextLanes)) * self.laneWidth) / 2

            availableAngle -= (maxNumberOfRoadsPerJunction - nIncidentAdded - 1) * self.minAngle
            # print(f"Before connection road: minAngle: remaining roads:{maxNumberOfRoadsPerJunction - nIncidentAdded - 1}, {math.degrees(self.minAngle)}, available Angle: {math.degrees(availableAngle)}")

            newConnection, availableAngle = self.createGeoConnectionRoad(action, newConnectionId, availableAngle, maxAnglePerConnection, maxLaneWidth=maxLaneWidth, equalAngles=equalAngles)
            geoConnectionRoads.append(newConnection)

            availableAngle += (maxNumberOfRoadsPerJunction - nIncidentAdded - 1) * self.minAngle
            # print(f"after connection road: minAngle: {math.degrees(self.minAngle)}, available Angle: {math.degrees(availableAngle)}")
            
            # 5 add new roads
            roads.append(newConnection)
            roads.append(newRoad)
            
            RoadLinker.createExtendedPredSuc(predRoad=prevIncidentRoad, predCp=prevCp, sucRoad=newConnection, sucCP=pyodrx.ContactPoint.start)
            RoadLinker.createExtendedPredSuc(predRoad=newConnection, predCp=pyodrx.ContactPoint.end, sucRoad=newRoad, sucCP=otherContactPoints)

            self.laneBuilder.createLanesForConnectionRoad(newConnection, prevIncidentRoad, newRoad)

            # 6 get next action
            action = self.actionAfterDrawingOne(roads, availableAngle, maxNumberOfRoadsPerJunction)
            nIncidentAdded += 1
            pass
        
        # 3.0 fix outgoing lane numbers

        self.fixNumOutgoingLanes(outsideRoads, cp1)

        # 3. create connections and junction
        # TODO this is not correct anymore.
        # junction = self.createJunctionForASeriesOfRoads(roads)
        junction = pyodrx.Junction("singleConnectionsJunction", id)
        # junction = pyodrx.Junction("singleConnectionsJunction", firstRoadId)

        odrName = 'Draw_Rmax' + str(maxNumberOfRoadsPerJunction) + '_L2_' + str(id)
        odr = extensions.createOdrByPredecessor(odrName, roads, [junction])

        
        logging.debug(f"{self.name}: roads before internal connections {len(roads)}")

        # Permanent connection roads
        if internalConnections:
            internalConnections = self.connectionBuilder.createSingleLaneConnectionRoads(nextRoadId, outsideRoads, cp1, internalLinkStrategy)
            nextRoadId += len(internalConnections)
            roads += internalConnections
            odr.updateRoads(roads)

            # remove lanes from connection roads which are used for geometric positioning of roads 
            for geoRoad in geoConnectionRoads:
                geoRoad.clearLanes()

            # TODO create the junction
            self.addInternalConnectionsToJunction(junction, internalConnections)

        # U-Turns
        if uTurnLanes == 1:
            uTurnConnections = self.connectionBuilder.createUTurnConnectionRoads(nextRoadId, outsideRoads, cp1)
            nextRoadId += 1
            roads += uTurnConnections
            odr.updateRoads(roads)
            self.addInternalConnectionsToJunction(junction, internalConnections)


        logging.debug(f"{self.name}: roads after internal connections {len(roads)}")

        odr.resetAndReadjust(byPredecessor=True)

        if getAsOdr:
            return odr

        intersection = Intersection(id, outsideRoads, incidentContactPoints, geoConnectionRoads=geoConnectionRoads, odr=odr)
        return intersection
Пример #17
0
    def ThreeWayJunctionWithAngle(
            self,
            odrId,
            angleBetweenRoads=np.pi / 4,
            maxLanePerSide=2,
            minLanePerSide=0,
            internalConnections=True,
            cp1=pyodrx.ContactPoint.end,
            randomState=None,
            internalLinkStrategy=LaneConfigurationStrategies.SPLIT_ANY,
            uTurnLanes=1):

        if angleBetweenRoads < np.pi / 9 or angleBetweenRoads > np.pi / 2:
            raise Exception("Come up with a better angle")

        outsideRoad = []
        roads = []

        if cp1 == pyodrx.ContactPoint.end:
            firstRoad = self.createRandomStraightRoad(
                0,
                maxLanePerSide=maxLanePerSide,
                minLanePerSide=minLanePerSide,
                skipEndpoint=pyodrx.ContactPoint.start)  # first road
        else:
            firstRoad = self.createRandomStraightRoad(
                0,
                maxLanePerSide=maxLanePerSide,
                minLanePerSide=minLanePerSide,
                skipEndpoint=pyodrx.ContactPoint.end)  # first road

        roads.append(firstRoad)
        outsideRoad.append(firstRoad)

        # second road

        secondRoad = self.createRandomStraightRoad(
            2,
            maxLanePerSide=maxLanePerSide,
            minLanePerSide=minLanePerSide,
            skipEndpoint=pyodrx.ContactPoint.end)
        outsideRoad.append(secondRoad)
        prevLanes, nextLanes = self.laneBuilder.getClockwiseAdjacentLanes(
            firstRoad=roads[0],
            firstCp=cp1,
            secondRoad=secondRoad,
            secondCP=pyodrx.ContactPoint.start)

        maxLaneWidth = self.getMaxLaneWidth(prevLanes, nextLanes)
        secondConnectionRoad = self.createConnectionRoadWithAngle(
            roadId=1,
            angleBetweenRoads=angleBetweenRoads,
            maxLaneWidth=maxLaneWidth)
        # firstRoad.addExtendedSuccessor(secondConnectionRoad, 0, pyodrx.ContactPoint.start)
        # secondConnectionRoad.addExtendedPredecessor(firstRoad, 0, cp1)
        RoadLinker.createExtendedPredSuc(predRoad=firstRoad,
                                         predCp=cp1,
                                         sucRoad=secondConnectionRoad,
                                         sucCP=pyodrx.ContactPoint.start)
        RoadLinker.createExtendedPredSuc(predRoad=secondConnectionRoad,
                                         predCp=pyodrx.ContactPoint.end,
                                         sucRoad=secondRoad,
                                         sucCP=pyodrx.ContactPoint.start)
        roads.append(secondConnectionRoad)
        roads.append(secondRoad)
        odrName = 'ThreeWay' + 'givenAngle' + str(odrId)
        odr = extensions.createOdrByPredecessor(odrName, roads, [])

        # third road
        thirdRoad = self.createRandomStraightRoad(
            4,
            maxLanePerSide=maxLanePerSide,
            minLanePerSide=minLanePerSide,
            skipEndpoint=pyodrx.ContactPoint.end)
        outsideRoad.append(thirdRoad)
        roadLen = roads[1].length()
        thirdConnectionRoad = self.straightRoadBuilder.create(roadId=3,
                                                              length=roadLen)
        RoadLinker.createExtendedPredSuc(predRoad=firstRoad,
                                         predCp=cp1,
                                         sucRoad=thirdConnectionRoad,
                                         sucCP=pyodrx.ContactPoint.start)
        RoadLinker.createExtendedPredSuc(predRoad=thirdConnectionRoad,
                                         predCp=pyodrx.ContactPoint.end,
                                         sucRoad=thirdRoad,
                                         sucCP=pyodrx.ContactPoint.start)
        roads.append(thirdConnectionRoad)
        roads.append(thirdRoad)
        odr.add_road(thirdConnectionRoad)
        odr.add_road(thirdRoad)
        odr.resetAndReadjust(byPredecessor=True)

        # last connection
        connectioRoadSecondAndThird = self.createConnectionFor2Roads(
            nextRoadId=5,
            road1=secondRoad,
            road2=thirdRoad,
            junction=None,
            cp1=pyodrx.ContactPoint.start,
            cp2=pyodrx.ContactPoint.start)
        roads.append(connectioRoadSecondAndThird)
        odr.add_road(connectioRoadSecondAndThird)
        self.fixNumOutgoingLanes(outsideRoad, cp1)

        if internalConnections:
            internalConnections = self.connectionBuilder.createSingleLaneConnectionRoads(
                6, outsideRoad, cp1, internalLinkStrategy)
            roads += internalConnections
            odr.updateRoads(roads)

        odr.resetAndReadjust(byPredecessor=True)
        return odr
    def drawLikeAPainter2L(self, odrId, maxNumberOfRoadsPerJunction, save=True, internalConnections=True, cp1=pyodrx.ContactPoint.end):
        if maxNumberOfRoadsPerJunction < 3:
            raise Exception("drawLikeAPainter is not for the weak. Please add more than 3 roads")

        
        maxLaneWidth = self.laneWidth 

        roads = []
        roads.append(self.straightRoadBuilder.create(0, length=self.straightRoadLen * 4)) # first road

        availableAngle = 1.8 * np.pi # 360 degrees
        maxAnglePerConnection = availableAngle / (maxNumberOfRoadsPerJunction - 1)
        action = self.actionAfterDrawingOne(roads, availableAngle, maxNumberOfRoadsPerJunction)
        nextRoadId = 1
        while (action != "end"):

            logging.debug(f"{self.name}: availableAngle {math.degrees(availableAngle)}, number of roads: {len(roads) / 2}")
            previousRoadId = nextRoadId - 1
            newConnectionId = nextRoadId
            nextRoadId += 1
            newRoadId = nextRoadId
            nextRoadId += 1

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

            # 2. create a new connection road
            newConnection, availableAngle = self.createGeoConnectionRoad(action, newConnectionId, availableAngle, maxAnglePerConnection, maxLaneWidth=maxLaneWidth)
            
            # 5 add new roads and increase road id
            roads.append(newConnection)
            roads.append(newRoad)

            # roads[previousRoadId].add_successor(pyodrx.ElementType.junction, newConnection.id)
            roads[previousRoadId].addExtendedSuccessor(newConnection, 0, pyodrx.ContactPoint.start)

            if newConnection.id == 1:
                # TODO this is a hack. It will not eventually work because outgoing roads' ends will come to join other junctions.
                newConnection.addExtendedPredecessor(roads[previousRoadId], 0 , cp1)
            else:
                newConnection.addExtendedPredecessor(roads[previousRoadId], 0 , pyodrx.ContactPoint.start)
            
            RoadLinker.createExtendedPredSuc(predRoad=newConnection, predCp=pyodrx.ContactPoint.end, sucRoad=newRoad, sucCP=pyodrx.ContactPoint.start)


            # 6 get next action
            action = self.actionAfterDrawingOne(roads, availableAngle, maxNumberOfRoadsPerJunction)
            pass
        
        # 3. create connections and junction

        junction = self.createJunctionForASeriesOfRoads(roads, odrId)

        odrName = 'Draw_Rmax' + str(maxNumberOfRoadsPerJunction) + '_L2_' + str(odrId)
        odr = extensions.createOdrByPredecessor(odrName, roads, [junction])

        # The last connection and resetting odr

        lastConnection = self.createLastConnectionForLastAndFirstRoad(nextRoadId, roads, junction, cp1=cp1)
        roads.append(lastConnection)
        odr.add_road(lastConnection)

        logging.debug(f"{self.name}: roads before internal connections {len(roads)}")

        if internalConnections:
            self.createInternalConnectionsForMissingSequentialRoads(roads, junction, cp1=cp1)
            odr.updateRoads(roads)

        logging.debug(f"{self.name}: roads after internal connections {len(roads)}")

        odr.resetAndReadjust(byPredecessor=True)
        
        return odr
    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)