Skip to content

Commit c9ae5ed

Browse files
committed
improvement on adapter and more features in controlling number of lanes
1 parent 795d88c commit c9ae5ed

File tree

7 files changed

+70046
-232
lines changed

7 files changed

+70046
-232
lines changed

junctions/Intersection.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ def getOrderedConnectionRoadsBetween(self, fromRoad: ExtendedRoad, toRoad: Exten
121121
if connectionRoad.isExtendedSuccessorOf(fromRoad) and connectionRoad.isExtendedPredecessorOf(toRoad):
122122
connectionRoads.append(connectionRoad)
123123

124-
print(connectionRoads)
124+
# print(connectionRoads)
125125
return connectionRoads
126126

127127

junctions/JunctionBuilderFromPointsAndHeading.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ def createStraightRoadsFromRoadDefinition(self, nextRoadId, roadDefinition, stra
341341
n_lanes_right=road['rightLane'],
342342
length=straighRoadLength,
343343
medianType=road['medianType'],
344-
medianWidth=3,
344+
medianWidth=2,
345345
skipEndpoint=road['skipEndpoint'])
346346
else:
347347
straightRoad = self.straightRoadBuilder.create(roadId=roadID,

log.txt

Lines changed: 94 additions & 208 deletions
Large diffs are not rendered by default.

roadgen/controlLine/ControlLineBasedGenerator.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ def __init__(self, mapSize, debug=False,
2525
randomizeLanes=True,
2626
randomizeDistance = True, randomizeHeading=False,
2727
country=CountryCodes.US, seed=101,
28-
nLaneDistributionOnASide=[0.15, 0.6, 0.2, 0.05]
28+
nLaneDistributionOnASide=[0.15, 0.6, 0.2, 0.05],
29+
nLaneDistributionOnControlLines=[0.05, 0.45, 0.4, 0.1],
30+
controlineLaneConfigurations = None
2931
) -> None:
3032
self.name = "ControlLineBasedGenerator"
3133
self.mapSize = mapSize
@@ -51,9 +53,13 @@ def __init__(self, mapSize, debug=False,
5153
laneWidth=3)
5254
self.laneConfigurations = None
5355

54-
self.nLaneDistributionOnASide = nLaneDistributionOnASide # 0, 1, 2, 3
5556

5657
self.placedIntersections = []
58+
59+
# lane distributions.
60+
self.nLaneDistributionOnASide = nLaneDistributionOnASide # 0, 1, 2, 3
61+
self.controlineLaneConfigurations = controlineLaneConfigurations
62+
self.nLaneDistributionOnControlLines = nLaneDistributionOnControlLines
5763

5864
np.random.seed(seed)
5965
pass
@@ -367,6 +373,15 @@ def createLaneConfigurationsForConnections(self):
367373
point1_n_left = np.random.choice([0, 1, 2, 3], p = self.nLaneDistributionOnASide)
368374
point1_n_right = np.random.choice([0, 1, 2, 3], p = self.nLaneDistributionOnASide)
369375

376+
if line1 == line2:
377+
# on the same control line
378+
if (self.controlineLaneConfigurations is not None) and (line1 in self.controlineLaneConfigurations):
379+
point1_n_left, point1_n_right = self.controlineLaneConfigurations[line1]
380+
else:
381+
point1_n_left = np.random.choice([0, 1, 2, 3], p = self.nLaneDistributionOnControlLines)
382+
point1_n_right = np.random.choice([0, 1, 2, 3], p = self.nLaneDistributionOnControlLines)
383+
384+
370385
if point1_n_left == 0 and point1_n_right == 0:
371386
point1_n_left = 1
372387

roadgen/controlLine/ControlPointIntersectionAdapter.py

Lines changed: 100 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ def createIntersection(id, builder, point: ControlPoint, firstIncidentId,
2626
roadDefs = []
2727

2828
nIncidentPoints = len(point.adjacentPointsCWOrder)
29-
if nIncidentPoints > 3:
30-
print(f"4 arms")
29+
# if nIncidentPoints > 3:
30+
# print(f"4 arms")
3131

3232
if nIncidentPoints == 0:
3333
raise Exception(f"ControlPointIntersectionAdapter: createIntersection adjacentPointsCWOrder is empty")
@@ -37,7 +37,7 @@ def createIntersection(id, builder, point: ControlPoint, firstIncidentId,
3737

3838
# randomDistance = distance
3939
randomDistance = ControlPointIntersectionAdapter.getMinDistance(point, adjPoint, laneConfigurations=laneConfigurations)
40-
print(f"distance for point {adjPoint.position} is {randomDistance}")
40+
# print(f"distance for point {adjPoint.position} is {randomDistance}")
4141

4242
if randomDistance > maxDistance:
4343
raise Exception(f"ControlPointIntersectionAdapter: angle too tight to generate intersection with specified lanes")
@@ -54,7 +54,7 @@ def createIntersection(id, builder, point: ControlPoint, firstIncidentId,
5454
incidentPoint = line.createNextControlPoint(line.len - randomDistance)
5555

5656
actualDistance = math.sqrt((point.position[0] - incidentPoint.position[0]) ** 2 + (point.position[1] - incidentPoint.position[1]) ** 2 )
57-
print(f"Incident point {incidentPoint.position}, heading {round(math.degrees(heading), 2)} with actual distance {actualDistance}")
57+
# print(f"Incident point {incidentPoint.position}, heading {round(math.degrees(heading), 2)} with actual distance {actualDistance}")
5858
if debug:
5959
logging.info(f"Incident point {incidentPoint.position}, heading {round(math.degrees(heading), 2)}")
6060

@@ -97,15 +97,83 @@ def createIntersection(id, builder, point: ControlPoint, firstIncidentId,
9797

9898

9999

100+
# @staticmethod
101+
# def getMinDistance(point: ControlPoint, adjPoint, laneConfigurations = None):
102+
103+
# """
104+
# Assumes start contact points are incident points
105+
# """
106+
107+
# laneWidth = 3
108+
# minDistance = 10
109+
# headings = list(point.adjacentPointsCWOrder.keys())
110+
# adjPoints = list(point.adjacentPointsCWOrder.values())
111+
112+
113+
# # get prev and next points
114+
# curIndex = adjPoints.index(adjPoint)
115+
# prevIndex = curIndex - 1
116+
# if curIndex == len(adjPoints) - 1:
117+
# nextIndex = 0
118+
# else:
119+
# nextIndex = curIndex + 1
120+
121+
# prevPoint = adjPoints[prevIndex]
122+
# nextPoint = adjPoints[nextIndex]
123+
124+
# n_left = 1
125+
# n_right = 1
126+
127+
# if laneConfigurations is not None:
128+
# (n_left, n_right) = laneConfigurations[point][adjPoint]
129+
130+
# # min distance based on the difference in headings
131+
# diffWithPrev = abs(headings[curIndex] - headings[prevIndex])
132+
# n_left_prev = 1
133+
# n_right_prev = 1
134+
135+
# if laneConfigurations is not None:
136+
# (n_left_prev, n_right_prev) = laneConfigurations[point][prevPoint]
137+
# maxNLanes = max(n_left, n_right_prev)
138+
# if diffWithPrev <= np.pi / 4: # less than 90:
139+
# minWithPrev = minDistance + maxNLanes * 15 / diffWithPrev
140+
# elif diffWithPrev <= np.pi / 2: # less than 90:
141+
# minWithPrev = minDistance + maxNLanes * 5 / diffWithPrev
142+
# else:
143+
# minWithPrev = minDistance + maxNLanes * 2
144+
145+
# if minDistance < minWithPrev:
146+
# minDistance = minWithPrev
147+
148+
# diffWithNext = abs(headings[curIndex] - headings[nextIndex])
149+
# n_left_next = 1
150+
# n_right_next = 1
151+
152+
# if laneConfigurations is not None:
153+
# (n_left_next, n_right_next) = laneConfigurations[point][nextPoint]
154+
# maxNLanes = max(n_right, n_left_next)
155+
# if diffWithNext <= np.pi / 4: # less than 45:
156+
# minWithNext = minDistance + maxNLanes * 15 / diffWithNext
157+
# elif diffWithNext <= np.pi / 2: # less than 45:
158+
# minWithNext = minDistance + maxNLanes * 5 / diffWithNext
159+
# else:
160+
# minWithNext = minDistance + maxNLanes * 2
161+
162+
# if minDistance < minWithNext:
163+
# minDistance = minWithNext
164+
165+
166+
# return minDistance
167+
100168
@staticmethod
101169
def getMinDistance(point: ControlPoint, adjPoint, laneConfigurations = None):
102170

103171
"""
104172
Assumes start contact points are incident points
105173
"""
106174

107-
108-
minDistance = 10
175+
laneWidth = 3
176+
minDistance = 1
109177
headings = list(point.adjacentPointsCWOrder.keys())
110178
adjPoints = list(point.adjacentPointsCWOrder.values())
111179

@@ -121,6 +189,9 @@ def getMinDistance(point: ControlPoint, adjPoint, laneConfigurations = None):
121189
prevPoint = adjPoints[prevIndex]
122190
nextPoint = adjPoints[nextIndex]
123191

192+
# print(f"prevPoint", prevPoint)
193+
# print(f"nextPoint", nextPoint)
194+
124195
n_left = 1
125196
n_right = 1
126197

@@ -134,13 +205,18 @@ def getMinDistance(point: ControlPoint, adjPoint, laneConfigurations = None):
134205

135206
if laneConfigurations is not None:
136207
(n_left_prev, n_right_prev) = laneConfigurations[point][prevPoint]
137-
maxNLanes = max(n_left, n_right_prev)
138-
if diffWithPrev <= np.pi / 4: # less than 90:
139-
minWithPrev = 10 + maxNLanes * 15 / diffWithPrev
140-
elif diffWithPrev <= np.pi / 2: # less than 90:
141-
minWithPrev = 10 + maxNLanes * 5 / diffWithPrev
208+
209+
totalLaneWidth = (n_left + n_right_prev) * laneWidth
210+
211+
if diffWithPrev <= np.pi / 2: # less than 90:
212+
minWithPrev = abs(totalLaneWidth / math.sin(diffWithPrev))
142213
else:
143-
minWithPrev = 10 + maxNLanes * 2
214+
minWithPrev = totalLaneWidth
215+
216+
# print(f"minWithPrev", minWithPrev)
217+
# print(f"totalLaneWidth", totalLaneWidth)
218+
# print(f"diffWithPrev", diffWithPrev)
219+
144220

145221
if minDistance < minWithPrev:
146222
minDistance = minWithPrev
@@ -151,18 +227,23 @@ def getMinDistance(point: ControlPoint, adjPoint, laneConfigurations = None):
151227

152228
if laneConfigurations is not None:
153229
(n_left_next, n_right_next) = laneConfigurations[point][nextPoint]
154-
maxNLanes = max(n_right, n_left_next)
155-
if diffWithNext <= np.pi / 4: # less than 45:
156-
minWithNext = 10 + maxNLanes * 15 / diffWithNext
157-
elif diffWithNext <= np.pi / 2: # less than 45:
158-
minWithNext = 10 + maxNLanes * 5 / diffWithNext
159-
else:
160-
minWithNext = 10 + maxNLanes * 2
161230

231+
totalLaneWidth = (n_right + n_left_next) * laneWidth
232+
233+
if diffWithNext <= np.pi / 2: # less than 90:
234+
minWithNext = abs(totalLaneWidth / math.sin(diffWithNext))
235+
else:
236+
minWithNext = totalLaneWidth
237+
238+
# print(f"minWithNext", minWithNext)
239+
# print(f"totalLaneWidth", totalLaneWidth)
240+
# print(f"diffWithNext", diffWithNext)
241+
162242
if minDistance < minWithNext:
163243
minDistance = minWithNext
164244

165245

246+
166247
return minDistance
167248

168249

tests/test_roadgen/controlLine/test_ControlLineBasedGenerator.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,16 @@ def test_generateWithManualControlLines(self):
3131
extensions.view_road(odr, os.path.join('..',self.configuration.get("esminipath")))
3232

3333

34+
def test_generateWithManualControlLines2(self):
35+
generator = ControlLineBasedGenerator((400, 400), debug=True, seed=10, randomizeDistance=False, nLaneDistributionOnASide=[0.2, 0.7, 0.1, 0], nLaneDistributionOnControlLines=[0, 0.2, 0.7, 0.1])
36+
odr = generator.generateWithManualControlines("test_generateWithHorizontalControlines2")
37+
# generator.grid.plot()
38+
# extensions.printRoadPositions(odr)
39+
xmlPath = f"output/test_generateWithManualControlLines2.xodr"
40+
odr.write_xml(xmlPath)
41+
extensions.view_road(odr, os.path.join('..',self.configuration.get("esminipath")))
42+
43+
3444
def test_generateWithHorizontalControlines(self):
3545

3646
generator = ControlLineBasedGenerator((400, 400), debug=True, seed=2, randomizeDistance=False)
@@ -52,10 +62,19 @@ def test_generateWithHorizontalControlinesCurvy(self):
5262
extensions.view_road(odr, os.path.join('..',self.configuration.get("esminipath")))
5363

5464
def test_generateWithHorizontalControlinesBig(self):
55-
generator = ControlLineBasedGenerator((2000, 2000), debug=True, seed=1)
65+
generator = ControlLineBasedGenerator((2000, 2000), debug=True, seed=1, randomizeDistance=False, nLaneDistributionOnASide=[0.25, 0.7, 0.05, 0])
5666
odr = generator.generateWithHorizontalControlines("test_generateWithHorizontalControlinesBig", 10)
5767
# generator.grid.plot()
5868
# extensions.printRoadPositions(odr)
5969
xmlPath = f"output/test_generateWithHorizontalControlinesBig.xodr"
6070
odr.write_xml(xmlPath)
71+
# extensions.view_road(odr, os.path.join('..',self.configuration.get("esminipath")))
72+
73+
def test_generateWithHorizontalControlinesBig2Lane(self):
74+
generator = ControlLineBasedGenerator((2000, 2000), debug=True, seed=1, randomizeLanes=False, randomizeDistance=False)
75+
odr = generator.generateWithHorizontalControlines("test_generateWithHorizontalControlinesBig2Lane", 10)
76+
# generator.grid.plot()
77+
# extensions.printRoadPositions(odr)
78+
xmlPath = f"output/test_generateWithHorizontalControlinesBig2Lane.xodr"
79+
odr.write_xml(xmlPath)
6180
# extensions.view_road(odr, os.path.join('..',self.configuration.get("esminipath")))

0 commit comments

Comments
 (0)