2

我正在尝试在 Matlab 中使用阻力对弹丸运动进行建模。一切都很完美......除了我不知道如何让它在“子弹”击中地面时停止。

我最初尝试了一个迭代循环,定义一个数据数组,并在 y 值为负时清空该数组的单元格......不幸的是,ode 求解器不太喜欢这样。

这是我的代码

      function [ time , x_position , y_position ] = shell_flight_simulator(m,D,Ve,Cd,ElAng)

rho=1.2; % kg/m^3
g=9.84; % acceleration due to gravity
A = pi.*(D./2).^2; % m^2, shells cross-sectional area (area of circle)

    function [lookfor,stop,direction] = linevent(t,y);
        % stop projectile when it hits the ground
        lookfor = y(1); %Sets this to 0
        stop = 1; %Stop when event is located
        direction = -1; %Specify downward direction

        options = odeset('Events',@event_function); % allows me to stop integration at an event
        function fvec = projectile_forces(x,y)
            vx=y(2);
            vy=y(4);
            v=sqrt(vx^2+vy^2);

            Fd=1/2 * rho * v^2 * Cd * A;

            fvec(1) = y(2);
            fvec(2) = -Fd*vx/v/m;
            fvec(3) = y(4);
            fvec(4) = -g -Fd*vy/v/m;
            fvec=fvec.';
        end

        tspan=[0, 90]; % time interval of interest

        y0(1)=0;   % initial x position
        y0(2)=Ve*cos(ElAng); % vx
        y0(3)=0;   % initial y position
        y0(4)=Ve*sin(ElAng); % vy

        % using matlab solver
        [t,ysol] = ode45(@projectile_forces, tspan, y0);
    end
end
x =  ysol(:,1);
vx = ysol(:,2);
y =  ysol(:,3);
vy = ysol(:,4);


plot(x,y, 'r-');
xlabel('X Position (m)');
ylabel('Y Position (m)');
title ('Position Over Time');

end

我认为这会在 y=0 时定义一个事件并停止射弹,但它什么也没做。我究竟做错了什么?

4

1 回答 1

2

当试图找到 ODE 的解决方案达到某个级别的时间时,您应该使用事件函数 - 请参阅BALLODE演示以获取当解决方案的组件之一达到 0 时停止解决方案过程的示例。

于 2012-12-07T04:57:16.787 回答