导弹追踪问题

相关资料见
Matlab建模—导弹追踪问题
追及问题真的有那么简单吗?–追及问题的本质
geogebra追及问题
以B站视频那道题的数据为例。
在这里插入图片描述
simucpp目前只支持绘制波形,不支持绘制坐标图,因此打印出导弹的横纵坐标后将打印结果复制到单独的data.csv文件中,并用python画图。绘图代码如下:

import numpy as np
import csv
import zhnplot
filename = 'data.csv'
with open(filename) as f:
    reader = csv.reader(f)
    ans = list(reader)
x, y = [], []
for adata in ans:
    x.append(adata[0])
    y.append(adata[1])
x=np.array(x, dtype=np.float32)
y=np.array(y, dtype=np.float32)
zhnplot.plot(x, y)

其中zhnplot封装matplotlib绘制单个子图

方法一

d x d t = v 2 cos ⁡ θ d y d t = v 2 sin ⁡ θ tan ⁡ θ = v 1 t − y − x \frac{dx}{dt}=v_2\cos\theta \\ \frac{dy}{dt}=v_2\sin\theta \\ \tan\theta=\frac{v_1t-y}{-x} dtdx=v2cosθdtdy=v2sinθtanθ=xv1ty

方法二

d y d x = v 1 t − y − x ∫ − L x 1 + y ′ 2 d x = v 2 t \frac{dy}{dx}=\frac{v_1t-y}{-x} \\ \int_{-L}^x\sqrt{1+y'^2}dx=v_2t dxdy=xv1tyLx1+y2 dx=v2t
上式代入下式得
∫ − L x 1 + y ′ 2 d x = ( y − x y ′ ) v 2 v 1 \int_{-L}^x\sqrt{1+y'^2}dx=(y-xy')\frac{v_2}{v_1} Lx1+y2 dx=(yxy)v1v2
两边同时求导得
1 + y ′ 2 = − v 2 v 1 x y ′ ′ \sqrt{1+y'^2}=-\frac{v_2}{v_1}xy'' 1+y2 =v1v2xy
z = d y d x z=\frac{dy}{dx} z=dxdy,则
d z d x = − v 1 v 2 x 1 + z 2 \frac{dz}{dx}=-\frac{v_1}{v_2x}\sqrt{1+z^2} dxdz=v2xv11+z2

方法三

也是来自B站视频的方法,可以算出时间,但轨迹不知道咋算,而且也不理解为什么可以这样算时间。
v 2 t − v 1 t sin ⁡ θ = L v 1 t − v 2 t sin ⁡ θ = 0 v_2t-v_1t\sin\theta=L \\ v_1t-v_2t\sin\theta=0 v2tv1tsinθ=Lv1tv2tsinθ=0
解得
t = L v 2 − v 1 sin ⁡ θ = L v 2 − v 1 2 v 2 t=\frac{L}{v_2-v_1\sin\theta}=\frac{L}{v_2-\frac{v_1^2}{v_2}} t=v2v1sinθL=v2v2v12L
simucpp代码:

// 导弹追踪问题
#include "simucpp.hpp"
#include <cmath>
int main()
{
    using namespace simucpp;
    using namespace std;
    Simulator sim1, sim2;

    constexpr double v1 = 1;
    constexpr double v2 = 2;
    constexpr double L = 5;

    // 方法一
    MInput *s1shipdist = new MInput(&sim1);  //输出敌舰向y轴正方向移动的距离
    MFcn *s1fcnx = new MFcn(&sim1);  // 输出导弹的速度的x分量
    MFcn *s1fcny = new MFcn(&sim1);  // 输出导弹的速度的y分量
    MFcn *s1divider = new MFcn(&sim1);  // 输出导弹的x坐标的倒数
    MFcn *s1theta = new MFcn(&sim1);  // 输出导弹的角度
    MIntegrator *s1missilex = new MIntegrator(&sim1);  // 输出导弹的x坐标
    MIntegrator *s1missiley = new MIntegrator(&sim1);  // 输出导弹的y坐标
    MSum *sum1 = new MSum(&sim1);  // 输出敌舰y坐标减去导弹的y坐标
    MProduct *s1tan = new MProduct(&sim1);  // 输出导弹的角度的正切值

    s1fcnx->Set_Function([](double u){return v2*cos(u);});
    s1fcny->Set_Function([](double u){return v2*sin(u);});
    s1divider->Set_Function([](double u){return -1/u;});
    s1theta->Set_Function([](double u){return atan(u);});
    s1shipdist->Set_InputFunction([](double t){return v1*t;});
    s1missilex->Set_InitialValue(-L);
    s1missiley->Set_InitialValue(0);

    sim1.connect(s1theta, s1fcnx);
    sim1.connect(s1theta, s1fcny);
    sim1.connect(s1fcnx, s1missilex);
    sim1.connect(s1fcny, s1missiley);
    sim1.connect(s1shipdist, sum1);
    sim1.connect(s1missiley, sum1);
    sum1->Set_InputGain(-1);
    sim1.connect(s1missilex, s1divider);
    sim1.connect(sum1, s1tan);
    sim1.connect(s1divider, s1tan);
    sim1.connect(s1tan, s1theta);

    sim1.Initialize();
    sim1.Set_ShowWave(false);
    double t, missilex, missiley;
    cout.precision(12);
    do {
        sim1.Simulate_OneStep();
        t = sim1.Get_t();
        missilex = s1missilex->Get_OutValue();
        missiley = s1missiley->Get_OutValue();
        // cout << missilex << ", "<< missiley << endl;
    } while (missilex < 0);
    // cout << "t: " << t << endl;

    // 方法二
    MIntegrator *s2missiley = new MIntegrator(&sim2);  // 输出导弹的y坐标
    MIntegrator *s2z = new MIntegrator(&sim2);  // 输出导弹的y分量速度
    MFcn *s2fcn1 = new MFcn(&sim2);  // 输出√(1+z^2)
    MInput *s2in = new MInput(&sim2);  // 输出(v1)(v2x)
    MProduct *s2zd = new MProduct(&sim2);  // 输出导弹的y分量加速度

    sim2.Set_t(-L);  // 方法一的自变量是t,方法二的自变量是x
    s2fcn1->Set_Function([](double u){return sqrt(1+u*u);});
    s2in->Set_InputFunction([](double t){return -v1/v2/t;});

    sim2.connect(s2in, s2zd);
    sim2.connect(s2z, s2fcn1);
    sim2.connect(s2fcn1, s2zd);
    sim2.connect(s2zd, s2z);
    sim2.connect(s2z, s2missiley);

    sim2.Initialize();
    sim2.Set_ShowWave(false);
    double missileyd;
    do {
        sim2.Simulate_OneStep();
        t = sim2.Get_t();
        missileyd = s2z->Get_OutValue();
        missiley = s2missiley->Get_OutValue();
        // cout << t << ", "<< missiley << endl;
    } while (t < 0);

    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值