掃地機器人的模擬程序 (3)

尋路模塊 (1)

終於要挑戰尋路模塊,雖然我是在重複造輪子,但看一下別人的輪子怎麼造也是很重要的,因此
在這以前首先搜索下,看看有什麼現成的思路和代碼,收穫以下:html

兩種尋路邏輯

有兩種尋路邏輯, 隨機碰撞和路徑規劃,考慮到:算法

a. 隨機碰撞彷佛須要很多經驗/實驗數據才能達到不錯的效果,我缺經驗/數據呢
b. 如今我擁有一個接近於理想環境的狀況,更便於路徑規劃
c. 隨機碰撞獲得的路徑不漂亮,搞很差還漏了邊邊角角,不符合個人美學價值觀

因此決定用路徑規劃iphone

一些路徑規劃的方法

這篇文章介紹了一些路徑規劃的方法學習

a. 人工智能:原本是想用辦法來作的,畢竟算是用過matlab的人(但忘光光了),但後來發現學習成本有點高,就放棄了……
b. 人工勢場法:看上去也不簡單,也放棄……
c. 柵格法:說明了地圖形態(含障礙物),但並無說明具體走法,有些懷疑小編或者做者的邏輯能力。話說個人地圖就是柵格形式(用點/座標來表示格子)
d. 模板模型法:很容易理解,就是有幾種走法,按狀況調用。就決定用這個辦法了

決定算法

按上面模板模型法的思路,去搜關鍵字(Complete coverage path planning等),看了2篇論文和一些科普文章
這篇文章引發了個人注意,這篇論文說的是基於A*算法來實現徹底路徑覆蓋,裏面還有兩個走法,分別是U-turn Search和 Internal Spiral Search,形象地說就是U型走法和回形走法
從文章結論看,U型走法配合A*算法的效果彷佛不錯(重複率低),那麼我也按這個辦法來吧
具體來講就是U型走法清掃一次,而後經過A*算法走到最近的未清潔點,如此反覆直到全部點都被清潔/走過
雖然這不是全局最優解,但仍是先以實現爲目標努力吧測試

實現算法 (U型走法)

A*算法稍微有些複雜,以後再開篇文章寫,我先寫U型走法的部分,思路:人工智能

  1. 須要兩個U型走法,一個朝右,一個朝左,除了朝左右不一樣以外其餘相同
  2. 以U型朝右走法爲例,先嚐試往上下移動,「碰牆」後朝右移動一格,而後掉頭,如此反覆直到沒法往右
  3. 因爲U型走法具備反覆的特性,若是發現下一步要走的點/格子已經走過了,就要停下來

path_finding代碼1,先寫上面3裏提到的判斷方法
篇幅起見,我這裏只寫一個判斷上方格子是否走過的方法:code

def judge_up_passed(self):
    x, y = self.current_coordinate
    up_coordinate = (x, y + 1)
    if up_coordinate in self.path_log:
        return True
    else:
        return False

path_finding代碼2,U型朝右走法:htm

def u_turn_toward_right(self):
    rollback = False
    while True:
        if (self.judge_up_passable() == False) and (self.judge_down_passable() == False) and (
            self.judge_right_passable() == True):
            self.move_right()

        if rollback == False:
            while self.judge_up_passable() == True and self.judge_up_passed() == False:
                self.move_up()
            if self.judge_right_passable() == True and self.judge_right_passed() == False:
                self.move_right()
                rollback = True
            else:
                rollback = True

        if rollback == True:
            while self.judge_down_passable() == True and self.judge_down_passed() == False:
                self.move_down()
            if self.judge_right_passable() == True and self.judge_right_passed() == False:
                self.move_right()
                rollback = False
            else:
                rollback = False
                break

以後在main中添加方法ip

from path_finding import *
    Robot.u_turn_toward_right = u_turn_toward_right
    Robot.u_turn_toward_left = u_turn_toward_left
    Robot.judge_up_passed = judge_up_passed
    Robot.judge_down_passed = judge_down_passed
    Robot.judge_left_passed = judge_left_passed
    Robot.judge_right_passed = judge_right_passed

測試

接着看一下寫的U型走法效果如何,在main中測一下get

...
    robot.u_turn_toward_right()
    print(robot.path_log)
    print(len(robot.path_log))

而後本身按着path_log看一下U型走得如何,按第一篇文章中的地圖,沒有意外的話,應該是82步

相關文章
相關標籤/搜索