|
1 | 1 | import carla |
2 | 2 | import random |
3 | 3 | import time |
| 4 | +import numpy as np |
| 5 | +import math |
| 6 | +import pygame |
| 7 | + |
| 8 | +# 初始化Pygame显示窗口 |
| 9 | +def init_pygame(width, height): |
| 10 | + pygame.init() |
| 11 | + display = pygame.display.set_mode((width, height)) |
| 12 | + pygame.display.set_caption("Driver's View") |
| 13 | + return display |
| 14 | + |
| 15 | +# 转换CARLA图像为RGB numpy数组 |
| 16 | +def process_image(image): |
| 17 | + array = np.frombuffer(image.raw_data, dtype=np.uint8) |
| 18 | + array = array.reshape((image.height, image.width, 4))[:, :, :3] # 丢弃alpha通道 |
| 19 | + return array |
| 20 | + |
| 21 | +# 计算车辆到目标路点的转向角度 |
| 22 | +def get_steering_angle(vehicle_transform, waypoint_transform): |
| 23 | + v_loc = vehicle_transform.location |
| 24 | + v_forward = vehicle_transform.get_forward_vector() |
| 25 | + wp_loc = waypoint_transform.location |
| 26 | + direction = wp_loc - v_loc |
| 27 | + direction = carla.Vector3D(direction.x, direction.y, 0.0) |
| 28 | + |
| 29 | + v_forward = carla.Vector3D(v_forward.x, v_forward.y, 0.0) |
| 30 | + norm_dir = math.sqrt(direction.x ** 2 + direction.y ** 2) |
| 31 | + norm_fwd = math.sqrt(v_forward.x ** 2 + v_forward.y ** 2) |
| 32 | + |
| 33 | + dot = v_forward.x * direction.x + v_forward.y * direction.y |
| 34 | + angle = math.acos(dot / (norm_dir * norm_fwd + 1e-5))# 避免除零错误 |
| 35 | + cross = v_forward.x * direction.y - v_forward.y * direction.x |
| 36 | + if cross < 0: |
| 37 | + angle *= -1 |
| 38 | + return angle |
| 39 | + |
4 | 40 |
|
5 | 41 | # 主函数 |
6 | 42 | def main(): |
@@ -30,6 +66,59 @@ def main(): |
30 | 66 | traffic_vehicle.set_autopilot(True) |
31 | 67 | actor_list.append(traffic_vehicle) |
32 | 68 |
|
| 69 | + # 挂载RGB摄像头到主车辆 |
| 70 | + camera_bp = blueprint_library.find("sensor.camera.rgb") |
| 71 | + camera_bp.set_attribute("image_size_x", "800") |
| 72 | + camera_bp.set_attribute("image_size_y", "600") |
| 73 | + camera_bp.set_attribute("fov", "90") |
| 74 | + camera_transform = carla.Transform(carla.Location(x=1.5, z=1.7)) |
| 75 | + camera = world.spawn_actor(camera_bp, camera_transform, attach_to=vehicle) |
| 76 | + actor_list.append(camera) |
| 77 | + |
| 78 | + # 初始化Pygame窗口 |
| 79 | + display = init_pygame(800, 600) |
| 80 | + |
| 81 | + # 摄像头回调:接收并转换图像 |
| 82 | + image_surface = [None] |
| 83 | + |
| 84 | + def image_callback(image): |
| 85 | + image_surface[0] = process_image(image) |
| 86 | + |
| 87 | + camera.listen(image_callback) |
| 88 | + print("摄像头挂载完成") |
| 89 | + |
| 90 | + clock = pygame.time.Clock() |
| 91 | + |
| 92 | + # 实时显示 |
| 93 | + while True: |
| 94 | + # 窗口退出逻辑 |
| 95 | + for event in pygame.event.get(): |
| 96 | + if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE): |
| 97 | + return |
| 98 | + |
| 99 | + # 车辆自动转向控制 |
| 100 | + transform = vehicle.get_transform() |
| 101 | + waypoint = map.get_waypoint(transform.location, project_to_road=True,lane_type=carla.LaneType.Driving) |
| 102 | + next_waypoint = waypoint.next(2.0)[0] # 下一个2米的路点 |
| 103 | + angle = get_steering_angle(transform, next_waypoint.transform) |
| 104 | + steer = max(-1.0, min(1.0, angle * 2.0)) # 限制转向范围 |
| 105 | + |
| 106 | + # 应用车辆控制:默认油门0.5,自动转向 |
| 107 | + control = carla.VehicleControl() |
| 108 | + control.throttle = 0.5 |
| 109 | + control.steer = steer |
| 110 | + control.brake = 0.0 |
| 111 | + vehicle.apply_control(control) |
| 112 | + |
| 113 | + # 渲染摄像头画面到Pygame窗口 |
| 114 | + if image_surface[0] is not None: |
| 115 | + surface = pygame.image.frombuffer(image_surface[0].tobytes(), (800, 600), "RGB") |
| 116 | + display.blit(surface, (0, 0)) |
| 117 | + pygame.display.flip() |
| 118 | + |
| 119 | + # 限制帧率30FPS |
| 120 | + clock.tick(30) |
| 121 | + |
33 | 122 | finally: |
34 | 123 | # 清理Actor |
35 | 124 | print("清理actors") |
|
0 commit comments