Logo Search packages:      
Sourcecode: acm version File versions  Download package

missilec.c

/*
 *  acm : an aerial combat simulator for X
 *  Copyright (C) 1991-1997  Riley Rainey
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; version 2 dated June, 1991.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program;  if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave., Cambridge, MA 02139, USA.
 */

#include <stdio.h>
#include <math.h>

#include "pm.h"

int       mdebug = 0;
extern double calcRho(double alt, double *mach);
extern void trackTarget(craft *);
extern void craftToGround(craft * c, VPoint * p, VPoint * g);
extern void calcGForces(craft *, VPoint *, double);

int
missileCalculations(craft * c)
{
      double    q, rho;
      double    FLift, FDrag, FWeight;
      double    dNorth, dEast, dmag;
      VPoint    F, Fg;

/*
 *  Check for ground impact.  We do this at the beginning to permit us to
 *  kill ground targets.
 */

      if (c->w.z < localAltitude(&c->Sg, &c->w)) {
            q = -c->prevSg.z / (c->Sg.z - c->prevSg.z);
            c->Sg.x = c->prevSg.x + q * (c->Sg.x - c->prevSg.x);
            c->Sg.y = c->prevSg.y + q * (c->Sg.y - c->prevSg.z);
            c->Sg.z = 0.0;
            return 1;
      }

      trackTarget(c);

/*
 *  If we haven't armed the missile, yet.  Decrement the delay timer.
 *  If the FL_BALLISTIC flag is set, we have no target; self-destruct
 *  if the timer expires.
 */

      if (c->armTimer != 0.0) {
            if ((c->armTimer -= deltaT) < 0.0) {
                  if (c->flags & FL_BALLISTIC) {
                        return 1;
                  }
                  c->armTimer = 0.0;
            }
      }

/*
 *  Re-orient the body of the missile towards it's intended target.
 */

      c->prevSg = c->Sg;

      rho = calcRho(METERStoFEET(c->w.z), &q);

/*
 *  Compute the resultant force vector on the missile.
 */

      c->VT = mag(c->Cg);
      q = rho * c->cinfo->wingS * c->VT * c->VT * 0.5;
      FLift = 0.0;
      FDrag = c->cinfo->CDOrigin * q;

#ifdef FLIGHTDEBUG
      if (mdebug) {
            printf("rho = %g, FLift = %g, FDrag = %g\n", rho, FLift, FDrag);
            printf("FThrust = %g\n", c->curThrust);
      }
#endif

      F.x = c->curThrust - FDrag;
      F.y = 0.0;
      F.z = 0.0;

/*
 *  Now calculate changes in position (Sg) and velocity (Cg).
 */

      if ((c->fuel -= fuelUsed(c)) <= 0.0) {
            if (c->curThrust > 0.0)
                  if (mdebug)
                        printf("Missile burnout; velocity = %g fps (%g kts)\n", c->VT,
                                 FPStoKTS(c->VT));
            c->fuel = 0.0;
            c->curThrust = 0.0;
      }

/*
 *  The missile's trihedral matrix is managed by 
 *  trackTarget().
 */

      craftToGround(c, &F, &Fg);
      FWeight = c->cinfo->emptyWeight + c->fuel;
      Fg.z += FWeight;
      calcGForces(c, &Fg, FWeight);

#ifdef FLIGHTDEBUG
      if (mdebug) {
            printf("v = %g kts, Fg = { %g, %g, %g }\n", FPStoKTS(c->VT),
                     Fg.x, Fg.y, Fg.z);
            printf("F = { %g, %g, %g }\n", F.x, F.y, F.z);
      }
#endif

/*
 *  Update the missile's position and velocity.
 */

      dNorth = FEETtoMETERS(c->Cg.x * deltaT + Fg.x / FWeight
                                      * earth_g * halfDeltaTSquared);
      dEast = FEETtoMETERS(c->Cg.y * deltaT + Fg.y / FWeight
                                     * earth_g * halfDeltaTSquared);
      c->w.z -= FEETtoMETERS(c->Cg.z * deltaT + Fg.z / FWeight
                                       * earth_g * halfDeltaTSquared);

      dmag = sqrt(dNorth * dNorth + dEast * dEast);

      DISUpdateWorldCoordinates(&c->w, dNorth / dmag, dEast / dmag, dmag);
      DISWorldCoordinatesToGeocentric(&c->w,
                                                      (dis_world_coordinates *) & c->Sg);
      GenerateWorldToLocalMatrix(&c->w, &c->XYZtoNED);

      c->Cg.x += Fg.x / FWeight * earth_g * deltaT;
      c->Cg.y += Fg.y / FWeight * earth_g * deltaT;
      c->Cg.z += Fg.z / FWeight * earth_g * deltaT;

#ifdef FLIGHTDEBUG
      if (mdebug) {
            printf("Altitude = %g ft\n", METERStoFEET(c->w.z));
            printf("Euler angles { %g, %g, %g }\n", RADtoDEG(c->curRoll),
                     RADtoDEG(c->curPitch), RADtoDEG(c->curHeading));
            printf("Cg = { %g, %g, %g }\n", c->Cg.x, c->Cg.y, c->Cg.z);
            printf("Sg = { %g, %g, %g }\n", c->Sg.x, c->Sg.y, c->Sg.z);
      }
#endif

      return 0;
}

Generated by  Doxygen 1.6.0   Back to index