1 #ifdef HAVE_CONFIG_H
2 #  include "config.h"
3 #endif
4 
5 #include <stdio.h>
6 #include <stdlib.h>
7 
8 #include "yasim-common.hpp"
9 #include "Math.hpp"
10 #include "FGFDM.hpp"
11 #include "PropEngine.hpp"
12 #include "Propeller.hpp"
13 #include "Atmosphere.hpp"
14 
15 #include <simgear/misc/sg_path.hxx>
16 
17 using namespace yasim;
18 
19 // Usage: proptest plane.xml [alt-ft] [spd-ktas]
20 
21 // Stubs.  Not needed by a batch program, but required to link.
22 class SGPropertyNode;
fgSetFloat(const char * name,float val)23 bool fgSetFloat (const char * name, float val) { return false; }
fgSetBool(char const * name,bool val)24 bool fgSetBool(char const * name, bool val) { return false; }
fgGetBool(char const * name,bool def)25 bool fgGetBool(char const * name, bool def) { return false; }
fgSetString(char const * name,char const * str)26 bool fgSetString(char const * name, char const * str) { return false; }
fgGetNode(const char * path,bool create)27 SGPropertyNode* fgGetNode (const char * path, bool create) { return 0; }
fgGetNode(const char * path,int i,bool create)28 SGPropertyNode* fgGetNode (const char * path, int i, bool create) { return 0; }
fgGetFloat(const char * name,float defaultValue)29 float fgGetFloat (const char * name, float defaultValue) { return 0; }
fgGetDouble(const char * name,double defaultValue)30 double fgGetDouble (const char * name, double defaultValue) { return 0; }
fgSetDouble(const char * name,double defaultValue)31 bool fgSetDouble (const char * name, double defaultValue) { return false; }
32 
33 const int COUNT = 100;
34 
main(int argc,char ** argv)35 int main(int argc, char** argv)
36 {
37     FGFDM fdm;
38 
39     // Read
40     try {
41         readXML(SGPath::fromLocal8Bit(argv[1]), fdm);
42     } catch (const sg_exception &e) {
43         printf("XML parse error: %s (%s)\n",
44                e.getFormattedMessage().c_str(), e.getOrigin());
45     }
46 
47     Airplane* airplane = fdm.getAirplane();
48     PropEngine* pe = airplane->getThruster(0)->getPropEngine();
49     Propeller* prop = pe->getPropeller();
50     Engine* eng = pe->getEngine();
51 
52     pe->init();
53     pe->setMixture(1);
54     pe->setFuelState(true);
55     eng->setBoost(1);
56 
57     float alt = (argc > 2 ? atof(argv[2]) : 0) * FT2M;
58     pe->setStandardAtmosphere(alt);
59 
60     float speed = (argc > 3 ? atof(argv[3]) : 0) * KTS2MPS;
61     float wind[3];
62     wind[0] = -speed; wind[1] = wind[2] = 0;
63     pe->setWind(wind);
64 
65     printf("Alt: %f\n", alt / FT2M);
66     printf("Spd: %f\n", speed / KTS2MPS);
67     printf("-----------------\n");
68     printf("Throt   RPM   thrustlbs      HP   eff %%   torque\n");
69     for(int i=0; i<COUNT; i++) {
70         float throttle = i/(COUNT-1.0);
71         pe->setThrottle(throttle);
72         pe->stabilize();
73 
74         float rpm = pe->getOmega() * (1/RPM2RAD);
75 
76         float tmp[3];
77         pe->getThrust(tmp);
78         float thrust = Math::mag3(tmp);
79 
80         float power = pe->getOmega() * eng->getTorque();
81 
82         float eff = thrust * speed / power;
83 
84         printf("%5.3f %7.1f %8.1f %8.1f %7.1f %8.1f\n",
85                throttle, rpm, thrust * N2LB, power * (1/HP2W), 100*eff, eng->getTorque());
86     }
87 
88     printf("\n");
89     printf("Propeller vs. RPM\n");
90     printf("-----------------\n");
91     printf("RPM       thrustlbs         HP   eff %%      torque\n");
92     for(int i=0; i<COUNT; i++) {
93         float thrust, torque, rpm = 3000 * i/(COUNT-1.0);
94         float omega = rpm * RPM2RAD;
95         prop->calc(Atmosphere::getStdDensity(alt),
96                    speed, omega, &thrust, &torque);
97         float power = torque * omega;
98         float eff = (thrust * speed) / power;
99         printf("%7.1f %11.1f %10.1f %7.1f %11.1f\n",
100                rpm, thrust * N2LB, power * (1/HP2W), 100*eff, torque);
101     }
102 }
103