|  |  |  | @ -1,5 +1,6 @@ | 
			
		
	
		
			
				
					|  |  |  |  | import numpy as np | 
			
		
	
		
			
				
					|  |  |  |  | import pyray as rl | 
			
		
	
		
			
				
					|  |  |  |  | from enum import Enum | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | from cereal import messaging, log | 
			
		
	
		
			
				
					|  |  |  |  | from msgq.visionipc import VisionStreamType | 
			
		
	
	
		
			
				
					|  |  |  | @ -10,8 +11,15 @@ from openpilot.common.transformations.camera import DEVICE_CAMERAS, DeviceCamera | 
			
		
	
		
			
				
					|  |  |  |  | from openpilot.common.transformations.orientation import rot_from_euler | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | OpState = log.SelfdriveState.OpenpilotState | 
			
		
	
		
			
				
					|  |  |  |  | CALIBRATED = log.LiveCalibrationData.Status.calibrated | 
			
		
	
		
			
				
					|  |  |  |  | DEFAULT_DEVICE_CAMERA = DEVICE_CAMERAS["tici", "ar0231"] | 
			
		
	
		
			
				
					|  |  |  |  | UI_BORDER_SIZE = 30 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | class BorderStatus(Enum): | 
			
		
	
		
			
				
					|  |  |  |  |   DISENGAGED = rl.Color(0x17, 0x33, 0x49, 0xc8) # Blue for disengaged state | 
			
		
	
		
			
				
					|  |  |  |  |   OVERRIDE = rl.Color(0x91, 0x9b, 0x95, 0xf1)   # Gray for override state | 
			
		
	
		
			
				
					|  |  |  |  |   ENGAGED = rl.Color(0x17, 0x86, 0x44, 0xf1)    # Green for engaged state | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | class AugmentedRoadView(CameraView): | 
			
		
	
	
		
			
				
					|  |  |  | @ -29,6 +37,7 @@ class AugmentedRoadView(CameraView): | 
			
		
	
		
			
				
					|  |  |  |  |     self._last_calib_time: float = 0 | 
			
		
	
		
			
				
					|  |  |  |  |     self._last_rect_dims = (0.0, 0.0) | 
			
		
	
		
			
				
					|  |  |  |  |     self._cached_matrix: np.ndarray | None = None | 
			
		
	
		
			
				
					|  |  |  |  |     self._content_rect = rl.Rectangle() | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     self.model_renderer = ModelRenderer() | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -36,6 +45,26 @@ class AugmentedRoadView(CameraView): | 
			
		
	
		
			
				
					|  |  |  |  |     # Update calibration before rendering | 
			
		
	
		
			
				
					|  |  |  |  |     self._update_calibration() | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     # Create inner content area with border padding | 
			
		
	
		
			
				
					|  |  |  |  |     self._content_rect = rl.Rectangle( | 
			
		
	
		
			
				
					|  |  |  |  |       rect.x + UI_BORDER_SIZE, | 
			
		
	
		
			
				
					|  |  |  |  |       rect.y + UI_BORDER_SIZE, | 
			
		
	
		
			
				
					|  |  |  |  |       rect.width - 2 * UI_BORDER_SIZE, | 
			
		
	
		
			
				
					|  |  |  |  |       rect.height - 2 * UI_BORDER_SIZE, | 
			
		
	
		
			
				
					|  |  |  |  |     ) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     # Draw colored border based on driving state | 
			
		
	
		
			
				
					|  |  |  |  |     self._draw_border(rect) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     # Enable scissor mode to clip all rendering within content rectangle boundaries | 
			
		
	
		
			
				
					|  |  |  |  |     # This creates a rendering viewport that prevents graphics from drawing outside the border | 
			
		
	
		
			
				
					|  |  |  |  |     rl.begin_scissor_mode( | 
			
		
	
		
			
				
					|  |  |  |  |       int(self._content_rect.x), | 
			
		
	
		
			
				
					|  |  |  |  |       int(self._content_rect.y), | 
			
		
	
		
			
				
					|  |  |  |  |       int(self._content_rect.width), | 
			
		
	
		
			
				
					|  |  |  |  |       int(self._content_rect.height) | 
			
		
	
		
			
				
					|  |  |  |  |     ) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     # Render the base camera view | 
			
		
	
		
			
				
					|  |  |  |  |     super().render(rect) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -44,7 +73,21 @@ class AugmentedRoadView(CameraView): | 
			
		
	
		
			
				
					|  |  |  |  |     # - Path prediction | 
			
		
	
		
			
				
					|  |  |  |  |     # - Lead vehicle indicators | 
			
		
	
		
			
				
					|  |  |  |  |     # - Additional features | 
			
		
	
		
			
				
					|  |  |  |  |     self.model_renderer.draw(rect, self.sm) | 
			
		
	
		
			
				
					|  |  |  |  |     self.model_renderer.draw(self._content_rect, self.sm) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     # End clipping region | 
			
		
	
		
			
				
					|  |  |  |  |     rl.end_scissor_mode() | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   def _draw_border(self, rect: rl.Rectangle): | 
			
		
	
		
			
				
					|  |  |  |  |     state = self.sm["selfdriveState"] | 
			
		
	
		
			
				
					|  |  |  |  |     if state.state in (OpState.preEnabled, OpState.overriding): | 
			
		
	
		
			
				
					|  |  |  |  |       status = BorderStatus.OVERRIDE | 
			
		
	
		
			
				
					|  |  |  |  |     elif state.enabled: | 
			
		
	
		
			
				
					|  |  |  |  |       status = BorderStatus.ENGAGED | 
			
		
	
		
			
				
					|  |  |  |  |     else: | 
			
		
	
		
			
				
					|  |  |  |  |       status = BorderStatus.DISENGAGED | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     rl.draw_rectangle_lines_ex(rect, UI_BORDER_SIZE, status.value) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   def _update_calibration(self): | 
			
		
	
		
			
				
					|  |  |  |  |     # Update device camera if not already set | 
			
		
	
	
		
			
				
					|  |  |  | @ -71,7 +114,7 @@ class AugmentedRoadView(CameraView): | 
			
		
	
		
			
				
					|  |  |  |  |   def _calc_frame_matrix(self, rect: rl.Rectangle) -> np.ndarray: | 
			
		
	
		
			
				
					|  |  |  |  |     # Check if we can use cached matrix | 
			
		
	
		
			
				
					|  |  |  |  |     calib_time = self.sm.recv_frame.get('liveCalibration', 0) | 
			
		
	
		
			
				
					|  |  |  |  |     current_dims = (rect.width, rect.height) | 
			
		
	
		
			
				
					|  |  |  |  |     current_dims = (self._content_rect.width, self._content_rect.height) | 
			
		
	
		
			
				
					|  |  |  |  |     if (self._last_calib_time == calib_time and | 
			
		
	
		
			
				
					|  |  |  |  |         self._last_rect_dims == current_dims and | 
			
		
	
		
			
				
					|  |  |  |  |         self._cached_matrix is not None): | 
			
		
	
	
		
			
				
					|  |  |  | @ -89,7 +132,8 @@ class AugmentedRoadView(CameraView): | 
			
		
	
		
			
				
					|  |  |  |  |     kep = calib_transform @ inf_point | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     # Calculate center points and dimensions | 
			
		
	
		
			
				
					|  |  |  |  |     w, h = current_dims | 
			
		
	
		
			
				
					|  |  |  |  |     x, y = self._content_rect.x, self._content_rect.y | 
			
		
	
		
			
				
					|  |  |  |  |     w, h = self._content_rect.width, self._content_rect.height | 
			
		
	
		
			
				
					|  |  |  |  |     cx, cy = intrinsic[0, 2], intrinsic[1, 2] | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     # Calculate max allowed offsets with margins | 
			
		
	
	
		
			
				
					|  |  |  | @ -117,8 +161,8 @@ class AugmentedRoadView(CameraView): | 
			
		
	
		
			
				
					|  |  |  |  |     ]) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     video_transform = np.array([ | 
			
		
	
		
			
				
					|  |  |  |  |         [zoom, 0.0, (w / 2 - x_offset) - (cx * zoom)], | 
			
		
	
		
			
				
					|  |  |  |  |         [0.0, zoom, (h / 2 - y_offset) - (cy * zoom)], | 
			
		
	
		
			
				
					|  |  |  |  |         [zoom, 0.0, (w / 2 + x - x_offset) - (cx * zoom)], | 
			
		
	
		
			
				
					|  |  |  |  |         [0.0, zoom, (h / 2 + y - y_offset) - (cy * zoom)], | 
			
		
	
		
			
				
					|  |  |  |  |         [0.0, 0.0, 1.0] | 
			
		
	
		
			
				
					|  |  |  |  |     ]) | 
			
		
	
		
			
				
					|  |  |  |  |     self.model_renderer.set_transform(video_transform @ calib_transform) | 
			
		
	
	
		
			
				
					|  |  |  | 
 |