向量直方图VFH,用于机器人局部壁障(python)

原理就不讲了

由于要用到四舍五入,但是python2和3的round函数有问题,所以自定义个函数Round

from math import *
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
import time

img=Image.open("1.png")
white,black=255,0
img = img.point(lambda x: white if x > 200 else black)
img = img.convert('1')
img = np.array(img)
ob=[]
obstacle=[]

for i in range(len(img)):
    temp = np.ones(800)
    for j in range(len(img[0])):
        if img[i][j]==True:
            temp[j]=0
        else:
            temp[j]=1
            obstacle.append([i, j])
        ob.append(temp)

ob=np.asarray(ob)
obstacle=np.asarray(obstacle)

startpoint=[3,3]    #起始点
endpoint=[200,600]  #目标点
def Round(n):       #自定义四舍五入函数
    n=round(n,2)
    xs=(n-floor(n))*10
    if (xs>=5):
        new=round(n)+1
    else:
        new=round(n)

    return new
def caculatebeta(s,e):  #角度计算,一到四象限
    dy=e[1]-s[1]
    dx=e[0]-s[0]
    if dx==0:
        beta=pi/2
    else:
        beta=atan(dy/dx)
        if(dx<0):
            if(dy>0):
                beta=pi-abs(beta)
            else:
                beta=pi+abs(beta)
        else:
            if (dy<0):
                beta=2*pi-abs(beta)
    return beta

def  howmany(c1,c2):   #扇区数目
    n=72
    dif=min([abs(c1-c2),abs(c1-c2-n),abs(c1-c2+n)])
    return dif

#plt.subplot(2,2,1)

#plt.show()


step=10    #步数
f=5
dmax=200   #激光超声波最大范围
smax=18    #扇区最大个数
b=2.5      #参数b
a=1+b*(dmax**2)  #参数a
C=15       #cv值
alpha=np.deg2rad(f)
n=360/f    #划分扇区
threshold=1300
rsafe=5    #机器人自身约束
robot=startpoint
kb=90/f
kt=Round(caculatebeta(robot,endpoint)/alpha)
if(kt==0):
    kt=n

ffff=np.zeros(73)
robottotal=[robot]
plt.figure()
plt.plot(obstacle[:, 0], obstacle[:, 1], '.k')
plt.grid("on")
plt.hold("on")
plt.plot(startpoint[0], startpoint[1], '.b')
plt.hold("on")
plt.title("VFH path planning")
plt.plot(endpoint[0], endpoint[1], '.r')
plt.hold("on")
while (np.linalg.norm(np.array(robot)-np.array(endpoint),2)!=0):
    if (np.linalg.norm(np.array(robot)-np.array(endpoint),2)>step*2):
        i=0
        mag=np.zeros(int(n+3))
        his=np.zeros(int(n+3))

        while(i<len(obstacle)):
            d=np.linalg.norm(obstacle[i,:]-robot)
            if((d<dmax) and (d>rsafe) ):
                beta=caculatebeta(robot,obstacle[i,:])
                rangle=asin(rsafe/d)
                k=int(Round(beta/alpha))

                if(k==0):
                    k=int(n)

                h = np.zeros(int(n + 3))
                if((5*(k)>np.rad2deg(beta)-np.rad2deg(rangle)) and (5*(k)<np.rad2deg(beta)+np.rad2deg(rangle))):
                    h[int(k)]=1
                else:
                    h[int(k)]=0

                m=(C**2)*(a-b*(d**2))
                mag[k]=max(mag[k],m*h[k])
                i=i+1
            else:
                i=i+1

        his=mag
        j=1
        q=1
        c = np.zeros(int(n))
        while(q<=n):
            if(his[q]<threshold):
                kr=q
                while ((q<=n) and (his[q]<threshold)):
                    kl=q
                    q=q+1

                #print(kl,kr)
                if (kl-kr>smax):
                    c[j]=Round(kl-smax/2)
                    c[j+1]=Round(kr+smax/2)
                    j=j+2
                    if(kt>=kr  and kt<=kl):
                        c[j]=kt
                        j=j+1

                elif (kl-kr>smax/5):
                    c[j]=Round((kr+kl)/2.0)

                    j=j+1
            else:
                q=q+1

        g=np.zeros(j)
        how=[]
        for i in range(1,j):
            g[i]=c[i]
            howtemp=5*howmany(g[i],kt)+2*howmany(g[i],kb)+2*howmany(g[i],kb)
            how.append(howtemp)


        ft=how.index(min(how))
        fk=ft+1
        kb=g[int(fk)]

        robot[0]=robot[0]+step*cos(kb*alpha)
        robot[1]=robot[1]+step*sin(kb*alpha)
        robottotal.append(robot)
        print(robot[0],robot[1])

        plt.hold("on")
        plt.plot(robot[0],robot[1],'.b')
        plt.hold("on")

        kt=Round(caculatebeta(robot,endpoint)/alpha)
        if(kt==0):
            kt=n
    else:
        break


robottotal=np.asarray(robottotal)
plt.show()


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值