Skip to content

Commit 5c6dfb4

Browse files
committed
enhance lane rendering performance with batched polygon shader
1 parent 8220599 commit 5c6dfb4

File tree

2 files changed

+320
-236
lines changed

2 files changed

+320
-236
lines changed

selfdrive/ui/onroad/model_renderer.py

Lines changed: 34 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from openpilot.common.params import Params
77
from openpilot.selfdrive.ui.ui_state import ui_state
88
from openpilot.system.ui.lib.application import DEFAULT_FPS, Widget
9-
from openpilot.system.ui.lib.shader_polygon import draw_polygon
9+
from openpilot.system.ui.lib.shader_polygon import draw_polygons_batch
1010
from openpilot.selfdrive.locationd.calibrationd import HEIGHT_INIT
1111

1212
CLIP_MARGIN = 500
@@ -54,6 +54,7 @@ def __init__(self):
5454
self._road_edge_stds = np.zeros(2, dtype=np.float32)
5555
self._lead_vehicles = [LeadVehicle(), LeadVehicle()]
5656
self._path_offset_z = HEIGHT_INIT[0]
57+
self._polygons = []
5758

5859
# Initialize ModelPoints objects
5960
self._path = ModelPoints()
@@ -71,13 +72,6 @@ def __init__(self):
7172
self._temp_points_3d = np.empty((MAX_POINTS * 2, 3), dtype=np.float32)
7273
self._temp_proj = np.empty((3, MAX_POINTS * 2), dtype=np.float32)
7374

74-
self._exp_gradient = {
75-
'start': (0.0, 1.0), # Bottom of path
76-
'end': (0.0, 0.0), # Top of path
77-
'colors': [],
78-
'stops': [],
79-
}
80-
8175
# Get longitudinal control setting from car parameters
8276
if car_params := Params().get("CarParams"):
8377
cp = messaging.log_from_bytes(car_params, car.CarParams)
@@ -131,8 +125,7 @@ def _render(self, rect: rl.Rectangle):
131125
self._transform_dirty = False
132126

133127
# Draw elements
134-
self._draw_lane_lines()
135-
self._draw_path(sm)
128+
draw_polygons_batch(self._rect, self._polygons)
136129

137130
if render_lead_indicator and radar_state:
138131
self._draw_lead_indicator()
@@ -169,6 +162,7 @@ def _update_leads(self, radar_state, path_x_array):
169162

170163
def _update_model(self, lead, path_x_array):
171164
"""Update model visualization data based on model message"""
165+
self._polygons = []
172166
max_distance = np.clip(path_x_array[-1], MIN_DRAW_DISTANCE, MAX_DRAW_DISTANCE)
173167
max_idx = self._get_path_length_idx(self._lane_lines[0].raw_points[:, 0], max_distance)
174168

@@ -177,11 +171,17 @@ def _update_model(self, lead, path_x_array):
177171
lane_line.projected_points = self._map_line_to_polygon(
178172
lane_line.raw_points, 0.025 * self._lane_line_probs[i], 0.0, max_idx
179173
)
174+
alpha = np.clip(self._lane_line_probs[i], 0.0, 0.7)
175+
color = rl.Color(255, 255, 255, int(alpha * 255))
176+
self._polygons.append(
177+
{"points": lane_line.projected_points, "color":color})
180178

181179
# Update road edges using raw points
182-
for road_edge in self._road_edges:
180+
for i, road_edge in enumerate(self._road_edges):
183181
road_edge.projected_points = self._map_line_to_polygon(road_edge.raw_points, 0.025, 0.0, max_idx)
184-
182+
alpha = np.clip(1.0 - self._road_edge_stds[i], 0.0, 1.0)
183+
color = rl.Color(255, 0, 0, int(alpha * 255))
184+
self._polygons.append({"points": road_edge.projected_points, "color": color})
185185
# Update path using raw points
186186
if lead and lead.status:
187187
lead_d = lead.dRel * 2.0
@@ -193,6 +193,7 @@ def _update_model(self, lead, path_x_array):
193193
)
194194

195195
self._update_experimental_gradient(self._rect.height)
196+
self._update_path_polygon()
196197

197198
def _update_experimental_gradient(self, height):
198199
"""Pre-calculate experimental mode gradient colors"""
@@ -233,8 +234,22 @@ def _update_experimental_gradient(self, height):
233234
i += 1 + (1 if (i + 2) < max_len else 0)
234235

235236
# Store the gradient in the path object
236-
self._exp_gradient['colors'] = segment_colors
237-
self._exp_gradient['stops'] = gradient_stops
237+
if len(segment_colors) > 2:
238+
self._polygons.append({
239+
'gradient': {
240+
'start': (0.0, 1.0), # Bottom of path
241+
'end': (0.0, 0.0), # Top of path
242+
'colors': segment_colors,
243+
'stops': gradient_stops,
244+
},
245+
"points": self._path.projected_points,
246+
})
247+
else:
248+
# draw_polygon(self._rect, self._path.projected_points, rl.Color(255, 255, 255, 30))
249+
self._polygons.append({
250+
"points": self._path.projected_points,
251+
"color": rl.Color(255, 255, 255, 30),
252+
})
238253

239254
def _update_lead_vehicle(self, d_rel, v_rel, point, rect):
240255
speed_buff, lead_buff = 10.0, 40.0
@@ -260,38 +275,10 @@ def _update_lead_vehicle(self, d_rel, v_rel, point, rect):
260275

261276
return LeadVehicle(glow=glow, chevron=chevron, fill_alpha=int(fill_alpha))
262277

263-
def _draw_lane_lines(self):
264-
"""Draw lane lines and road edges"""
265-
for i, lane_line in enumerate(self._lane_lines):
266-
if lane_line.projected_points.size == 0:
267-
continue
268-
269-
alpha = np.clip(self._lane_line_probs[i], 0.0, 0.7)
270-
color = rl.Color(255, 255, 255, int(alpha * 255))
271-
draw_polygon(self._rect, lane_line.projected_points, color)
272-
273-
for i, road_edge in enumerate(self._road_edges):
274-
if road_edge.projected_points.size == 0:
275-
continue
276-
277-
alpha = np.clip(1.0 - self._road_edge_stds[i], 0.0, 1.0)
278-
color = rl.Color(255, 0, 0, int(alpha * 255))
279-
draw_polygon(self._rect, road_edge.projected_points, color)
280-
281-
def _draw_path(self, sm):
282-
"""Draw path with dynamic coloring based on mode and throttle state."""
283-
if not self._path.projected_points.size:
284-
return
285-
286-
if self._experimental_mode:
287-
# Draw with acceleration coloring
288-
if len(self._exp_gradient['colors']) > 2:
289-
draw_polygon(self._rect, self._path.projected_points, gradient=self._exp_gradient)
290-
else:
291-
draw_polygon(self._rect, self._path.projected_points, rl.Color(255, 255, 255, 30))
292-
else:
278+
def _update_path_polygon(self):
279+
if True:#not self._experimental_mode:
293280
# Draw with throttle/no throttle gradient
294-
allow_throttle = sm['longitudinalPlan'].allowThrottle or not self._longitudinal_control
281+
allow_throttle = ui_state.sm['longitudinalPlan'].allowThrottle or not self._longitudinal_control
295282

296283
# Start transition if throttle state changes
297284
if allow_throttle != self._prev_allow_throttle:
@@ -305,15 +292,13 @@ def _draw_path(self, sm):
305292
begin_colors = NO_THROTTLE_COLORS if allow_throttle else THROTTLE_COLORS
306293
end_colors = THROTTLE_COLORS if allow_throttle else NO_THROTTLE_COLORS
307294

308-
# Blend colors based on transition
309-
blended_colors = self._blend_colors(begin_colors, end_colors, self._blend_factor)
310295
gradient = {
311296
'start': (0.0, 1.0), # Bottom of path
312297
'end': (0.0, 0.0), # Top of path
313-
'colors': blended_colors,
298+
'colors': self._blend_colors(begin_colors, end_colors, self._blend_factor),
314299
'stops': [0.0, 0.5, 1.0],
315300
}
316-
draw_polygon(self._rect, self._path.projected_points, gradient=gradient)
301+
self._polygons.append({'points': self._path.projected_points, 'gradient': gradient})
317302

318303
def _draw_lead_indicator(self):
319304
# Draw lead vehicles if available

0 commit comments

Comments
 (0)