車載通信與導航(九):python實現街道模型&GPRS通信&D2D通信

寫在前面:沒有進行非常難的代碼編寫,僅僅是算法思想的抽象實現
首先,明確如何建立模型。
這裏我選擇使用python編程語言來實現模型,因爲python編程語言相較於其他編程語言,更適合進行數據運算,也更方便進行圖形化演示。
先在excel中建立起街道模型,並形成二維矩陣作爲地圖。這裏我選擇的是64x64的二維矩陣,並模仿背景道路圖設計的地圖。
在這裏插入圖片描述
其中綠色代表綠地,白色代表樓房,紅色代表街道,黃色代表固定信號站。這裏建議在構建道路的時候,選擇使用一格寬度作爲道路抽象模型,而非其他寬度作爲道路模型,因爲在車輛運行時牽扯到變道問題。
然後,在代碼中保存二維矩陣作爲地圖,並在窗口函數中進行調用,以實現窗口化展示結果。

self.top=tkinter.Tk()
self.top.title("道路模型")  # 標題
self.top.resizable(0, 0)  # 大小可調性
self.top.geometry('900x640')  # 大小
for i in range(64):
    for j in range(64):
        if map[i][j]==0:
            self.l = tkinter.Label(self.top, text=(chr(9608)), fg='white',font=('黑體',6))
            self.l.place(x=i*10,y=j*10)
        elif map[i][j]==1:
            self.l = tkinter.Label(self.top, text=(chr(9608)), fg='green',font=('黑體',6))
            self.l.place(x=i * 10, y=j * 10)
        elif map[i][j]==2:
            self.l = tkinter.Label(self.top, text=(chr(9608)), fg='orange',font=('黑體',6))
            self.l.place(x=i * 10, y=j * 10)
        else :
            self.l = tkinter.Label(self.top, text=(chr(9608)), fg='gray',font=('黑體',6))
            self.l.place(x=i * 10, y=j * 10)

運行結果如下:
在這裏插入圖片描述
可以看到,基本上已經有了一個街道模型的感覺。
然後,設立car類,並設計運行函數,能夠保證車輛在道路上運行。

def run(self):
    num=0
    axx=[]
    ayy=[]
    if self.x==0:
        self.x = 32
        self.y = 32
        self.px = self.x
        self.px = self.y
        s=r.randint(0,3)
        if s==0:
            self.y=self.y-1
        elif s==1:
            self.y=self.y+1
        elif s==2:
            self.x=self.x-1
        else:
            self.x=self.x+1
    elif self.x==63:
        self.x = 32
        self.y = 32
        self.px = self.x
        self.px = self.y
        s=r.randint(0,3)
        if s==0:
            self.y=self.y-1
        elif s==1:
            self.y=self.y+1
        elif s==2:
            self.x=self.x-1
        else:
            self.x=self.x+1
    elif self.y==0:
        self.x = 32
        self.y = 32
        self.px = self.x
        self.px = self.y
        s=r.randint(0,3)
        if s==0:
            self.y=self.y-1
        elif s==1:
            self.y=self.y+1
        elif s==2:
            self.x=self.x-1
        else:
            self.x=self.x+1
    elif self.y==63:
        self.x = 32
        self.y = 32
        self.px = self.x
        self.px = self.y
        s=r.randint(0,3)
        if s==0:
            self.y=self.y-1
        elif s==1:
            self.y=self.y+1
        elif s==2:
            self.x=self.x-1
        else:
            self.x=self.x+1
    else:
        if map[self.x][self.y]==map[self.x-1][self.y] and self.x-1!=self.px:
            num=num+1
            axx.append(self.x-1)
            ayy.append(self.y)
        if map[self.x][self.y]==map[self.x+1][self.y] and self.x+1!=self.px:
            num=num+1
            axx.append(self.x+1)
            ayy.append(self.y)
        if map[self.x][self.y]==map[self.x][self.y-1] and self.y-1!=self.py:
            num=num+1
            axx.append(self.x)
            ayy.append(self.y-1)
        if map[self.x][self.y]==map[self.x][self.y+1] and self.y+1!=self.py:
            num=num+1
            axx.append(self.x)
            ayy.append(self.y+1)
        self.px=self.x
        self.py=self.y
        n=r.randint(0,num-1)
        self.x=axx[n]
        self.y=ayy[n]

由此,實現了車輛的前進一步以及隨即轉向,然後只需要生成一定量的車輛,並通過while函數維持每隔一定時間調用一次run函數即可。

def make(self):
    if self.flag==0:
        self.flag=1
        self.a=car('001')
        self.b=car('002')
        self.c=car('003')
    else:
        self.flag=1
    self.l = tkinter.Label(self.top, text=(chr(9608)), fg='red',font=('黑體',6))
    self.l.place(x=self.a.x * 10, y=self.a.y * 10)
    self.l = tkinter.Label(self.top, text=(chr(9608)), fg='blue',font=('黑體',6))
    self.l.place(x=self.b.x * 10, y=self.b.y * 10)
    self.l = tkinter.Label(self.top, text=(chr(9608)), fg='purple',font=('黑體',6))
    self.l.place(x=self.c.x * 10, y=self.c.y * 10)
    self.top.update()
    while self.flag==1:
        self.carr()
        t.sleep(0.5)

最終可得到如下結果:
在這裏插入圖片描述
一共有三輛車,其中紅色的爲車a,藍色爲車b,紫色爲車c。
然後解決通信問題。首先是通過GPS實現的簡單直接通信,即發送方將信息發送到GPS衛星,衛星保持一個列表存儲車輛實時位置,並再將信息發送給接收方。

def sen1(self):
    sta=self.c1.get()
    aim=self.c2.get()
    self.n=2
    if sta==aim:
        print('error')
    else:
        if sta=='a':
            message=self.a.send()
        elif sta=='b':
            message=self.b.send()
        else:
            message=self.c.send()

        if aim=='a':
            self.a.reciv(message)
        elif aim=='b':
            self.b.reciv(message)
        else:
            self.c.reciv(message)

        self.l = tkinter.Label(self.top, text=('message:'+str(message)), fg='black', font=('黑體', 15))
        self.l.place(relx=0.75,rely=0.8)
        self.l = tkinter.Label(self.top, text=('num:'+str(self.n)), fg='black', font=('黑體', 15))
        self.l.place(relx=0.75,rely=0.9)

然後是GPSR通信,GPSR通信是發送方先發送信息和接收方所在的區域,然後通過貪心選擇和D2D多跳實現數據的傳輸。
這裏我定義了很多的中間固定信號站作爲多跳節點,然後每個中間固定信號站有一定的信號範圍,在接受到傳輸信號後,查看自己的信號範圍內是否有目標節點,有則直接進行傳輸,否則將會通過貪心選擇選擇範圍內最接近目標節點的下一站點,或者隨機選擇一個站點(無最近)。代碼實現如下:

def search(self,aax,aay,aim):
    lx=0
    ly=0
    ax=aax
    ay=aay
    self.n=0
    for o in range(99):
        le=9999
        print(o,ax,ay)
        self.n=self.n+1
        for i in range(ax-6,ax+6):
            if i>=0 and i<64:
                for j in range(ay-6,ay+6):
                    if j>=0 and j<64:
                        if aim.x==i and aim.y==j:
                            return self.n
                        if map[i][j]==2 and i!=ax and j!=ay:
                            if le>=int((aim.x-i)*(aim.x-i)+(aim.y-j)*(aim.y-j)):
                                le=int((aim.x-i)*(aim.x-i)+(aim.y-j)*(aim.y-j))
                                lx=i
                                ly=j
        ax=lx
        ay=ly

這裏我原本打算使用遞歸,後來在實驗中發現如果使用遞歸可能會出現內存錯誤,故選擇循環來代替遞歸,並設置了最大遞歸深度
然後只需要對發送方進行處理,並調用search函數即可。

def sen2(self):
    sta=self.c1.get()
    aim=self.c2.get()
    self.n=0
    if sta==aim:
        print('error')
    else:
        if sta=='a':
            message=self.a.send()
            if aim == 'a':
                try:
                    self.n=self.search(self.a.x,self.a.y,self.a)
                except:
                    self.n=-1
                self.a.reciv(message)
            elif aim == 'b':
                try:
                    self.n=self.search(self.a.x,self.a.y,self.b)
                except:
                    self.n=-1
                self.b.reciv(message)
            else:
                try:
                    self.n=self.search(self.a.x,self.a.y,self.c)
                except:
                    self.n=-1
                self.c.reciv(message)
        elif sta=='b':
            message=self.b.send()
            if aim == 'a':
                try:
                    self.n=self.search(self.a.x,self.a.y,self.a)
                except:
                    self.n=-1
                self.a.reciv(message)
            elif aim == 'b':
                try:
                    self.n=self.search(self.a.x,self.a.y,self.b)
                except:
                    self.n=-1
                self.b.reciv(message)
            else:
                try:
                    self.n=self.search(self.a.x,self.a.y,self.c)
                except:
                    self.n=-1
                self.c.reciv(message)
        else:
            message=self.c.send()
            if aim == 'a':
                try:
                    self.n=self.search(self.a.x,self.a.y,self.a)
                except:
                    self.n=-1
                self.a.reciv(message)
            elif aim == 'b':
                try:
                    self.n=self.search(self.a.x,self.a.y,self.b)
                except:
                    self.n=-1
                self.b.reciv(message)
            else:
                try:
                    self.n=self.search(self.a.x,self.a.y,self.c)
                except:
                    self.n=-1
                self.c.reciv(message)

        self.l = tkinter.Label(self.top, text=('message:'+str(message)), fg='black', font=('黑體', 15))
        self.l.place(relx=0.75,rely=0.8)
        self.l = tkinter.Label(self.top, text=('num:'+str(self.n)), fg='black', font=('黑體', 15))
        self.l.place(relx=0.75,rely=0.9)

通過一個變量存儲路徑中的節點數目,並在後臺打印每個節點的座標值。結果如下:
在這裏插入圖片描述
繪製在圖中即爲:
在這裏插入圖片描述

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