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