(1-6-03) Dijkstra算法:基于Pygame模拟的自动驾驶系统(3)

1.6.5  主程序

在本项目中有三个程序文件包含了main()函数,都可以被视为主程序,分别负责执行程序的不同逻辑。每个文件都有不同的主要功能,但它们都在程序的不同方面扮演着核心的角色。

(1)文件autopilot.py实现了一个自动驾驶汽车游戏的主程序。首先,根据选择的难度级别生成游戏世界和路线地图。然后,利用采样路径规划方法生成路径,并尝试解决规划问题。接着,根据规划结果模拟路径,并通过动作规划生成自动驾驶汽车的动作序列。最后,在自动驾驶模式下运行游戏,根据生成的动作序列控制汽车行驶,并实时更新游戏界面。

def main():
    difficulty="Easy" # 简单,中等,困难,极难,随机
    # 启动游戏
    print("Starting game")
    game=car_game(difficulty) # 实例化游戏
    print("Generating world")
    world=World(game) # 生成世界

    # 生成运动规划
    print("Generating roadmap for solver")
    Map = statespace.RoadMap(game, world)
    print("Attempting to solve")
    planner = motionplanner.SamplingPlanner(Map)
    t0 = time()
    solved, plan, exploredNodes, _ = planner.RRT()
    t1 = time() 
    if solved: 
        print(f'Path found in {t1-t0} s\n')
    else:
        print('Path not found')
    planner.simulation(plan, exploredNodes)
    actions = motionplanner.actionPlanner_SDC(Map, plan)
    # 在自动驾驶模式下运行游戏
    runGame(game, world, actions)
    pygame.quit()

def runGame(game, world, actions):
    busy = False
    ready_for_next_action = True
    angle = 0
    turn_increment = 15
    count, start_count =0, 0
    while game.run:
        game.clock.tick(100)
        count+=1
        # 更新绿色汽车
        for active_car in game.active_list:
            active_car.spritex+=active_car.vel
            active_car.updateCarOrigin()
        # 获取新事件
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                game.run = False

        keys = pygame.key.get_pressed()
        # t = pygame.time.get_ticks()
        if ready_for_next_action:
            if actions:
                action,position = actions.pop(0)
                ready_for_next_action = False
                if action == 'L':
                    angle = turn_increment
                    lane_change_count = 33
                elif action == 'R':
                    angle = -turn_increment
                    lane_change_count = 33

        if game.orange_car.x + 3*game.orange_car.car_width_px < position:
            game.orange_car.turnCar(0,game)
            start_count = count
        else:
            if count-start_count<=lane_change_count:
                game.orange_car.turnCar(angle,game)  
            elif game.orange_car.theta*(angle/abs(angle)) > 0:
                game.orange_car.turnCar(-angle,game)
            else:
                game.orange_car.theta = 0
                ready_for_next_action = True

        world.updateWinPos(game)
        world.window.redrawGameWindow(game,world.WorldSize_px)          
        if keys[pygame.K_q]:
            pygame.quit()
            game.run=False

if __name__ == '__main__':
    main()

(2)文件photo.py的功能是创建一个游戏世界并生成游戏窗口,然后在游戏窗口中绘制汽车游戏场景,并保存为图像文件。具体步骤包括导入所需的模块和函数、设置游戏难度、生成游戏世界、设置窗口大小和位置、将橙色汽车放置在指定位置、绘制游戏窗口场景、保存窗口截图为图像文件,并最终退出pygame游戏。

# 导入自定义函数
sys.path.append('Game/')
sys.path.append('MotionPlanning/')
from car import car
from window import Window
from world import World
from game import car_game
import statespace
import motionplanner
difficulty = "Easy" # 简单、中等、困难、极端、随机
print("Starting game")  # 开始游戏
game=car_game(difficulty) # 实例化游戏
print("Generating world") # 生成世界
world=World(game) # 生成世界

# 将窗口宽度和高度设置为与世界匹配
world.window.width_px=world.WorldSize_px[0]
world.window.height_px=world.WorldSize_px[1]
world.window.win = pygame.display.set_mode((world.window.width_px, world.window.height_px))

# 将窗口放置在左上角
world.window.x=0
world.window.y=0

# 将橙色汽车放在正确的位置
game.orange_car.spritex=410-game.orange_car.car_width_px/2
game.orange_car.spritey=375

# 绘制窗口并保存
world.window.redrawGameWindow(game,world.WorldSize_px)
path='world_files/'+game.gameMode+'.png'
pygame.image.save(world.window.win,path)
print("Image saved to '"+path+"'")

pygame.quit()

(3)文件worldbuilder.py实现了一个游戏世界构建器,允许用户以“建立模式”在游戏世界中放置蓝色汽车。用户可以使用箭头键移动窗口,并在所选位置放置蓝色汽车。当用户点击鼠标时,将在鼠标位置放置蓝色汽车,并保存汽车位置供以后使用。用户可以按下Q键保存并退出。

difficulty = "Easy" # 简单、中等、困难、极难、随机
road_length = 170 # 米,乘以 30 转换为像素

needCheck=True
print("这是一个用于选择蓝色汽车位置的建造模式")
while needCheck:
    check=input("此模式将覆盖以前保存的难度为 '"+difficulty+"' 的蓝色汽车位置。您确定要继续吗?请输入 'Yes' 或 'No':")
    if check.lower()=="no" or check.lower()=='n':
        print("退出")
        needCheck=False
        exit()
    elif check.lower()=="yes" or check.lower()=='y':
        needCheck=False
        print("使用箭头键移动窗口,然后选择您想要蓝色汽车停放的位置")
        print("单击的位置会出现一个蓝色汽车,并且它的位置将被保存以供以后使用")
        print("完成后,按 Q 键保存并退出。下次您使用此难度模式运行 game.py 时,所有汽车都将停放在您放置它们的位置。")
    else:
        print("我不明白。请重试。")
bluecarlist=[]

car_pos_path = 'world_files/car_positions_'+difficulty+'.data'
length_path = 'world_files/road_length_'+difficulty+'.data'

if os.path.exists(car_pos_path):
    os.remove(car_pos_path)
if os.path.exists(length_path):
    os.remove(length_path)

print("开始游戏")
game=car_game(difficulty) # 实例化游戏

print("生成世界")
world=World(game) # 生成世界

world.window.width_px=1800
world.window.height_px=world.WorldSize_px[1]
world.window.win = pygame.display.set_mode((world.window.width_px, world.window.height_px))

# 运行游戏
while game.run:
    game.clock.tick(100)
    # 获取新事件
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            game.run = False
    keys = pygame.key.get_pressed()
    speed=10
    # 获取用于放置蓝色汽车的光标位置
    if keys[pygame.K_LEFT]:
        world.window.x-=speed
    elif keys[pygame.K_RIGHT]:
        world.window.x+=speed
    if keys[pygame.K_UP]:
        world.window.y-=speed
    elif keys[pygame.K_DOWN]:
        world.window.y+=speed
    cursor=pygame.mouse.get_pos()
    click=pygame.mouse.get_pressed()
    if click[0]==1:
        window_pos=(world.window.x,world.window.y)
        cursor_pos=(cursor[0]+window_pos[0],cursor[1]+window_pos[1])
        if world.window.top_shoulder_pos_y+world.window.y<=cursor_pos[1]<=world.window.lane_pos_y[0]+world.window.y:
            new_y=(world.window.top_shoulder_pos_y+world.window.lane_pos_y[0])/2+world.window.y

        if world.window.lane_pos_y[0]+world.window.y<=cursor_pos[1]<=world.window.lane_pos_y[1]+world.window.y:
            new_y=(world.window.lane_pos_y[0]+world.window.y+world.window.lane_pos_y[1]+world.window.y)/2
        
        if world.window.lane_pos_y[1]+world.window.y<=cursor_pos[1]<=world.window.lane_pos_y[2]+world.window.y:
            new_y=(world.window.lane_pos_y[1]+world.window.y+world.window.lane_pos_y[2]+world.window.y)/2

        if world.window.lane_pos_y[2]+world.window.y<=cursor_pos[1]<=world.window.bot_shoulder_pos_y+world.window.y:
            new_y=(world.window.lane_pos_y[2]+world.window.y+world.window.bot_shoulder_pos_y+world.window.y)/2
        new_obst=car(cursor_pos[0],new_y,"obstacle",game)
        game.obst_list.add(new_obst)
        game.all_sprites.add(new_obst)
        bluecarlist.append(cursor_pos)

    # world.updateWinPos(game)
    world.window.redrawGameWindow(game,world.WorldSize_px)
        
    if keys[pygame.K_q]:
        pygame.quit()
        game.run=False

pygame.quit()
print("保存数据")
# 从长点击中清除重复项
bluecarlist=list(dict.fromkeys(bluecarlist))
# print(bluecarlist)
with open(car_pos_path,'wb') as filehandle:
    pickle.dump(bluecarlist,filehandle)
    print("数据已保存")
with open(length_path,'wb') as filehandle:
    pickle.dump(road_length,filehandle)

执行本项目后,在Pygame中的模拟效果如图1-8所示。

图1-8  在Pygame中的模拟效果

绘制的自动驾驶路径的可视化图如图1-8所示。

图1-8  自动驾驶路径的可视化图

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农三叔

感谢鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值