Yasim-test: add detailed lift/drag graphing
Patch by Huntley Palmer, to extend range of recorded angles, and offer a detailed mode with finer resolution over a specific range. SF-ID: https://sourceforge.net/p/flightgear/codetickets/2629/
This commit is contained in:
parent
82863d3f3e
commit
f8afde7528
1 changed files with 154 additions and 10 deletions
|
@ -59,6 +59,9 @@ void _calculateAcceleration(Airplane* a, float aoa_rad, float speed_mps, float*
|
||||||
s.localToGlobal(output, output);
|
s.localToGlobal(output, output);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Comments are incorrect: Historically this function only produces lift, drag curves
|
||||||
|
// For lift, drag and LD three column output please use --yasim-graph-detailed
|
||||||
|
//
|
||||||
// Generate a graph of lift, drag and L/D against AoA at the specified
|
// Generate a graph of lift, drag and L/D against AoA at the specified
|
||||||
// speed and altitude. The result is a tab-separated file of
|
// speed and altitude. The result is a tab-separated file of
|
||||||
// numbers: "aoa lift drag LD" (aoa in degrees, lift and drag in
|
// numbers: "aoa lift drag LD" (aoa in degrees, lift and drag in
|
||||||
|
@ -77,8 +80,8 @@ void yasim_graph(Airplane* a, const float alt, const float kts, Airplane::Config
|
||||||
float cl_max = 0, cd_min = 1e6, ld_max = 0;
|
float cl_max = 0, cd_min = 1e6, ld_max = 0;
|
||||||
int cl_max_deg = 0, cd_min_deg = 0, ld_max_deg = 0;
|
int cl_max_deg = 0, cd_min_deg = 0, ld_max_deg = 0;
|
||||||
|
|
||||||
printf("aoa\tLift\tDrag\tLvsD\n");
|
printf("aoa\tlift\tdrag\n");
|
||||||
for(int deg=-5; deg<=29; deg++) {
|
for(int deg=-15; deg<=90; deg++) {
|
||||||
float aoa = deg * DEG2RAD;
|
float aoa = deg * DEG2RAD;
|
||||||
_calculateAcceleration(a, aoa, speed, acc);
|
_calculateAcceleration(a, aoa, speed, acc);
|
||||||
float drag = acc[0] * (-1/9.8);
|
float drag = acc[0] * (-1/9.8);
|
||||||
|
@ -97,7 +100,7 @@ void yasim_graph(Airplane* a, const float alt, const float kts, Airplane::Config
|
||||||
ld_max= ld;
|
ld_max= ld;
|
||||||
ld_max_deg = deg;
|
ld_max_deg = deg;
|
||||||
}
|
}
|
||||||
printf("%2d\t%.4f\t%.4f\t%.4f\n", deg, lift, drag, ld);
|
printf("%2d\t%.4f\t%.4f\n", deg, lift, drag);
|
||||||
}
|
}
|
||||||
printf("# cl_max %.4f at %d deg\n", cl_max, cl_max_deg);
|
printf("# cl_max %.4f at %d deg\n", cl_max, cl_max_deg);
|
||||||
printf("# cd_min %.4f at %d deg\n", cd_min, cd_min_deg);
|
printf("# cd_min %.4f at %d deg\n", cd_min, cd_min_deg);
|
||||||
|
@ -235,6 +238,94 @@ void findMinSpeed(Airplane* a, float alt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Additional command functions with 10x detail, smaller AoA range
|
||||||
|
//
|
||||||
|
// Generate a graph of lift, drag and L/D against AoA at the specified
|
||||||
|
// speed and altitude with fine deteil. The result is a tab-separated file of
|
||||||
|
// numbers: "aoa lift drag LD" (aoa in degrees, lift and drag in
|
||||||
|
// G's). You can use this in gnuplot like so (assuming the output is
|
||||||
|
// in a file named "dat":
|
||||||
|
/*
|
||||||
|
plot "dat" using 1:2 with lines title 'lift', \
|
||||||
|
"dat" using 1:3 with lines title 'drag', \
|
||||||
|
"dat" using 1:4 with lines title 'LD'
|
||||||
|
*/
|
||||||
|
void yasim_graph_detailed(Airplane* a, const float alt, const float kts, Airplane::Configuration cfgID)
|
||||||
|
{
|
||||||
|
_setup(a, cfgID, alt);
|
||||||
|
float speed = kts * KTS2MPS;
|
||||||
|
float acc[3] {0,0,0};
|
||||||
|
float cl_max = 0, cd_min = 1e6, ld_max = 0;
|
||||||
|
int cl_max_deg = 0, cd_min_deg = 0, ld_max_deg = 0;
|
||||||
|
|
||||||
|
printf("aoa\tlift\tdrag\tLD\n");
|
||||||
|
for(float deg=-2.0; deg<=25.0 ; deg+= 0.10 ) {
|
||||||
|
float aoa = deg * DEG2RAD;
|
||||||
|
_calculateAcceleration(a, aoa, speed, acc);
|
||||||
|
float drag = acc[0] * (-1/9.8);
|
||||||
|
float lift = 1 + acc[2] * (1/9.8);
|
||||||
|
float ld = lift/drag;
|
||||||
|
|
||||||
|
if (cd_min > drag) {
|
||||||
|
cd_min = drag;
|
||||||
|
cd_min_deg = deg;
|
||||||
|
}
|
||||||
|
if (cl_max < lift) {
|
||||||
|
cl_max = lift;
|
||||||
|
cl_max_deg = deg;
|
||||||
|
}
|
||||||
|
if (ld_max < ld) {
|
||||||
|
ld_max= ld;
|
||||||
|
ld_max_deg = deg;
|
||||||
|
}
|
||||||
|
printf("%-2.1f\t%-2.3f\t%-2.3f\t%-2.3f\n", deg, lift, drag, ld);
|
||||||
|
}
|
||||||
|
//printf("# cl_max %.4f at %d deg\n", cl_max, cl_max_deg);
|
||||||
|
//printf("# cd_min %.4f at %d deg\n", cd_min, cd_min_deg);
|
||||||
|
//printf("# ld_max %.4f at %d deg\n", ld_max, ld_max_deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void yasim_drag_detailed(Airplane* a, const float aoa, const float alt, Airplane::Configuration cfgID)
|
||||||
|
{
|
||||||
|
_setup(a, cfgID, alt);
|
||||||
|
|
||||||
|
float cd_min = 1e6;
|
||||||
|
int cd_min_kts = 0;
|
||||||
|
float acc[3] {0,0,0};
|
||||||
|
|
||||||
|
printf("knots\tdrag\n");
|
||||||
|
for(float kts=0; kts<=100; kts += 0.1) {
|
||||||
|
_calculateAcceleration(a, aoa,kts * KTS2MPS, acc);
|
||||||
|
float drag = acc[0] * (-1/9.8);
|
||||||
|
if (cd_min > drag) {
|
||||||
|
cd_min = drag;
|
||||||
|
cd_min_kts = kts;
|
||||||
|
}
|
||||||
|
printf("%-2.3f\t%-2.3f\n", kts, drag);
|
||||||
|
}
|
||||||
|
//printf("# cd_min %g at %d kts\n", cd_min, cd_min_kts);
|
||||||
|
}
|
||||||
|
|
||||||
|
void findMinSpeedDetailed(Airplane* a, float alt)
|
||||||
|
{
|
||||||
|
a->addControlSetting(Airplane::CRUISE, "/controls/flight/elevator-trim", 0.7f);
|
||||||
|
_setup(a, Airplane::CRUISE, alt);
|
||||||
|
float acc[3];
|
||||||
|
|
||||||
|
printf("aoa\tknots\tlift\n");
|
||||||
|
for(float deg=-2; deg<=25.0; deg+=0.10) {
|
||||||
|
float aoa = deg * DEG2RAD;
|
||||||
|
for(float kts = 0; kts <= 180.0; kts += 0.1) {
|
||||||
|
_calculateAcceleration(a, aoa, kts * KTS2MPS, acc);
|
||||||
|
float lift = acc[2];
|
||||||
|
if (lift > 0) {
|
||||||
|
printf("%-2.1f \t %-2.3f \t %-2.3f\n", deg, kts, ( 100 + 100 * lift));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void report(Airplane* a)
|
void report(Airplane* a)
|
||||||
{
|
{
|
||||||
printf("==========================\n");
|
printf("==========================\n");
|
||||||
|
@ -270,7 +361,7 @@ void report(Airplane* a)
|
||||||
MACy = wing->getMACy();
|
MACy = wing->getMACy();
|
||||||
sweepMin = wing->getSweepLEMin() * RAD2DEG;
|
sweepMin = wing->getSweepLEMin() * RAD2DEG;
|
||||||
sweepMax = wing->getSweepLEMax() * RAD2DEG;
|
sweepMax = wing->getSweepLEMax() * RAD2DEG;
|
||||||
printf("Wing MAC : (x:%.2f, y:%.2f), length:%.1f \n", MACx, MACy, MAC);
|
printf("Wing MAC : (x:%.3f, y:%.3f), length:%.3f \n", MACx, MACy, MAC);
|
||||||
printf("hard limit CG-x : %.3f m\n", a->getCGHardLimitXMax());
|
printf("hard limit CG-x : %.3f m\n", a->getCGHardLimitXMax());
|
||||||
printf("soft limit CG-x : %.3f m\n", a->getCGSoftLimitXMax());
|
printf("soft limit CG-x : %.3f m\n", a->getCGSoftLimitXMax());
|
||||||
printf("CG-x : %.3f m\n", cg[0]);
|
printf("CG-x : %.3f m\n", cg[0]);
|
||||||
|
@ -296,10 +387,12 @@ void report(Airplane* a)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
wing->printSectionInfo();
|
wing->printSectionInfo();
|
||||||
}
|
}
|
||||||
printf("\nInertia tensor [kg*m^2], origo at CG:\n\n");
|
printf("\nInertia Tensor [kg*m^2], ( Angular Moments ) Origo at CG:\n\n");
|
||||||
printf(" %7.0f, %7.0f, %7.0f\n", SI_inertia[0], SI_inertia[1], SI_inertia[2]);
|
printf(" Effect on Axis\n");
|
||||||
printf(" %7.0f, %7.0f, %7.0f\n", SI_inertia[3], SI_inertia[4], SI_inertia[5]);
|
printf(" x Roll y Pitch z Yaw\n");
|
||||||
printf(" %7.0f, %7.0f, %7.0f\n", SI_inertia[6], SI_inertia[7], SI_inertia[8]);
|
printf("Impulse x Roll %7.0f %7.0f %7.0f\n", SI_inertia[0], SI_inertia[1], SI_inertia[2]);
|
||||||
|
printf(" on y Pitch %7.0f %7.0f %7.0f\n", SI_inertia[3], SI_inertia[4], SI_inertia[5]);
|
||||||
|
printf(" Axis z Yaw %7.0f %7.0f %7.0f\n", SI_inertia[6], SI_inertia[7], SI_inertia[8]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int usage()
|
int usage()
|
||||||
|
@ -307,7 +400,7 @@ int usage()
|
||||||
fprintf(stderr, "Usage: \n");
|
fprintf(stderr, "Usage: \n");
|
||||||
fprintf(stderr, " yasim <aircraft.xml> [-g [-a meters] [-s kts] [-approach | -cruise] ]\n");
|
fprintf(stderr, " yasim <aircraft.xml> [-g [-a meters] [-s kts] [-approach | -cruise] ]\n");
|
||||||
fprintf(stderr, " yasim <aircraft.xml> [-d [-a meters] [-approach | -cruise] ]\n");
|
fprintf(stderr, " yasim <aircraft.xml> [-d [-a meters] [-approach | -cruise] ]\n");
|
||||||
fprintf(stderr, " yasim <aircraft.xml> [-m]\n");
|
fprintf(stderr, " yasim <aircraft.xml> [-m] [-h] [--min-speed]\n");
|
||||||
fprintf(stderr, " yasim <aircraft.xml> [-test] [-a meters] [-s kts] [-approach | -cruise] ]\n");
|
fprintf(stderr, " yasim <aircraft.xml> [-test] [-a meters] [-s kts] [-approach | -cruise] ]\n");
|
||||||
fprintf(stderr, " -g print lift/drag table: aoa, lift, drag, lift/drag \n");
|
fprintf(stderr, " -g print lift/drag table: aoa, lift, drag, lift/drag \n");
|
||||||
fprintf(stderr, " -d print drag over TAS: kts, drag\n");
|
fprintf(stderr, " -d print drag over TAS: kts, drag\n");
|
||||||
|
@ -316,6 +409,10 @@ int usage()
|
||||||
fprintf(stderr, " -a set altitude in meters!\n");
|
fprintf(stderr, " -a set altitude in meters!\n");
|
||||||
fprintf(stderr, " -s set speed in knots\n");
|
fprintf(stderr, " -s set speed in knots\n");
|
||||||
fprintf(stderr, " -m print mass distribution table: id, x, y, z, mass \n");
|
fprintf(stderr, " -m print mass distribution table: id, x, y, z, mass \n");
|
||||||
|
fprintf(stderr, " Options to generate LD curve and greater deteiled plotting\n");
|
||||||
|
fprintf(stderr, " yasim <aircraft.xml> [--detailed-graph] [--detailed-drag]\n");
|
||||||
|
fprintf(stderr, " yasim <aircraft.xml> [--detailed-min-speed -approach]\n");
|
||||||
|
fprintf(stderr, " yasim <aircraft.xml> [--detailed-min-speed -cruise]\n");
|
||||||
fprintf(stderr, " -test print summary and output like -g -m \n");
|
fprintf(stderr, " -test print summary and output like -g -m \n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -355,7 +452,54 @@ int main(int argc, char** argv)
|
||||||
Airplane::Configuration cfg = Airplane::NONE;
|
Airplane::Configuration cfg = Airplane::NONE;
|
||||||
float alt = 5000, kts = 100;
|
float alt = 5000, kts = 100;
|
||||||
|
|
||||||
if((strcmp(argv[2], "-g") == 0) || test) {
|
// command extensions tested first to preserve precedence
|
||||||
|
if((strcmp(argv[2], "--detailed-graph") == 0) || test) {
|
||||||
|
for(int i=3; i<argc; i++) {
|
||||||
|
if (std::strcmp(argv[i], "-a") == 0) {
|
||||||
|
if (i+1 < argc) alt = std::atof(argv[++i]);
|
||||||
|
}
|
||||||
|
else if(std::strcmp(argv[i], "-s") == 0) {
|
||||||
|
if(i+1 < argc) kts = std::atof(argv[++i]);
|
||||||
|
}
|
||||||
|
else if(std::strcmp(argv[i], "-approach") == 0) cfg = Airplane::APPROACH;
|
||||||
|
else if(std::strcmp(argv[i], "-cruise") == 0) cfg = Airplane::CRUISE;
|
||||||
|
else return usage();
|
||||||
|
}
|
||||||
|
if (test) {
|
||||||
|
report(a);
|
||||||
|
printf("\n#-- lift, drag at altitude %.0f meters, %.0f knots, Config %d --\n", alt, kts, cfg);
|
||||||
|
}
|
||||||
|
yasim_graph_detailed(a, alt, kts, cfg);
|
||||||
|
if (test) {
|
||||||
|
printf("\n#-- mass distribution --\n");
|
||||||
|
yasim_masses(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(strcmp(argv[2], "--detailed-drag") == 0) {
|
||||||
|
float alt = 2000, aoa = a->getCruiseAoA();
|
||||||
|
for(int i=3; i<argc; i++) {
|
||||||
|
if (std::strcmp(argv[i], "-a") == 0) {
|
||||||
|
if (i+1 < argc) alt = std::atof(argv[++i]);
|
||||||
|
}
|
||||||
|
else if(std::strcmp(argv[i], "-approach") == 0) cfg = Airplane::APPROACH;
|
||||||
|
else if(std::strcmp(argv[i], "-cruise") == 0) cfg = Airplane::CRUISE;
|
||||||
|
else return usage();
|
||||||
|
}
|
||||||
|
yasim_drag_detailed(a, aoa, alt, cfg);
|
||||||
|
}
|
||||||
|
else if(strcmp(argv[2], "--detailed-min-speed") == 0) {
|
||||||
|
alt = 10;
|
||||||
|
for(int i=3; i<argc; i++) {
|
||||||
|
if (std::strcmp(argv[i], "-a") == 0) {
|
||||||
|
if (i+1 < argc) alt = std::atof(argv[++i]);
|
||||||
|
}
|
||||||
|
else if(std::strcmp(argv[i], "-approach") == 0) cfg = Airplane::APPROACH;
|
||||||
|
else if(std::strcmp(argv[i], "-cruise") == 0) cfg = Airplane::CRUISE;
|
||||||
|
else return usage();
|
||||||
|
}
|
||||||
|
findMinSpeedDetailed(a, alt);
|
||||||
|
}
|
||||||
|
else if((strcmp(argv[2], "-g") == 0) || test) {
|
||||||
for(int i=3; i<argc; i++) {
|
for(int i=3; i<argc; i++) {
|
||||||
if (std::strcmp(argv[i], "-a") == 0) {
|
if (std::strcmp(argv[i], "-a") == 0) {
|
||||||
if (i+1 < argc) alt = std::atof(argv[++i]);
|
if (i+1 < argc) alt = std::atof(argv[++i]);
|
||||||
|
|
Loading…
Add table
Reference in a new issue