Skip to content

Commit

Permalink
fix #16036
Browse files Browse the repository at this point in the history
  • Loading branch information
namdre committed Feb 4, 2025
1 parent 8ee76f8 commit 1f48396
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 6 deletions.
31 changes: 29 additions & 2 deletions tools/net/netcheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@
# @date 2007-03-20

"""
This script does simple check for the network.
It tests whether the network is (weakly) connected.
This script performs checks for the network.
It needs one parameter, the SUMO net (.net.xml).
- if either option --source or --destination is given, it checks reachability
- if option --right-of-way is set, it checks for problems with right of way rules
- by default it tests whether the network is (weakly) connected.
"""
from __future__ import absolute_import
from __future__ import print_function
Expand All @@ -42,6 +45,9 @@ def parse_args():
help="List edges reachable from the source")
op.add_argument("-d", "--destination", category="input", type=op.edge, default=False,
help="List edges which can reach the destination")
op.add_argument("-w", "--right-of-way", action="store_true", default=False,
dest="checkRightOfWay",
help="Check for problems with right-of-way rules")
op.add_argument("-o", "--selection-output", category="output", type=op.file,
help="Write output to file(s) as a loadable selection")
op.add_argument("--ignore-connections", action="store_true", default=False,
Expand Down Expand Up @@ -118,6 +124,25 @@ def getReachable(net, source_id, options, useIncoming=False):
sys.exit(e)


def checkRightOfWay(net, options):
lanes = []
for edge in net.getEdges(False):
for lane in edge.getLanes():
if lane.isAccelerationLane():
for c in lane.getIncomingConnections():
if c.getFromLane().isNormal() and c.getState() != "M":
lanes.append(lane)

if options.selection_output:
with open(options.selection_output, 'w') as f:
for lane in lanes:
f.write("lane:%s\n" % lane.getID())
else:
if lanes:
print("Found %s acceleration lanes with invalid right-of-way on the incoming connection" % len(lanes))
print('\n'.join([l.getID() for l in lanes]))


if __name__ == "__main__":
options = parse_args()
net = sumolib.net.readNet(options.net,
Expand All @@ -127,6 +152,8 @@ def getReachable(net, source_id, options, useIncoming=False):
getReachable(net, options.source, options)
elif options.destination:
getReachable(net, options.destination, options, True)
elif options.checkRightOfWay:
checkRightOfWay(net, options)
else:
components = getWeaklyConnected(
net, options.vclass, options.ignore_connections)
Expand Down
7 changes: 4 additions & 3 deletions tools/sumolib/net/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,8 @@ def addEdge(self, id, fromID, toID, prio, function, name, edgeType=''):
self.hasWalkingArea = True
return self._id2edge[id]

def addLane(self, edge, speed, length, width, allow=None, disallow=None):
return lane.Lane(edge, speed, length, width, allow, disallow)
def addLane(self, edge, speed, length, width, allow=None, disallow=None, acceleration=False):
return lane.Lane(edge, speed, length, width, allow, disallow, acceleration)

def addRoundabout(self, nodes, edges=None):
r = roundabout.Roundabout(nodes, edges)
Expand Down Expand Up @@ -790,7 +790,8 @@ def startElement(self, name, attrs):
float(attrs['length']),
float(attrs.get('width', 3.2)),
attrs.get('allow'),
attrs.get('disallow'))
attrs.get('disallow'),
attrs.get('acceleration') == "1")
self._currentLane.setShape(convertShape(attrs.get('shape', '')))
elif name == 'neigh' and self._currentLane is not None:
self._currentLane.setNeigh(attrs['lane'])
Expand Down
29 changes: 28 additions & 1 deletion tools/sumolib/net/lane.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class Lane:

""" Lanes from a sumo network """

def __init__(self, edge, speed, length, width, allow, disallow):
def __init__(self, edge, speed, length, width, allow, disallow, acceleration):
self._edge = edge
self._speed = speed
self._length = length
Expand All @@ -124,6 +124,7 @@ def __init__(self, edge, speed, length, width, allow, disallow):
self._allowed = get_allowed(allow, disallow)
self._neigh = None
self._selected = False
self._acceleration = acceleration
edge.addLane(self)

def getSpeed(self):
Expand Down Expand Up @@ -256,6 +257,26 @@ def getIncoming(self, onlyDirect=False):
_lane.getOutgoing()[0].getViaLaneID() == ""]
return lanes


def getIncomingConnections(self, onlyDirect=False):
"""
Returns all incoming connections for this lane
If onlyDirect is True, then only connections from internal lanes are returned for a normal lane if they exist
"""
candidates = reduce(lambda x, y: x + y, [cons for e, cons in self._edge.getIncoming().items()], [])
cons = [c for c in candidates if self == c.getToLane()]
if onlyDirect:
hasInternal = False
for c in cons:
if c.getFromLane().getID()[0] == ":":
hasInternal = True
break
if hasInternal:
return [c for c in cons if c.getFromLane()[0] == ":" and
c.getFromLane().getOutgoing()[0].getViaLaneID() == ""]
return cons


def getConnection(self, toLane):
"""Returns the connection to the given target lane or None"""
for conn in self._outgoing:
Expand Down Expand Up @@ -289,3 +310,9 @@ def getParam(self, key, default=None):

def getParams(self):
return self._params

def isAccelerationLane(self):
return self._acceleration

def isNormal(self):
return self.getID()[0] != ":"

0 comments on commit 1f48396

Please sign in to comment.