如何计算火箭? [英] How to calculate rocket?

查看:110
本文介绍了如何计算火箭?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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




  • 开始坐标(x,y,z一枚火箭(在地面上)

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






我得到了一些初始值,如:




  • maximum_velocityZ = 0.5

  • maximum_resVelocityXY = 0.3

  • gravity factor = 9.81






如何计算每个更新帧的飞行速度(velocityX,velocityY和velocityZ)



  let maximum_velocityZ = 0.5let maximum_resVelocityXY = 0.3let gravity_factor = 9.81let rocketPosition = {x:3,y:0,z:2}让rocketTarget = {x:7,y:5,z:8}让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)让distanceY =(rocketTarget.y  -  rocketPosition.y)让distanceZ =(rocketTarget.z  -  rocketPosition.z)让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(更新,300) 



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



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

解决方案

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




  • plane

  • sphere

  • 这样的椭圆体WGS84



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


  1. Newton / D'Alembert物理



    你很奇怪,因为你没有 dt 乘法,所以只有当你的更新是1时它才有用赫兹。看看这个:






    • 白线是从地面开始的线路,用于验证火箭的高度。 ..火箭是蓝色,目标是红色。



      转向数学是这样的:





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



      谨防单位



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


      So I got a 3d system and some coordinates:

      • Start coordinates (x, y, z) of a rocket (on the ground)
      • Target coordinates (x, y, z) of the rockets target (also on the ground)

      I got some initialize values like:

      • maximum_velocityZ = 0.5
      • maximum_resVelocityXY = 0.3
      • gravity factor = 9.81

      How can I calculate the flight velocitys (velocityX, velocityY and velocityZ) for every update frame?

      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)

      This code is what I've developed so far. I'm sure I'm on the right track. X and Y seem to be more or less right. Only the Velocity Z can't be calculated the way I tried. In 3D space the trajectory doesn't really look realistic. So by "not really" I mean "not realistic at all"...

      I would be happy for help. Thanks and a happy new year - matching to the rocket - of course!

      解决方案

      I do not know what is you coordinate system

      • plane
      • sphere
      • ellipsoid like WGS84

      My guess is your ground is planar (induced from your constants however your positions suggest something else)... so I will stick with that for now... You got 2 problems:

      1. Newton/D'Alembert physics

        Yours is weird as you got no dt multiplication so it works only if your update is 1 Hz. take a look at this:

        you do not need speed limiter as air friction will do it for you and you should drive with accelerations ... or Force if you want to account for mass changes too.

        However as you are working with ground/ground then I assume atmospheric flight instead of Newtonian so in such case you need to handle the heading control not by acceleration but by turning the integrated velocity. The main thruster should still be handled as acceleration.

        The collisions are not necessary in your case (unless your ground is not planar or have obstacles along the way).

      2. Rocket guiding system

        I suggest to use 3 state (Markovov model) rocket control.

        1. launch

          Rise the rocket to safe altitude first to avoid obstacles, conserve fuel and maximize speed

        2. cruise

          Travel to the target area (while still keep its altitude). Simply compute heading projected on the ground plane and apply correction to the heading of the rocket to match it (still going parallel to ground).

        3. hit

          Hit the target while descending. Almost the same as #2 but this time you need to change altitude too...


        On top of these you can add strategies to avoid detection/destruction or obstacles etc ... You can also make a fake approach from different heading to keep the launch position hidden ...

      Here a simple C++ example of this approach:

      //---------------------------------------------------------------------------
      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;
          }
      //---------------------------------------------------------------------------
      

      You might need to tweak the constants a bit to match your sizes and game needs. As you can see you can customize the rocket quite a lot which is ideal for game (tech upgrades).

      The physics is straight forward Newton/D'Alembert (apart the vel turning due to wings) and the guiding system works as described above. In first state the rocket just rise to alt0 then it try to turn towards target with dang0 turn speed while maintaining altitude and when closer than dis0 it start also descending. If closer than dis1 the rocket should explode ...

      Here preview (top view):

      The white line is line from ground to verify the altitude of rocket ... Rocket is Blue and target is Red.

      The turning math is like this:

      so I just scaled tar-hdg to approximately match dang0*dt and add that to original hdg. now the new heading is turned towards target by up to dang0*dt so just I normalize it back to unit size and recompute velocity to this new direction (as wings are turning velocity instead of accelerating)

      Beware of the units

      All the units used must be compatible I am using SI. Your 9.81 constant suggest the same but your position and target values makes no sense if in meters ... Why shoot rocket if target is just few meters away? Also the values suggest your coordinates are either not cartessian or ground is not planar/flat. Also the values suggest integers hope you have floats/doubles instead...

      这篇关于如何计算火箭?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆