]> git.mxchange.org Git - flightgear.git/blob - src/AIModel/AIBallistic.cxx
ddac65cdf8d3ce96e79cb2c14987d40e9934de19
[flightgear.git] / src / AIModel / AIBallistic.cxx
1 // FGAIBallistic - FGAIBase-derived class creates a ballistic object
2 //
3 // Written by David Culp, started November 2003.
4 // - davidculp2@comcast.net
5 //
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License as
8 // published by the Free Software Foundation; either version 2 of the
9 // License, or (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful, but
12 // WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20 #ifdef HAVE_CONFIG_H
21 #  include <config.h>
22 #endif
23
24 #include <simgear/math/point3d.hxx>
25 #include <math.h>
26
27 #include "AIBallistic.hxx"
28
29
30 FGAIBallistic::FGAIBallistic(FGAIManager* mgr) {
31     manager = mgr;
32     _type_str = "ballistic";
33     _otype = otBallistic;
34     drag_area = 0.007;
35     life_timer = 0.0;
36         gravity = 32;
37 //      buoyancy = 64;
38         }
39
40 FGAIBallistic::~FGAIBallistic() {
41 }
42
43
44 bool FGAIBallistic::init() {
45    FGAIBase::init();
46    aero_stabilized = true;
47    hdg = azimuth;
48    pitch = elevation;
49    return true;
50 }
51
52 void FGAIBallistic::bind() {
53 //    FGAIBase::bind();
54    props->tie("sim/time/elapsed-sec", SGRawValuePointer<double>(&(this->life_timer)));
55 }
56
57 void FGAIBallistic::unbind() {
58 //    FGAIBase::unbind();
59    props->untie("sim/time/elapsed-sec");
60 }
61
62 void FGAIBallistic::update(double dt) {
63    FGAIBase::update(dt);
64    Run(dt);
65    Transform();
66 }
67
68
69 void FGAIBallistic::setAzimuth(double az) {
70    hdg = azimuth = az;
71 }
72
73
74 void FGAIBallistic::setElevation(double el) {
75    pitch = elevation = el;
76 }
77
78
79 void FGAIBallistic::setStabilization(bool val) {
80    aero_stabilized = val;
81 }
82
83 void FGAIBallistic::setDragArea(double a) {
84    drag_area = a;
85 }
86
87 void FGAIBallistic::setLife(double seconds) {
88    life = seconds;
89 }
90
91 void FGAIBallistic::setBuoyancy(double fpss) {
92    buoyancy = fpss;
93 }
94
95 void FGAIBallistic::setWind_from_east(double fps) {
96    wind_from_east = fps;
97 }
98
99 void FGAIBallistic::setWind_from_north(double fps) {
100    wind_from_north = fps;
101 }
102
103 void FGAIBallistic::setWind(bool val) {
104    wind = val;
105 }
106 void FGAIBallistic::Run(double dt) {
107
108    life_timer += dt;
109    if (life_timer > life) setDie(true); 
110
111    double speed_north_deg_sec;
112    double speed_east_deg_sec;
113    double wind_speed_from_north_deg_sec;
114    double wind_speed_from_east_deg_sec;
115       
116    // the two drag calculations below assume sea-level density, 
117    // mass of 0.03 slugs,  drag coeff of 0.295
118    // adjust speed due to drag 
119    speed -= 0.0116918 * drag_area * speed * speed * dt;
120    if ( speed < 0.0 ) speed = 0.0;
121    vs = sin( pitch * SG_DEGREES_TO_RADIANS ) * speed;
122    hs = cos( pitch * SG_DEGREES_TO_RADIANS ) * speed;
123
124    // convert horizontal speed (fps) to degrees per second
125    speed_north_deg_sec = cos(hdg / SG_RADIANS_TO_DEGREES) * hs / ft_per_deg_lat;
126    speed_east_deg_sec  = sin(hdg / SG_RADIANS_TO_DEGREES) * hs / ft_per_deg_lon;
127    
128    // convert wind speed (fps) to degrees per second
129    
130    if (!wind){
131       wind_from_north = 0;
132       wind_from_east = 0;
133           }
134
135    wind_speed_from_north_deg_sec = wind_from_north / ft_per_deg_lat;
136    wind_speed_from_east_deg_sec  = wind_from_east / ft_per_deg_lon;
137    
138  
139    // set new position
140 //   pos.setlat( pos.lat() + (speed_north_deg_sec * dt)  );
141 //   pos.setlon( pos.lon() + (speed_east_deg_sec * dt)  ); 
142  
143  
144    // set new position
145    
146    pos.setlat( pos.lat() + (speed_north_deg_sec - wind_speed_from_north_deg_sec) * dt );
147    pos.setlon( pos.lon() + (speed_east_deg_sec - wind_speed_from_east_deg_sec) * dt ); 
148
149    // adjust vertical speed for acceleration of gravity
150    vs -= (gravity - buoyancy) * dt;
151    
152    // adjust altitude (feet)
153    altitude += vs * dt;
154    pos.setelev(altitude * SG_FEET_TO_METER); 
155
156    // recalculate pitch (velocity vector) if aerostabilized
157    if (aero_stabilized) pitch = atan2( vs, hs ) * SG_RADIANS_TO_DEGREES;
158
159    // recalculate total speed
160    speed = sqrt( vs * vs + hs * hs);
161
162    // set destruction flag if altitude less than sea level -1000
163    if (altitude < -1000.0) setDie(true);
164
165 }