0


Python 三维无预测拦截机动目标的实现

  • 作者没实现的 - 作者没能做出一个视频,都是以照片形式保存的- 我们考虑的导弹完全没有智能,只知道开最大马力向前冲- 我们的导弹没有预测功能- 我们的飞机不会调整加速度

  • 作者实现的 - 导弹和目标 受气动阻力f=-kv 重力 G=-mg - 导弹只能在一定范围内追踪目标- 导弹每隔0.3秒搜索一次目标,并确定追踪目标- 导弹加速需要燃料,导弹的燃料有上限

  • 作者相信的 - 一定可以很快完善这些问题- 有预测拦截正在学正在学

  • 好习惯,讲问题先上效果图

  • 提示,你要先在同一文件夹下新建一个 0 文件夹

  • 好习惯,讲问题先上源码

import numpy as np
import matplotlib.pyplot as plt
import scipy as sp
import random
from matplotlib.animation import ArtistAnimation
import matplotlib
import xlsxwriter as xls
import xlrd as xl

matplotlib.rcParams["font.sans-serif"] = ["SimHei"]
matplotlib.rcParams["axes.unicode_minus"] = False
frames = []
Missile = [0 for i in range(3)]
Target =  [0 for i in range(3)]
dt = 0.1
time = 0

#阻力 f = -kv
#重力 f = g
class missile():
    global Target
    global Missile
    global get
    
    def __init__(self,location,verb,acce,dn=-1,road=0,oil=2000,acce_max=40):
        self.location = location
        self.verb = verb
        self.acce = acce
        self.dn = dn
        self.road = road
        self.oil = oil
        self.acce_max = acce_max

    def find_target(self,Target):
        scale = 100000
        acce_max = self.acce_max
        x = self.location[0]
        y = self.location[1]
        z = self.location[2]
        L = [x,y,z]
        
        if self.dn == -1:
            flag = 0
            for i in Target:
                if (i.dn == -1)&(sum([(L[i]-self.location[i])**2 for i in range(len(L))])<scale**2):
                    self.dn = get
                    i.dn = get
                    flag = 1
                    target_dis = [-self.location[0] + i.location[0],
                                 -self.location[1] + i.location[1],
                                 -self.location[2] + i.location[2]]
                    k = sum([i**2 for i in target_dis])**0.5
                    target_dis = [j/k for j in target_dis]                    
                    self.acce = np.array([acce_max*i for i in target_dis])
                    self.acce -= np.array([0,0,9.8])
                    self.acce -= 0.02 * self.verb
                    break
                        
            if not flag:
                 i = random.choice(Target)
                 self.dn = i.dn
                 target_dis = [-self.location[0] + i.location[0],
                               -self.location[1] + i.location[1],
                               -self.location[2] + i.location[2]]
                 k = sum([i**2 for i in target_dis])**0.5
                 target_dis = [j/k for j in target_dis]                    
                 self.acce = np.array([acce_max*i for i in target_dis])
                 self.acce -= np.array([0,0,9.8])
                 self.acce -= 0.02 * self.verb
        else:
            for i in Target:
                if i.dn == self.dn:
                    target_dis = [-self.location[0] + i.location[0],
                                  -self.location[1] + i.location[1],
                                  -self.location[2] + i.location[2]]
                    k = sum([i**2 for i in target_dis])**0.5
                    target_dis = [j/k for j in target_dis]                    
                    self.acce = np.array([acce_max*i for i in target_dis])
                    self.acce -= np.array([0,0,9.8])
                    self.acce -= 0.02 * self.verb
                    break
                    

    def self_check(self,Target):
        flag = 0
        for i in Target:
            if i.dn == self.dn:
                flag = 1
                break
            
        if not flag:
            self.dn = -1
            

    def fire(self,Target):
        least_dis = 50
        i = -2
        for j in Target:
            if j.dn == self.dn:
                i = Target.index(j)
                break
        x = Target[i].location[0]
        y = Target[i].location[1]
        z = Target[i].location[2]

        if (x-self.location[0])**2+\
           (y-self.location[1])**2+\
           (z-self.location[2])**2 <= least_dis**2:
            Target.pop(i)
            print("strike!")
            Missile.remove(self)

    def run(self):
        global dt
        self.location += (self.verb * dt + 0.5 * self.acce * dt**2.0)
        self.verb = self.verb + dt * self.acce

    def count(self):
        oil_consumption = 0.1
        self.oil -= oil_consumption * sum([i**2 for i in self.acce])**0.5
        if self.oil <= 0:
            self.acce_max = 0
            print("No fuel")

class target():

    def __init__(self,location,verb,acce,dn=-1):
        self.location = location
        self.verb = verb
        self.acce = acce
        self.dn = dn

    def run(self):
        global dt
        self.location += (self.verb * dt + 0.5 * self.acce * dt**2.0)
        self.verb = self.verb + dt * self.acce        
        self.acce -= np.array([0,0,9.8])
        self.acce -= 0.02 * self.verb

def draw():
    global Target
    global Missile
    global time

    fig = plt.figure()
    ax = fig.add_subplot(1,1,1,projection="3d")
    
    Tx = [i.location[0] for i in Target]
    Ty = [i.location[1] for i in Target]
    Tz = [i.location[2] for i in Target]
    Mx = [i.location[0] for i in Missile]
    My = [i.location[1] for i in Missile]
    Mz = [i.location[2] for i in Missile]

    plt.title(str(time)+"  "+str([round(i,2) for i in Mx]))
    plt.xlabel(str([round(i,2) for i in Tx]))
    ax.scatter(Tx,Ty,Tz,s=5,c="r",label="Target")
    ax.scatter(Mx,My,Mz,s=5,c="b",label="Missile")
    plt.pause(1)
    plt.savefig("0//"+str(time)+".jpg")
    plt.close()

if __name__ == "__main__":

    
    missile1 = missile(np.array([0.,0.,0.]),np.array([0.,0.,0.]),np.array([0.,0.,0.]))
    missile2 = missile(np.array([0.,0.,0.]),np.array([0.,0.,0.]),np.array([0.,0.,0.]))
    missile3 = missile(np.array([0.,0.,0.]),np.array([0.,0.,0.]),np.array([0.,0.,0.]))
    missile4 = missile(np.array([0.,0.,0.]),np.array([0.,0.,0.]),np.array([0.,0.,0.]))
    missile5 = missile(np.array([0.,0.,0.]),np.array([0.,0.,0.]),np.array([0.,0.,0.]))
    missile6 = missile(np.array([0.,0.,0.]),np.array([0.,0.,0.]),np.array([0.,0.,0.]))
    
    Missile = [missile1,missile2,missile3,missile4,missile5,missile6]
    #Missile = [missile1,missile2,missile3]

    target1 = target(np.array([500.,100.,200.]),np.array([30.,-1.,1.]),np.array([10.,5.,3.]))
    target2 = target(np.array([200.,100.,100.]),np.array([20.,-2.,-1.]),np.array([7.,10.,1.]))
    target3 = target(np.array([100.,500.,200.]),np.array([10.,-3.,0.]),np.array([2.,2.,12.]))
    
    Target = [target1,target2,target3]

    time1 = 0
    get = 0
    while Target and (time < 200):
        for m in Missile:
            get += 1
            if not (time1%3):
                m.self_check(Target)
                m.find_target(Target)
            m.count()
            m.run()
            m.fire(Target)
            
        for t in Target:
            t.run()
        draw()
        time += dt
        time1 += 1
  • 主要用到的编码思想也就是一个面向对象的编程
  • 主要用的库是 Numpy - 为什么用Numpy呢? - 操作很简单,相同位置的可以直接相加- 对于大量数据算得更快
  • 警告 - 你应该调整飞机或者导弹的飞行参数来使得更快得拦截
  • 参数解释
        self.location = location
        self.verb = verb
        self.acce = acce
  • location是一个一维三项的array数组,数组的类型应该被设定为float

  • verb acce 同上

  • scale 导弹扫描范围

        scale = 100000
  • oil 和 acce_max 油量和导弹最大加速度
  • oil_consumption 油耗 油耗量/加速度

本文转载自: https://blog.csdn.net/Chandler_river/article/details/127148914
版权归原作者 River Chandler 所有, 如有侵权,请联系我们删除。

“Python 三维无预测拦截机动目标的实现”的评论:

还没有评论