機器人世界

與人類一樣,機器人通過它的“感官”來感知世界。例如,無人駕駛汽車使用視頻、雷達與激光雷達來觀察周圍的世界。隨着汽車不斷地收集數據,它們會建立起一個3D觀察世界,在這個世界,汽車可以知道自己在哪裏,其他物體(如樹木、行人和其他車輛)在哪裏,以及它應該去哪裏!

機器人世界: 1-D

首先,假設你有一個生活在1-D世界中機器人。你可以將這個1-D世界看做是一個單車道道路

我們可以將這條道路視爲一個陣列,並將其分解爲很多網格單元,便於機器人理解。在這種情況下,這條道路是一個一維網格,有5個不同的空間。機器人只能向前或向後移動。如果機器人從網格上掉下來,它將環繞回到另一側(這被稱爲循環世界)。

均勻分佈

機器人有一張地圖,因此它知道這個1D世界中只有5個空間,但是,它沒有感覺到任何東西或沒有發生移動。那麼,對於這個5個單元格長度(5個值的列表),機器人在這些位置中的任何一個位置的概率分佈p是多少? 由於機器人最初不知道它在哪裏,所以在任何空間中的概率是相同的!這就是概率分佈,因此所有這些概率的總和應該等於1,所以1/5 spaces = 0.2。所有概率相同(並且具有最大不確定性)的分佈稱爲均勻分佈

# importing resources
import matplotlib.pyplot as plt
import numpy as np
# uniform distribution for 5 grid cells
# we use "p" to represent probability
p = [0.2, 0.2, 0.2, 0.2, 0.2]
print(p)

下面的函數display_map將會輸出一個條形圖,用於顯示機器人在每個網格空間中的概率。對於概率範圍,y軸的範圍爲0到1。在均勻分佈中,這看起來像一條扁平線。如果你想將它們分開,可以選擇每個條的寬度<= 1。

def display_map(grid, bar_width=1):
    if(len(grid) > 0):
        x_labels = range(len(grid))
        plt.bar(x_labels, height=grid, width=bar_width, color='b')
        plt.xlabel('Grid Cell')
        plt.ylabel('Probability')
        plt.ylim(0, 1) # range of 0-1 for probability values 
        plt.title('Probability of the robot being at each cell in the grid')
        plt.xticks(np.arange(min(x_labels), max(x_labels)+1, 1))
        plt.show()
    else:
        print('Grid is empty')

# call function on grid, p, from before
display_map(p)
機器人傳感器

機器人通過攝像頭和其他傳感器來感知世界,但這些傳感器並不是完全正確。 感知後的概率: 機器人會感知它處於一個紅色單元格中,並更新其概率。根據我們的例子:

  • 機器人對顏色感知正確的概率是pHit = 0.6
  • 機器人對顏色感知不正確的概率是pMiss = 0.2,在這個示例中:它看到了紅色,但實際上它在綠色單元格中
# given initial variables
p = initialize_robot(5)
pHit  = 0.6
pMiss = 0.2

# Creates a new grid, with modified probabilities, after sensing
# All values are calculated by a product of 1. the sensing probability for a color (pHit for red)
# and 2. the current probability of a robot being in that location p[i]; all equal to 0.2 at first.
p[0] = p[0]*pMiss
p[1] = p[1]*pHit
p[2] = p[2]*pHit
p[3] = p[3]*pMiss
p[4] = p[4]*pMiss

print(p)
display_map(p)
# given initial variables
p=[0.2, 0.2, 0.2, 0.2, 0.2]
# the color of each grid cell in the 1D world
world=['green', 'red', 'red', 'green', 'green']
# Z, the sensor reading ('red' or 'green')
Z = 'red'
pHit = 0.6
pMiss = 0.2

## Complete this function
def sense(p, Z):
    ''' Takes in a current probability distribution, p, and a sensor reading, Z.
        Returns an unnormalized distribution after the sensor measurement has been made, q.
        This should be accurate whether Z is 'red' or 'green'. '''
    
    q=[]
    for i in range(len(p)):
        hit = (Z == world[i])
        q.append(p[i] * (hit * pHit + (1-hit) * pMiss))
    return q

q = sense(p,Z)
print(q)
display_map(q)
# given initial variables
p=[0.2, 0.2, 0.2, 0.2, 0.2]
# the color of each grid cell in the 1D world
world=['green', 'red', 'red', 'green', 'green']
# Z, the sensor reading ('red' or 'green')
Z = 'red'
pHit = 0.6
pMiss = 0.2

## Complete this function
def sense(p, Z):
    ''' Takes in a current probability distribution, p, and a sensor reading, Z.
        Returns a *normalized* distribution after the sensor measurement has been made, q.
        This should be accurate whether Z is 'red' or 'green'. '''
    
    q=[]
    
    ##TODO: normalize q
    
    # loop through all grid cells
    for i in range(len(p)):
        # check if the sensor reading is equal to the color of the grid cell
        # if so, hit = 1
        # if not, hit = 0
        hit = (Z == world[i])
        q.append(p[i] * (hit * pHit + (1-hit) * pMiss))
        
    # sum up all the components
    s = sum(q)
    # divide all elements of q by the sum
    for i in range(len(p)):
        q[i] = q[i] / s
    return q

q = sense(p,Z)
print(q)
display_map(q)
Move函數

使其返回一個新的分佈q,向右運動(U)個單位。此函數下的分佈應隨着運動U的變化而變化,如果U = 1,你應該可以看到p中的所有值都向右移動1。

## TODO: Complete this move function so that it shifts a probability distribution, p
## by a given motion, U
def move(p, U):
    q=[]
    # iterate through all values in p
    for i in range(len(p)):
        # use the modulo operator to find the new location for a p value
        # this finds an index that is shifted by the correct amount
        index = (i-U) % len(p)
        # append the correct value of p to q
        q.append(p[index])
    return q

p = move(p,2)
print(p)
display_map(p)
不精確的運動

對於初始分佈[0,1,0,0,0]和U = 2的運動,當考慮運動中的不確定性時,得到的分佈是:[0,0,0.1,0.8,0.1]

修改move函數,使其能夠容納機器人超越或未到達預期目的地的附加概率 此函數下的分佈應隨着運動U的變化而變化,但其中有一些未達到目的地或超越目的地的概率。 對於給定的初始p,你應該可以看到一個U = 1的結果並且包含不確定性:[0.0, 0.1, 0.8, 0.1, 0.0]。

## TODO: Modify the move function to accommodate the added robabilities of overshooting or undershooting 
pExact = 0.8
pOvershoot = 0.1
pUndershoot = 0.1

# Complete the move function
def move(p, U):
    q=[]
    # iterate through all values in p
    for i in range(len(p)):
        # use the modulo operator to find the new location for a p value
        # this finds an index that is shifted by the correct amount
        index = (i-U) % len(p)
        nextIndex = (index+1) % len(p)
        prevIndex = (index-1) % len(p)
        s = pExact * p[index]
        s = s + pOvershoot  * p[nextIndex]
        s = s + pUndershoot * p[prevIndex]
        # append the correct, modified value of p to q
        q.append(s)
    return q

## TODO: try this for U = 2 and see the result
p = move(p,1)
print(p)
display_map(p)
多次不精確移動
# given initial variables
p=[0, 1, 0, 0, 0]
# the color of each grid cell in the 1D world
world=['green', 'red', 'red', 'green', 'green']
# Z, the sensor reading ('red' or 'green')
Z = 'red'
pHit = 0.6
pMiss = 0.2

pExact = 0.8
pOvershoot = 0.1
pUndershoot = 0.1

# Complete the move function
def move(p, U):
    q=[]
    # iterate through all values in p
    for i in range(len(p)):
        # use the modulo operator to find the new location for a p value
        # this finds an index that is shifted by the correct amount
        index = (i-U) % len(p)
        nextIndex = (index+1) % len(p)
        prevIndex = (index-1) % len(p)
        s = pExact * p[index]
        s = s + pOvershoot  * p[nextIndex]
        s = s + pUndershoot * p[prevIndex]
        # append the correct, modified value of p to q
        q.append(s)
    return q

# Here is code for moving twice
# p = move(p, 1)
# p = move(p, 1)
# print(p)
# display_map(p)
## TODO: Write code for moving 1000 times
for k in range(1000):
    p = move(p,1)

print(p)
display_map(p)

谷歌無人車定位功能基本就是以上代碼實現,編寫了兩個部分:感知和移動

感知與移動 循環
# importing resources
import matplotlib.pyplot as plt
import numpy as np

def display_map(grid, bar_width=1):
    if(len(grid) > 0):
        x_labels = range(len(grid))
        plt.bar(x_labels, height=grid, width=bar_width, color='b')
        plt.xlabel('Grid Cell')
        plt.ylabel('Probability')
        plt.ylim(0, 1) # range of 0-1 for probability values 
        plt.title('Probability of the robot being at each cell in the grid')
        plt.xticks(np.arange(min(x_labels), max(x_labels)+1, 1))
        plt.show()
    else:
        print('Grid is empty')

給定列表爲motions=[1,1],如果機器人首先感知到紅色,則計算後驗分佈,然後向右移動一個單位,然後感知綠色,之後再次向右移動,從均勻的先驗分佈p開始。 motions=[1,1]意味着機器人向右移動一個單元格,然後向右移動。你會獲得一個初始變量以及完整的sensemove函數,如下所示。

# given initial variables
p=[0.2, 0.2, 0.2, 0.2, 0.2]
# the color of each grid cell in the 1D world
world=['green', 'red', 'red', 'green', 'green']
# Z, the sensor reading ('red' or 'green')
measurements = ['red', 'green']
pHit = 0.6
pMiss = 0.2

motions = [1,1]
pExact = 0.8
pOvershoot = 0.1
pUndershoot = 0.1

# You are given the complete sense function
def sense(p, Z):
    ''' Takes in a current probability distribution, p, and a sensor reading, Z.
        Returns a *normalized* distribution after the sensor measurement has been made, q.
        This should be accurate whether Z is 'red' or 'green'. '''
    q=[]
    # loop through all grid cells
    for i in range(len(p)):
        # check if the sensor reading is equal to the color of the grid cell
        # if so, hit = 1
        # if not, hit = 0
        hit = (Z == world[i])
        q.append(p[i] * (hit * pHit + (1-hit) * pMiss))
        
    # sum up all the components
    s = sum(q)
    # divide all elements of q by the sum to normalize
    for i in range(len(p)):
        q[i] = q[i] / s
    return q


# The complete move function
def move(p, U):
    q=[]
    # iterate through all values in p
    for i in range(len(p)):
        # use the modulo operator to find the new location for a p value
        # this finds an index that is shifted by the correct amount
        index = (i-U) % len(p)
        nextIndex = (index+1) % len(p)
        prevIndex = (index-1) % len(p)
        s = pExact * p[index]
        s = s + pOvershoot  * p[nextIndex]
        s = s + pUndershoot * p[prevIndex]
        # append the correct, modified value of p to q
        q.append(s)
    return q


## TODO: Compute the posterior distribution if the robot first senses red, then moves 
## right one, then senses green, then moves right again, starting with a uniform prior distribution.
for k in range(len(measurements)):
    # sense and then move, reading the correct measurements/motions at each step
    p = sense(p, measurements[k])
    p = move(p, motions[k])

## print/display that distribution
print(p)
display_map(p)
## print/display that distribution
關於熵值的說明

在更新步驟之後熵值將下降,並且在測量步驟之後熵值將上升。 通常情況下,熵值可以用來測量不確定性的量。由於更新步驟增加了不確定性,因此熵值應該增加。測量步驟降低了不確定性,因此熵值應該減少。 讓我們看一看當前的這個例子,其中機器人可以處於五個不同的位置。當所有位置具有相等的概率 [0.2,0.2,0.2,0.2,0.2] 時,會出現最大的不確定性。

進行測量就會降低不確定性,從而降低熵值。假設在進行測量後,概率變爲 [0.05,0.05,0.05,0.8,0.05]。現在熵值減少到0.338。因此,一個測量步驟會使熵值降低,而一個更新步驟則會使熵值增加。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章