6 #include "performancedata.hxx"
8 #include <simgear/props/props.hxx>
9 #include "AIAircraft.hxx"
11 // For now, make this a define
12 // Later on, additional class variables can simulate settings such as braking power
13 // also, the performance parameters can be tweaked a little to add some personality
15 #define BRAKE_SETTING 1.6
17 PerformanceData::PerformanceData() :
31 _rollrate = 9.0; // degrees per second
32 _maxbank = 30.0; // passenger friendly bank angle
36 PerformanceData::PerformanceData(PerformanceData* clone) :
37 _acceleration(clone->_acceleration),
38 _deceleration(clone->_deceleration),
39 _climbRate(clone->_climbRate),
40 _descentRate(clone->_descentRate),
41 _vRotate(clone->_vRotate),
42 _vTakeOff(clone->_vTakeOff),
43 _vClimb(clone->_vClimb),
44 _vCruise(clone->_vCruise),
45 _vDescent(clone->_vDescent),
46 _vApproach(clone->_vApproach),
47 _vTouchdown(clone->_vTouchdown),
50 _rollrate = clone->_rollrate;
51 _maxbank = clone->_maxbank;
54 PerformanceData::~PerformanceData()
57 void PerformanceData::initFromProps(SGPropertyNode *db_node)
59 // read the values, using the existing values as defaults
60 _acceleration = db_node->getDoubleValue("acceleration-kts-hour", _acceleration);
61 _deceleration = db_node->getDoubleValue("deceleration-kts-hour", _deceleration);
62 _climbRate = db_node->getDoubleValue("climbrate-fpm", _climbRate);
63 _descentRate = db_node->getDoubleValue("decentrate-fpm", _descentRate);
64 _vRotate = db_node->getDoubleValue("rotate-speed-kts", _vRotate);
65 _vTakeOff = db_node->getDoubleValue("takeoff-speed-kts", _vTakeOff);
66 _vClimb = db_node->getDoubleValue("climb-speed-kts", _vClimb);
67 _vCruise = db_node->getDoubleValue("cruise-speed-kts", _vCruise);
68 _vDescent = db_node->getDoubleValue("decent-speed-kts", _vDescent);
69 _vApproach = db_node->getDoubleValue("approach-speed-kts", _vApproach);
70 _vTouchdown = db_node->getDoubleValue("touchdown-speed-kts", _vTouchdown);
71 _vTaxi = db_node->getDoubleValue("taxi-speed-kts", _vTaxi);
74 double PerformanceData::actualSpeed(FGAIAircraft* ac, double tgt_speed, double dt, bool maxBrakes) {
75 // if (tgt_speed > _vTaxi & ac->onGround()) // maximum taxi speed on ground
76 // tgt_speed = _vTaxi;
77 // bad idea for a take off roll :-)
79 double speed = ac->getSpeed();
80 double speed_diff = tgt_speed - speed;
82 if (speed_diff > 0.0) // need to accelerate
84 speed += _acceleration * dt;
85 if ( speed > tgt_speed )
88 } else if (speed_diff < 0.0) { // decelerate
90 // deceleration performance is better due to wheel brakes.
91 double brakePower = 0;
95 brakePower = BRAKE_SETTING;
97 speed -= brakePower * _deceleration * dt;
99 speed -= _deceleration * dt;
102 if ( speed < tgt_speed )
110 double PerformanceData::decelerationOnGround() const
112 return _deceleration * BRAKE_SETTING;
115 double PerformanceData::actualBankAngle(FGAIAircraft* ac, double tgt_roll, double dt) {
116 // check maximum bank angle
117 if (fabs(tgt_roll) > _maxbank)
118 tgt_roll = _maxbank * tgt_roll/fabs(tgt_roll);
120 double roll = ac->getRoll();
121 double bank_diff = tgt_roll - roll;
123 if (fabs(bank_diff) > 0.2) {
124 if (bank_diff > 0.0) {
125 roll += _rollrate * dt;
129 else if (bank_diff < 0.0) {
130 roll -= _rollrate * dt;
135 //while (roll > 180) roll -= 360;
136 //while (roll < 180) roll += 360;
142 double PerformanceData::actualPitch(FGAIAircraft* ac, double tgt_pitch, double dt) {
143 double pitch = ac->getPitch();
144 double pdiff = tgt_pitch - pitch;
146 if (pdiff > 0.0) { // nose up
147 pitch += 0.005*_climbRate * dt / 3.0; //TODO avoid hardcoded 3 secs
149 if (pitch > tgt_pitch)
151 } else if (pdiff < 0.0) { // nose down
152 pitch -= 0.002*_descentRate * dt / 3.0;
154 if (pitch < tgt_pitch)
161 double PerformanceData::actualAltitude(FGAIAircraft* ac, double tgt_altitude, double dt) {
162 if (ac->onGround()) {
163 //FIXME: a return sensible value here
164 return 0.0; // 0 for now to avoid compiler errors
166 return ac->getAltitude() + ac->getVerticalSpeed()*dt/60.0;
169 double PerformanceData::actualVerticalSpeed(FGAIAircraft* ac, double tgt_vs, double dt) {
170 double vs = ac->getVerticalSpeed();
171 double vs_diff = tgt_vs - vs;
173 if (fabs(vs_diff) > .001) {
175 vs += _climbRate * dt / 3.0; //TODO avoid hardcoded 3 secs to attain climb rate from level flight
179 } else if (vs_diff < 0.0) {
180 vs -= _descentRate * dt / 3.0;
190 bool PerformanceData::gearExtensible(const FGAIAircraft* ac) {
191 return (ac->altitudeAGL() < 900.0)
192 && (ac->airspeed() < _vTouchdown * 1.25);