Beispiel #1
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")))
Beispiel #2
0
    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 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))
Beispiel #4
0
    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 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 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
    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 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)
Beispiel #10
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
Beispiel #11
0
    def createSingleLaneConnectionRoad(self, newRoadId, incomingRoad,
                                       outgoingRoad, incomingLaneId,
                                       outgoingLaneId, incomingCp, outgoingCp):
        """Warining: uses default lane width. Works only after roads has been adjusted.

        Args:
            incomingRoad ([type]): [description]
            outgoingRoad ([type]): [description]
            incomingLaneId ([type]): [description]
            outgoingLaneId ([type]): [description]
            incomingCp ([type]): [description]
            outgoingCp ([type]): [description]
        """
        laneSides = None
        if self.countryCode == CountryCodes.US:
            laneSides = LaneSides.RIGHT
        if self.countryCode == CountryCodes.UK:
            laneSides = LaneSides.LEFT

        incomingBoundaryId = incomingLaneId - 1
        if incomingLaneId < 0:
            incomingBoundaryId = incomingLaneId + 1

        outgoingBoundaryId = outgoingLaneId - 1
        if outgoingLaneId < 0:
            outgoingBoundaryId = outgoingLaneId + 1

        # TODO, get lane widths from road and create an equation.
        width = self.config.get("default_lane_width")

        x1, y1, h1 = incomingRoad.getLanePosition(incomingBoundaryId,
                                                  incomingCp)
        x2, y2, h2 = outgoingRoad.getLanePosition(outgoingBoundaryId,
                                                  outgoingCp)

        # special case for U turns from -1 to 1 or 1 to -1
        if x1 == x2 and y1 == y2:
            #     x1 = 0.9 * x1
            #     y1 = 0.9 * y1
            width -= self.uTurnFirstLaneShift

        logging.debug(f"{self.name}: createSingleLaneConnectionRoad: start: ",
                      x1, y1, h1)
        logging.debug(f"{self.name}: createSingleLaneConnectionRoad: end: ",
                      x2, y2, h2)

        xCoeffs, yCoeffs = Geometry.getCoeffsForParamPoly(
            x1,
            y1,
            h1,
            x2,
            y2,
            h2,
            incomingCp,
            outgoingCp,
            vShiftForSamePoint=self.uTurnFirstLaneShift)

        # scipy coefficient and open drive coefficents have opposite order.
        newConnection = self.curveBuilder.createParamPoly3(newRoadId,
                                                           isJunction=True,
                                                           au=xCoeffs[3],
                                                           bu=xCoeffs[2],
                                                           cu=xCoeffs[1],
                                                           du=xCoeffs[0],
                                                           av=yCoeffs[3],
                                                           bv=yCoeffs[2],
                                                           cv=yCoeffs[1],
                                                           dv=yCoeffs[0],
                                                           n_lanes=1,
                                                           lane_offset=width,
                                                           laneSides=laneSides)

        newConnection.predecessorOffset = incomingBoundaryId

        newConnection.isSingleLaneConnection = True

        RoadLinker.createExtendedPredSuc(predRoad=incomingRoad,
                                         predCp=incomingCp,
                                         sucRoad=newConnection,
                                         sucCP=pyodrx.ContactPoint.start)
        RoadLinker.createExtendedPredSuc(predRoad=newConnection,
                                         predCp=pyodrx.ContactPoint.end,
                                         sucRoad=outgoingRoad,
                                         sucCP=outgoingCp)

        return newConnection
Beispiel #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