如何计算火箭?

问题描述 投票:1回答:2

所以我得到了一个3d系统和一些坐标:

  • 起始火箭的坐标(x,y,z)(在地面上)
  • 目标坐标(x,y,z)火箭目标(也在地面上)

我有一些初始化值,如:

  • maximum_velocityZ = 0.5
  • maximum_resVelocityXY = 0.3
  • 重力因子= 9.81

如何计算每个更新帧的飞行速度qazxsw poi?

(velocityX, velocityY and velocityZ)

这段代码是我迄今为止开发的。我相信我走在正确的轨道上。 X和Y似乎或多或少是正确的。只有Velocity Z无法按照我尝试的方式计算。在3D空间中,轨迹看起来并不真实。因此,“不是真的”,我的意思是“根本不现实”......

我很乐意帮忙。谢谢,新年快乐 - 与火箭相匹配 - 当然!

javascript math calculation
2个回答
0
投票

我不知道你的坐标系是什么

  • 平面
  • 像WGS84那样的椭圆体

我的猜测是你的地面是平面的(从你的常数引起,但你的位置暗示其他的东西)...所以我现在坚持这个......你有两个问题:

  1. Newton / D'Alembert物理学 你很奇怪,因为你没有let maximum_velocityZ = 0.5 let maximum_resVelocityXY = 0.3 let gravity_factor = 9.81 let rocketPosition = { x: 3, y: 0, z: 2 } let rocketTarget = { x: 7, y: 5, z: 8 } let rocketVelocity = { x: 0, y: 0, z: 0 } let update = function() { rocketPosition.x += rocketVelocity.x rocketPosition.y += rocketVelocity.y rocketPosition.z += rocketVelocity.z let distanceX = (rocketTarget.x - rocketPosition.x) let distanceY = (rocketTarget.y - rocketPosition.y) let distanceZ = (rocketTarget.z - rocketPosition.z) let factorXY = Math.abs(distanceX / distanceY) rocketVelocity.x = maximum_resVelocityXY / Math.sqrt((1 / factorXY ** 2) + 1) * (distanceX > 0 ? 1 : -1) rocketVelocity.y = maximum_resVelocityXY / Math.sqrt((factorXY ** 2) + 1) * (distanceY > 0 ? 1 : -1) rocketVelocity.z = maximum_velocityZ * distanceZ; rocketVelocity.z /= gravity_factor; console.log("x:", Math.round(rocketPosition.x), "y:", Math.round(rocketPosition.y), "z:", Math.round(rocketPosition.z)) } setInterval(update, 300)乘法,所以只有你的更新是1赫兹它才有效。看看这个: dt 你不需要速度限制器,因为空气摩擦会为你做,你应该用加速度驱动...或者如果你想要考虑质量变化也要强制。 然而,当您使用地面/地面时,我假设大气飞行而不是牛顿飞行,因此在这种情况下,您需要处理航向控制而不是通过加速而是通过转动积分速度。主推进器仍应作为加速度处理。 在您的情况下,碰撞是不必要的(除非您的地面不是平面或沿途有障碍物)。
  2. 火箭引导系统 我建议使用3状态(马尔可夫模型)火箭控制。 发射 首先将火箭升高到安全高度,以避开障碍物,节省燃料并最大限度地提高速度 巡航 前往目标区域(同时仍保持其高度)。只需计算投影在地平面上的航向,并对火箭的航向进行修正以匹配它(仍然平行于地面)。 击中 下降时击中目标。几乎与#2相同,但这次你需要改变高度...... 除此之外,您可以添加策略以避免检测/破坏或障碍等...您还可以从不同的标题做出虚假的方法来保持发射位置隐藏...

这是这种方法的简单C ++示例:

Can't flip direction of ball without messing up gravity

您可能需要稍微调整常量以匹配您的尺寸和游戏需求。正如你所看到的,你可以自定义火箭,非常适合游戏(技术升​​级)。

物理学是直接的Newton / D'Alembert(由于翅膀而转向//--------------------------------------------------------------------------- void vector_one(double *c,double *a) { double l=sqrt((a[0]*a[0])+(a[1]*a[1])+(a[2]*a[2])); if (l>1e-10) l=1.0/l; else l=0.0; c[0]=a[0]*l; c[1]=a[1]*l; c[2]=a[2]*l; } //--------------------------------------------------------------------------- // Z=0 plane is ground, Z+ is up const double g=9.81; // [m/s^2] Earth's gravity const double acc0=20.0; // [m/s^2] rocket main thruster acceleration const double kv2 =0.002; // [-] rocket air friction coeff (speed limiter) const double alt0=50.0; // [m] rocket safe altitude const double dis0=100.0; // [m] rocket safe distance to target const double dis1= 10.0; // [m] rocket explosion distance to target const double dang0=375.0*M_PI/180.0;// [rad/s] rocket turn speed per yaw/roll/pitch // Rocket double dst[3]={+90.0,-50.0,0.0}; // [m] target position double pos[3]={-100.0,200.0,0.0}; // [m] rocket position double vel[3]={ 0.0, 0.0,0.0}; // [m/s] rocket velocity double acc[3]={ 0.0, 0.0,0.0}; // [m/s^2] rocket acceleration enum{ _state_none=0, _state_launch, // rise to alt0 _state_cruise, // get near target but maintain alt0 _state_hit, // descend and hit }; int state=_state_launch; void update(double dt) // update rocket after dt [sec] has passed { int i; double v,a,hdg[3],tar[3]; // guiding system if (state==_state_none) { for (i=0;i<3;i++) vel[i]=0.0; for (i=0;i<3;i++) acc[i]=0.0; return; } if (state==_state_launch) { // init heading to Up for (i=0;i<3;i++) hdg[i]=0.0; hdg[2]=1.0; if (pos[2]>=alt0) state=_state_cruise; } v=sqrt((vel[0]*vel[0])+(vel[1]*vel[1])+(vel[2]*vel[2]));// |vel| if ((state==_state_cruise)||(state==_state_hit)) { vector_one(hdg,vel); // heading for (i=0;i<3;i++) tar[i]=dst[i]-pos[i]; // to target a=sqrt((tar[0]*tar[0])+(tar[1]*tar[1])+(tar[2]*tar[2])); // distance to target if (state==_state_cruise) { tar[2]=0; // no altitude change if (a<=dis0) state=_state_hit; } else{ if (a<=dis1) state=_state_none; // here you shoul add exlosion code } vector_one(tar,tar); // a = angle between hdg and tar [rad] for (a=0.0,i=0;i<3;i++) a+=hdg[i]*tar[i]; a=fabs(acos(a)); // approximate turn up to dang0 if (a>1e-10) a=dt*dang0/a; else a=0.0; for (i=0;i<3;i++) hdg[i]=hdg[i]+a*(tar[i]-hdg[i]); vector_one(hdg,hdg); // new heading for (i=0;i<3;i++) vel[i]=v*hdg[i]; // new vel } // physics for (i=0;i<3;i++) acc[i] =-kv2*vel[i]*v; // air friction (k*|vel|^2) for (i=0;i<3;i++) acc[i]+=hdg[i]*acc0; // rocket thrust acc[2]-=g; // gravity // Newton/D'Alembert simulation for (i=0;i<3;i++) vel[i]+=acc[i]*dt; for (i=0;i<3;i++) pos[i]+=vel[i]*dt; } //--------------------------------------------------------------------------- ),导向系统如上所述工作。在第一状态,火箭刚刚上升到vel然后它试图转向目标与alt0转速同时保持高度,当比dang0更接近它开始下降。如果比dis0更近,火箭应该爆炸......

这里预览(顶视图):

dis1

白线是从地面划线以验证火箭的高度......火箭是蓝色,目标是红色。

转动的数学是这样的:

rocket flight

所以我只是缩放turn math以大致匹配tar-hdg并将其添加到原始的dang0*dt。现在新的标题被转向hdg的目标,所以我将它归一化到单位大小并重新计算速度到这个新的方向(因为机翼正在转动速度而不是加速)

小心单位

使用的所有单位必须兼容我使用SI。你的dang0*dt常数表示相同,但​​你的位置和目标值是没有意义的,如果在米...如果目标只有几米远,为什么射击火箭?此外,值表明您的坐标要么不是caressian,要么是地面不是平面/平面。值也表明整数希望你有浮动/双打......


0
投票

轨迹将是抛物线。这里的基本方程很好地解释了:9.81

3D问题(x,y,z)可以很容易地转换为2D(单平面)问题(水平,垂直),对于方程然后回到3D以解决问题。

© www.soinside.com 2019 - 2024. All rights reserved.