Exemple #1
0
	def __init__(self, proj, data):
		super().__init__(proj, data)
		self.id = data['id']
		self.direction = data['direction']
		self.origin_lane = data['origin_lane']['lane_id']
		medianPoints = localize(data['median'], proj)
		self.median = PolylineRegion(medianPoints)
		self.medianPoints = np.array(medianPoints)
		self.region.orientation = VectorField(f'Road{self.id}Direction', self.directionAt)
Exemple #2
0
    def __attrs_post_init__(self):
        proxy = weakref.proxy(self)
        for uid, elem in self.elements.items():
            assert elem.uid == uid
            elem.network = proxy

        self.allRoads = self.roads + self.connectingRoads
        self.roadSections = tuple(sec for road in self.roads
                                  for sec in road.sections)
        self.laneSections = tuple(sec for lane in self.lanes
                                  for sec in lane.sections)

        if self.roadRegion is None:
            self.roadRegion = PolygonalRegion.unionAll(self.roads)
        if self.laneRegion is None:
            self.laneRegion = PolygonalRegion.unionAll(self.lanes)
        if self.intersectionRegion is None:
            self.intersectionRegion = PolygonalRegion.unionAll(
                self.intersections)
        if self.crossingRegion is None:
            self.crossingRegion = PolygonalRegion.unionAll(self.crossings)
        if self.sidewalkRegion is None:
            self.sidewalkRegion = PolygonalRegion.unionAll(self.sidewalks)
        if self.shoulderRegion is None:
            self.shoulderRegion = PolygonalRegion.unionAll(self.shoulders)

        if self.drivableRegion is None:
            self.drivableRegion = self.laneRegion.union(
                self.intersectionRegion)
        if self.walkableRegion is None:
            self.walkableRegion = self.sidewalkRegion.union(
                self.crossingRegion)

        if self.curbRegion is None:
            edges = []
            for road in self.roads:  # only include curbs of ordinary roads
                if road.forwardLanes:
                    edges.append(road.forwardLanes.curb)
                if road.backwardLanes:
                    edges.append(road.backwardLanes.curb)
            self.curbRegion = PolylineRegion.unionAll(edges)

        if self.roadDirection is None:
            # TODO replace with a PolygonalVectorField for better pruning
            self.roadDirection = VectorField('roadDirection',
                                             self._defaultRoadDirection)
Exemple #3
0
    def computeGeometry(self, crossroads, snapTolerance=0.05):
        ## Approximate bounding polygon and sidewalks
        # TODO improve this!!!
        lefts, rights = [], []
        leftSidewalk, rightSidewalk = [], []
        headings = []
        sidewalkWidths = itertools.chain(
            self.sidewalkWidths, itertools.repeat(self.sidewalkWidths[-1]))
        segments = zip(self.waypoints, sidewalkWidths)
        for i, segment in enumerate(segments):
            point, sidewalkWidth = segment
            if i + 1 < len(self.waypoints):
                nextPt = self.waypoints[i + 1]
                dx, dy = nextPt - point
                heading = normalizeAngle(math.atan2(dy, dx) - (math.pi / 2))
                headings.append(heading)
                perp = np.array([-dy, dx])
                perp /= np.linalg.norm(perp)
            else:
                pass  # use perp from last segment
            toEdge = perp * (self.width / 2)
            left = point + toEdge
            right = point - toEdge
            lefts.append(left)
            rights.append(right)
            toEdge = perp * sidewalkWidth
            leftSidewalk.append(left + toEdge)
            rightSidewalk.append(right - toEdge)

        # Snap to adjacent crossroads if possible
        if snapTolerance > 0:
            sc = self.startCrossroad
            if sc is not None:
                if sc not in crossroads:
                    raise RuntimeError(
                        f'Road {self.osmID} begins at invalid crossroad {sc}')
                crossroad = crossroads[sc]
                if crossroad.region is not None:
                    pt = shapely.geometry.Point(lefts[0])
                    pt = shapely.ops.snap(pt, crossroad.region.polygons,
                                          snapTolerance)
                    lefts[0] = np.array([pt.x, pt.y])
                    pt = shapely.geometry.Point(rights[0])
                    pt = shapely.ops.snap(pt, crossroad.region.polygons,
                                          snapTolerance)
                    rights[0] = np.array([pt.x, pt.y])
                    perp = lefts[0] - rights[0]
                    toEdge = perp * (self.sidewalkWidths[0] /
                                     np.linalg.norm(perp))
                    leftSidewalk[0] = lefts[0] + toEdge
                    rightSidewalk[0] = rights[0] - toEdge
            ec = self.endCrossroad
            if ec is not None:
                if ec not in crossroads:
                    raise RuntimeError(
                        f'Road {self.osmID} ends at invalid crossroad {ec}')
                crossroad = crossroads[ec]
                if crossroad.region is not None:
                    pt = shapely.geometry.Point(lefts[-1])
                    pt = shapely.ops.snap(pt, crossroad.region.polygons,
                                          snapTolerance)
                    lefts[-1] = np.array([pt.x, pt.y])
                    pt = shapely.geometry.Point(rights[-1])
                    pt = shapely.ops.snap(pt, crossroad.region.polygons,
                                          snapTolerance)
                    rights[-1] = np.array([pt.x, pt.y])
                    perp = lefts[-1] - rights[-1]
                    toEdge = perp * (self.sidewalkWidths[-1] /
                                     np.linalg.norm(perp))
                    leftSidewalk[-1] = lefts[-1] + toEdge
                    rightSidewalk[-1] = rights[-1] - toEdge

        roadPoints = lefts + list(reversed(rights))
        self.leftCurb = PolylineRegion(reversed(lefts))
        self.rightCurb = PolylineRegion(rights)

        self.leftSidewalk = self.rightSidewalk = None
        if self.hasLeftSidewalk:
            points = lefts + list(reversed(leftSidewalk))
            polygon = polygonWithPoints(points)
            assert polygon.is_valid, self.waypoints
            self.leftSidewalk = PolygonalRegion(polygon=polygon)
        if self.hasRightSidewalk:
            points = rights + list(reversed(rightSidewalk))
            polygon = polygonWithPoints(points)
            assert polygon.is_valid, self.waypoints
            self.rightSidewalk = PolygonalRegion(polygon=polygon)

        ## Compute lanes and traffic directions
        cells = []
        la, ra = lefts[0], rights[0]
        gapA = (ra - la) / self.lanes
        markerA = ra
        laneMarkers = [[] for lane in range(self.lanes)]
        for lb, rb, heading in zip(lefts[1:], rights[1:], headings):
            # Compute lanes for this segment of road
            gapB = (rb - lb) / self.lanes
            markerB = rb
            for lane, markers in enumerate(laneMarkers):
                forward = lane < self.forwardLanes
                if self.driveOnLeft:
                    forward = not forward
                nextMarkerA = markerA - gapA
                nextMarkerB = markerB - gapB
                markers.append(nextMarkerA)
                cell = shapely.geometry.Polygon(
                    (markerA, markerB, nextMarkerB, nextMarkerA))
                heading = heading if forward else normalizeAngle(heading +
                                                                 math.pi)
                cells.append((cell, heading))
                markerA = nextMarkerA
                markerB = nextMarkerB
            gapA = gapB
            markerA = rb
        self.lanes = []
        markerB = rb
        rightEdge = rights
        for lane, markers in enumerate(laneMarkers):
            markerB = markerB - gapB
            markers.append(markerB)
            self.lanes.append(
                PolygonalRegion(rightEdge + list(reversed(markers))))
            rightEdge = markers
        self.laneMarkers = laneMarkers[:-1]
        self.cells = cells
        self.direction = PolygonalVectorField(f'Road{self.osmID}Direction',
                                              cells)

        roadPolygon = polygonWithPoints(roadPoints)
        self.region = PolygonalRegion(polygon=roadPolygon,
                                      orientation=self.direction)
Exemple #4
0
	def __init__(self, world):
		# Find roads, crossroads, and pedestrian crossings
		nodeClasses = {
			'Road': Road,
			'Crossroad': Crossroad,
			'PedestrianCrossing': PedestrianCrossing
		}
		self.roads, self.crossroads, self.crossings = world_parser.findNodeTypesIn(
			('Road', 'Crossroad', 'PedestrianCrossing'), world, nodeClasses)

		# Compute road geometry
		crossroadsByID = { crossroad.osmID: crossroad for crossroad in self.crossroads }
		for road in self.roads:
			road.computeGeometry(crossroadsByID)

		# Construct regions
		allCells = []
		drivableAreas = []
		for road in self.roads:
			assert road.region.polygons.is_valid, (road.waypoints, road.region.points)
			allCells.extend(road.cells)
		for crossroad in self.crossroads:
			if crossroad.region is not None:
				for poly in crossroad.region.polygons:
					allCells.append((poly, None))
		if not allCells:
			raise RuntimeError('Webots world has no drivable geometry!')
		self.roadDirection = PolygonalVectorField(
		    'roadDirection', allCells,
		    headingFunction=lambda pos: 0, defaultHeading=0		# TODO fix
		)
		if not self.roads:
			roadPoly = None
			self.roadsRegion = nowhere
			self.curbsRegion = nowhere
		else:
			roadPoly = polygonUnion(road.region.polygons for road in self.roads)
			self.roadsRegion = PolygonalRegion(polygon=roadPoly,
			                                   orientation=self.roadDirection)
			drivableAreas.append(roadPoly)
			curbs = [road.leftCurb.lineString for road in self.roads]
			curbs.extend(road.rightCurb.lineString for road in self.roads)
			curbLine = shapely.ops.unary_union(curbs)
			self.curbsRegion = PolylineRegion(polyline=curbLine)
		if not self.crossroads:
			crossroadPoly = None
			self.crossroadsRegion = nowhere
		else:
			crossroadPoly = polygonUnion(cr.region.polygons
			                             for cr in self.crossroads
			                             if cr.region is not None)
			self.crossroadsRegion = PolygonalRegion(polygon=crossroadPoly,
			                                        orientation=self.roadDirection)
			drivableAreas.append(crossroadPoly)

		sidewalks = []
		walkableAreas = []
		for road in self.roads:
			if road.hasLeftSidewalk:
				sidewalks.append(road.leftSidewalk.polygons)
			if road.hasRightSidewalk:
				sidewalks.append(road.rightSidewalk.polygons)
		if not sidewalks:
			sidewalksPoly = None
			self.sidewalksRegion = nowhere
		else:
			sidewalksPoly = polygonUnion(sidewalks)
			self.sidewalksRegion = regionWithPolygons(sidewalksPoly)
			walkableAreas.append(sidewalksPoly)

		if not self.crossings:
			crossingsPoly = None
			self.crossingsRegion = nowhere
		else:
			crossingsPoly = polygonUnion(crossing.region.polygons
			                             for crossing in self.crossings)
			self.crossingsRegion = regionWithPolygons(crossingsPoly)
			walkableAreas.append(crossingsPoly)

		if not walkableAreas:
			self.walkableRegion = nowhere
		else:
			walkablePoly = polygonUnion(walkableAreas)
			self.walkableRegion = regionWithPolygons(walkablePoly)
		drivablePoly = polygonUnion(drivableAreas)
		self.drivableRegion = PolygonalRegion(polygon=drivablePoly,
		                                      orientation=self.roadDirection)
		workspacePoly = polygonUnion(drivableAreas + walkableAreas)
		self.workspaceRegion = PolygonalRegion(polygon=workspacePoly)

		# Identify various roads and lanes of interest
		slowCurbs = []
		for road in self.roads:
			if road.forwardLanes > 1:
				slowCurbs.append(road.rightCurb)
			if road.backwardLanes > 1:
				slowCurbs.append(road.leftCurb)
		self.slowCurbs = slowCurbs

		super().__init__(self.workspaceRegion)