-
我們將學習基本但關鍵的知識,構建你的自動駕駛汽車(虛擬顯示)。
-
你會變得更聰明,就像埃隆·馬斯克(Elon Musk)那樣(你的朋友會嫉妒羨慕你的)。
必要條件
你不需要真正關注跟蹤馬斯克。但有兩個簡單的必要條件
-
在您的系統中安裝最新版本的Python。
-
選擇一個你熟悉的代碼編輯器(PyCharm或VS code,我認為都很酷)。
自動駕駛汽車的核心特征
-
首先,它可以自動駕駛,而無需任何人為干預。
-
其次,如果道路上有任何障礙物,道路盡頭或停車信號,它可以停止行駛。
-
第三,它可以檢測道路并進行相應地轉彎。
-
第四,可以自己到達目的地。
了解這四個核心功能后,您就可以完成這個項目。
讓我們跳過無聊的部分
我們需要創建一個有道路、汽車、轉彎和障礙的項目。這幾乎就像設計一款游戲。
Python提供了一個名為pygame的第三方模塊,它是一組用于編寫電子游戲的Python模塊。這允許你用Python語言創建功能齊全的游戲和多媒體程序。
因為它是第三方模塊,所以在使用它之前,我們需要先安裝它。打開終端,輸入以下命令安裝pygame:
linuxmi@linuxmi:~/www.linuxmi.com$ pip3 install pygame
安裝好之后,我們可以通過簡單地將該模塊導入到我們的項目中來訪問該模塊提供的各種功能:
import pygame
讓我們從有趣的代碼開始
我們將通過五個簡單的步驟來完成此項目。
步驟1、啟動pygame
獲取相關資源。
資源包含汽車將在其上行駛的六種不同類型的賽道。 第六部分有些困難,但是使用它會很有趣。
第一條路很簡單:我們要走一條直線路,我們必須在那兒開車。
從第一個賽道開始,我們需要做三件事:
-
初始化pygame模塊
-
創建所需大小的窗口
-
加載軌道圖像并將其添加到窗口
我們將從導入pygame模塊開始:
import pygame
在使用模塊之前先初始化它:
pygame.init():
接下來,我們使用display() 方法創建基本的pygame窗口。 display方法將簡單地創建一個空窗口,我們可以在其中放置元素。 但是我們需要定義我們需要創建的窗口的大小。 我們可以使用set_mode() 方法做到這一點。
在set_mode() 方法中,我們將窗口的大小(以像素為單位)傳遞為表示該窗口的XY坐標的Python元組。 Python元組是用括號括起來的有效Python數據類型的逗號分隔元素的集合,例如:() 。
有了窗口后,就可以使用pygame提供的圖像模塊加載圖像并創建圖像表面對象。 圖像表面在字節緩沖區內共享數據。 沒有圖像類。 圖像作為表面對象加載:
window = pygame.display.set_mode((1200, 400))
track = pygame.image.load("track1.png")
圖像模塊是pygame的必需依賴項,它提供了load()方法,該方法通過創建圖像表面對象來加載傳遞的圖像。
方法blit() — blit表示塊圖像傳輸 - 將一個表面的內容復制到另一表面。 我們需要傳遞表面圖像對象以及我們要將圖像放置在窗口中的位置。 最后,我們可以使用update()方法更新空白窗口。
上面的代碼產生以下輸出:
現在我們有了軌道,讓我們再來添加汽車。我們將遵循與track相同的方法:加載圖像并使用blit()將其傳送到窗口:
import pygame
pygame.init()
pygame.display.set_caption('www.linuxmi.com 游戲之旅')
window = pygame.display.set_mode((1200, 400))
track = pygame.image.load("track1.png")
while True:
window.blit(track, (0, 0))
pygame.display.update()
添加汽車圖像時,我們必須調整其大小以滿足我們的要求,因為默認圖像尺寸可能不適合。 我們可以使用轉換模塊的scale()方法來調整圖像的大小,并將圖像對象和新的大小作為元組作為參數傳遞。
運行上面的代碼,輸出如下:
步驟1完成。在第二步,我們將駕駛汽車在賽道上,并在需要時停止它。
步驟2、駕駛和控制汽車
在賽道上駕駛賽車超級容易。
我們只需要改變汽車的Y坐標,它就會開始移動。簡單的邏輯是將Y值減少2個或3個點,這樣它就會沿著Y軸向上移動,讓我們覺得汽車在移動:
import pygame
pygame.init()
pygame.display.set_caption('Linux迷 www.linuxmi.com 特斯拉汽車游戲')
window = pygame.display.set_mode((1200, 400))
track = pygame.image.load("track1.png")
car = pygame.image.load("tesla.png")
car = pygame.transform.scale(car, (30, 60))
car_x = 150
car_y = 300
clock = pygame.time.Clock()
while True:
clock.tick(60)
car_y = car_y - 2
window.blit(track, (0, 0))
window.blit(car, (car_x, car_y))
pygame.display.update()
這里,我們只是將變量' car_x '和' car_y '的值作為汽車在blit()方法中的位置傳遞,而不是像前面那樣直接硬編碼這些值。
另外,要控制pygame中元素的移動并使其可見,我們需要在每次迭代中都稍加延遲。可以使用timepygame中的模塊來完成。
就這樣。如果您現在運行代碼,則汽車將開始行駛。
但是有一個問題。汽車駛出賽道并駛出屏幕。一旦到達道路/賽道的盡頭,我們需要停車。為此,我們的汽車需要檢測周圍環境并采取相應措施。
我們將在我們的汽車上創建一個圓形,作為一個相機:
import pygame
pygame.init()
pygame.display.set_caption('Linux迷 www.linuxmi.com 特斯拉汽車游戲')
window = pygame.display.set_mode((1200, 400))
track = pygame.image.load("track1.png")
car = pygame.image.load("tesla.png")
car = pygame.transform.scale(car, (30, 60))
car_x = 150
car_y = 300
clock = pygame.time.Clock()
while True:
clock.tick(60)
cam_x = car_x + 15
cam_y = car_y + 15
car_y = car_y - 2
window.blit(track, (0, 0))
window.blit(car, (car_x, car_y))
pygame.draw.circle(window, (0, 255, 0), (cam_x, cam_y), 5, 5)
pygame.display.update()
我們只使用了一些數學運算,并使用drawPython模塊創建了圓圈。
該circle()方法需要幾個參數:首先是窗口對象,然后是RGB格式的顏色,圓的位置以及圓的大小。
在上面的代碼中,我們在兩條直線上計算并指定了圓的坐標-也就是說,我們需要在汽車前方的圓,因此我們在汽車位置的XY坐標上添加了固定值15:
cam_x = car_x + 15
cam_y = car_y + 15
上面更新的代碼產生以下結果:
我們現在有相機cam。當您運行代碼時,您會發現相機粘在汽車上并且工作正常。
現在的最后一部分是使汽車檢測到賽道的盡頭。既然有了相機,我們需要使它向前看一點。如果白色軌道結束,我們將停止駕駛汽車。
為此,我們聲明一個變量focus_dis并將其賦值為25。這意味著它將負責查看前面的25個步驟。然后我們做一些數學運算:
up_px = window.get_at((cam_x, cam_y - focal_dis))[0]
if up_px == 255:
car_y = car_y - 2
通過使用當前位置值并檢查向前的軌道是否為白色(255代表白色),我們可以得到向前的軌道的位置。如果是這樣,那么只有我們才能移動汽車。
另外,如果您注意到,當我們得到pygame窗口時,我們的光標仍在加載。我們將使用以下代碼擺脫它:
for event in pygame.event.get():
if event.type == pygame.QUIT:
drive = False
現在我們的車停在了賽道的盡頭。這是整個更新的代碼:
import pygame
pygame.init()
pygame.display.set_caption('Linux迷 www.linuxmi.com 特斯拉汽車游戲')
window = pygame.display.set_mode((1200, 400))
track = pygame.image.load("track1.png")
car = pygame.image.load("tesla.png")
car = pygame.transform.scale(car, (30, 60))
car_x = 150
car_y = 300
focal_dis = 25
drive = True
clock = pygame.time.Clock()
while drive:
for event in pygame.event.get():
if event.type == pygame.QUIT:
drive = False
clock.tick(60)
cam_x = car_x + 15
cam_y = car_y + 15
up_px = window.get_at((cam_x, cam_y - focal_dis))[0]
if up_px == 255:
car_y = car_y - 2
window.blit(track, (0, 0))
window.blit(car, (car_x, car_y))
pygame.draw.circle(window, (0, 255, 0), (cam_x, cam_y), 5, 5)
pygame.display.update()
輸出如下圖:
車子停在賽道盡頭
棒不!那是我們自己的自動駕駛汽車。
這是有趣的部分:上面的代碼不僅能夠檢測道路的盡頭,而且還可以檢測是否有障礙物(如下圖所示的第2賽道圖像):
我們的賽道2有一個障礙。但是我們的特斯拉可以檢測到它。它看到前方的軌道是紅色而不是白色,因此它停止了行駛。
在上面的代碼中,只需將賽道中的圖像更改為‘track2.png’:
track = pygame.image.load("track2.png")
現在,讓我們再次執行代碼。它產生以下輸出:
看,我們的車停下來了!
步驟3、處理轉彎
讓我們進一步前進。讓我們來嘗試一下‘track3.png’:
track = pygame.image.load(“track3.png”)
執行代碼將產生以下輸出:
它工作正常。但是現在,這對我們來說是另一個挑戰:以一種能夠轉彎的方式駕駛汽車。
哦,請明白這一點:在轉彎之前,我們的汽車應該知道在特定的轉彎之后有一條道路/賽道。因此,無論何時汽車停下來,我們都需要在這種情況下看向右側。
我們的汽車停在必須水平行進的特定點上,即在X軸方向上,而我們的Y軸將保持不變。為此,我們將定義另一個變量‘right_px’,該變量將負責查看右側,就像我們使用了‘up_px’:
right_px = window.get_at((cam_x + focal_dis, cam_y))[0]
因此,X軸+焦距和Y軸將保持不變。
讓我們定義一個變量‘direction’,以跟蹤汽車的行駛方向,并將其初始化為‘up’:
direction = 'up'
現在,我們將有一個if條件來防止up_px等于255-也就是說,它不應是白色軌跡。如果right_px等于255,則意味著我們在右側有一條白色的軌道,需要轉彎:
# 改變方向(轉彎)
if up_px != 255 and right_px == 255:
direction = 'right'
而已。我們if有條件檢查a是否up_px為白色,如果是,它將使汽車沿Y軸移動,還記得嗎?現在,讓我們簡單地添加一個elif條件,使我們的汽車向右轉:
# 開車
if up_px == 255:
car_y = car_y - 2
elif direction == 'right' and right_px == 255:
car_x = car_x + 2
該代碼現在產生以下輸出:
賽車在右轉結束時停止,但角度錯誤(見上圖)
這在一定程度上達到了目的,并且汽車向右行駛。但是我們也需要旋轉汽車,對嗎?
我們可以使用該rotate()方法來做到這一點。它帶有兩個參數:需要旋轉的對象和角度。
car = pygame.transform.rotate(car, -90)
但是當您這樣做時,您會發現汽車上的攝像頭會粘在后面,而我們需要將其放在前面。為了解決這個問題,讓我們定義一個‘cam_x_offset = 0’初始化為零的變量。由于我們稍后將更改此變量的值,因此我們只需將該變量定義為0。此變量將負責攝像機的位置。因此,輪到我們時,我們還需要更改此變量的值。
另外,讓我們檢查條件下的方向值。以下是更新的條件語句:
# 改變方向(轉彎)
if direction == 'up' and up_px != 255 and right_px == 255:
direction = 'right'
cam_x_offset = 30
car = pygame.transform.rotte(car, -90)
我們完了?,F在應該可以正常工作了。這是到目前為止的全部更新代碼:
import pygame
pygame.init()
pygame.display.set_caption('Linux迷 www.linuxmi.com 特斯拉汽車游戲')
window = pygame.display.set_mode((1200, 400))
track = pygame.image.load("track3.png")
car = pygame.image.load("tesla.png")
car = pygame.transform.scale(car, (30, 60))
car_x = 150
car_y = 300
cam_x_offset = 0
direction = 'up'
focal_dis = 25
drive = True
clock = pygame.time.Clock()
while drive:
for event in pygame.event.get():
if event.type == pygame.QUIT:
drive = False
clock.tick(60)
cam_x = car_x + cam_x_offset + 15
cam_y = car_y + 15
up_px = window.get_at((cam_x, cam_y - focal_dis))[0]
right_px = window.get_at((cam_x + focal_dis, cam_y))[0]
# 改變方向(轉彎)
if direction == 'up' and up_px != 255 and right_px == 255:
direction = 'right'
cam_x_offset = 30
car = pygame.transform.rotte(car, -90)
# 開車
if direction == 'up' and up_px == 255:
car_y = car_y - 2
elif direction == 'right' and right_px == 255:
car_x = car_x + 2
window.blit(track, (0, 0))
window.blit(car, (car_x, car_y))
pygame.draw.circle(window, (0, 255, 0), (cam_x, cam_y), 5, 5)
pygame.display.update()
讓我們看一下輸出:
完成的游戲,賽車在右轉彎的盡頭停下來了,并且車頭轉正了!
步驟4、新賽道-下移
現在,讓我們繼續前進并檢查賽道4:
track = pygame.image.load("track4.png")
執行代碼:
如上圖,它工作得很好,但這一次,我們需要讓相機向下看(在輸出中可以看到,我們有一個向下的軌道),我們的汽車需要再次轉彎?,F在你知道怎么做了吧?
-
轉向的車。
-
創建down_px變量向下看。
-
設置cam_y偏移設置相機在y軸上的偏移量。
很簡單,是吧?
這是經過上述更改后的更新代碼:
import pygame
pygame.init()
pygame.display.set_caption('Linux迷 www.linuxmi.com 特斯拉汽車游戲')
window = pygame.display.set_mode((1200, 400))
track = pygame.image.load("track3.png")
car = pygame.image.load("tesla.png")
car = pygame.transform.scale(car, (30, 60))
car_x = 150
car_y = 300
cam_x_offset = 0
direction = 'up'
focal_dis = 25
drive = True
clock = pygame.time.Clock()
while drive:
for event in pygame.event.get():
if event.type == pygame.QUIT:
drive = False
clock.tick(60)
cam_x = car_x + cam_x_offset + 15
cam_y = car_y + 15
up_px = window.get_at((cam_x, cam_y - focal_dis))[0]
right_px = window.get_at((camx + focal_dis, cam_y))[0]
# change direction (take turn)
if direction == 'up' and up_px != 255 and right_px == 255:
direction = 'right'
cam_x_offset = 30
car = pygame.transform.rotate(car, -90)
# drive
if direction == 'up' and up_px == 255:
car_y = car_y - 2
elif direction == 'right' and right_px == 255:
car_x = car_x + 2
window.blit(track, (0, 0))
window.blit(car, (car_x, car_y))
pygame.draw.circle(window, (0, 255, 0), (cam_x, cam_y), 5, 5)
pygame.display.update()import pygame
pygame.init()
pygame.display.set_caption('Linux迷 www.linuxmi.com 特斯拉汽車游戲')
window = pygame.display.set_mode((1200, 400))
track = pygame.image.load("track4.png")
car = pygame.image.load("tesla.png")
car = pygame.transform.scale(car, (30, 60))
car_x = 150
car_y = 300
cam_x_offset = 0
cam_y_offset = 0
direction = 'up'
focal_dis = 25
drive = True
clock = pygame.time.Clock()
while drive:
for event in pygame.vent.get():
if event.type == pygame.QUIT:
drive = False
clock.tick(60)
cam_x = car_x + cam_x_offset + 15
cam_y = car_y + cam_y_offset + 15
up_px = window.get_at((cam_x, cam_y - focal_dis))[0]
right_px = window.get_at((cam_x + focal_dis, cam_y))[0]
down_px = window.get_at((cam_x, cam_y + focal_dis))[0]
# 改變方向(轉彎)
if direction == 'up' and up != 255 and right_px == 255:
direction = 'right'
cam_x_offset = 30
car = pygame.transform.rotate(car, -90)
elif direction == 'right' and right_px != 255 and down_px == 255:
direction = 'down'
car_x = car_x + 30
cam_x_offset = 0
cam_y_offset = 30
car = pygame.transform.rotate(car, -90)
# 開車
if direction == 'up' and up_px == 255:
car_y = car_y - 2
elif direction == 'right' and right_px == 255:
car_x = car_x + 2
elif direction == 'down' and down_px == 255:
car_y = car_y + 2
window.blit(track, (0, 0))
window.blit(car, (car_x, car_y))
pygame.draw.circle(window, (0, 255, 0), (cam_x, cam_y), 5, 5)
pygame.display.update()
執行它,輸出如下:
好極了!我們的自動駕駛汽車已經在學習如何自動駕駛。
步驟5、新路線-最終道路
現在,讓我們繼續前進并檢查賽道5:
track = pygame.image.load("track5.png")
讓我們看一下輸出:
在我們的車左轉之前,它一直運轉良好。我們的車可以上下移動,現在,我們需要做同樣的更改,并處理使汽車左轉的情況。為什么離開了?假設你在車里(綠點是前面的攝像頭)。
elif direction == 'down' and down_px != 255 and right_px == 255:
direction = 'right'
car_y = car_y + 30
cam_x_offset = 30
cam_y_offset = 0
car = pygame.transform.rotate(car, 90)
這將使我們的汽車向左轉。讓我們看一下輸出:
我們做到了?,F在,最后一件事是重新確定方向up并處理汽車和攝像頭的位置。
這是相同的條件:
elif direction == 'right' and right_px != 255 and up_px == 255:
direction = 'up'
car_x = car_x + 30
cam_x_offset = 0
car = pygame.transform.rotate(car, 90)
讓我們執行代碼以查看輸出:
有用!我們已經處理了所有方向,現在我們的汽車將能夠在任何道路上自動行駛。嘗試‘track6’進行驗證。
track = pygame.image.load("track6.png")
最終執行,輸出如下:
OK,我們做到了。您有自己的自動駕駛汽車了。
審核編輯 :李倩
-
編輯器
+關注
關注
1文章
806瀏覽量
31293 -
python
+關注
關注
56文章
4807瀏覽量
85040 -
自動駕駛
+關注
關注
785文章
13932瀏覽量
167013
原文標題:Python 代碼實現汽車自動駕駛技術
文章出處:【微信號:Linux迷,微信公眾號:Linux迷】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論