Solve for the elevator control input during approach. It turns out that
the downforce from the tail due to elevator trim is a significant contribution to total lift.
This commit is contained in:
parent
e380891c40
commit
4535c84b99
4 changed files with 63 additions and 9 deletions
|
@ -1,3 +1,5 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "Atmosphere.hpp"
|
||||
#include "ControlMap.hpp"
|
||||
#include "Gear.hpp"
|
||||
|
@ -10,6 +12,10 @@
|
|||
#include "Airplane.hpp"
|
||||
namespace yasim {
|
||||
|
||||
// gadgets
|
||||
inline float norm(float f) { return f<1 ? 1/f : f; }
|
||||
inline float abs(float f) { return f<0 ? -f : f; }
|
||||
|
||||
Airplane::Airplane()
|
||||
{
|
||||
_emptyWeight = 0;
|
||||
|
@ -146,6 +152,13 @@ void Airplane::setCruise(float speed, float altitude)
|
|||
_tailIncidence = 0;
|
||||
}
|
||||
|
||||
void Airplane::setElevatorControl(int control)
|
||||
{
|
||||
_approachElevator.control = control;
|
||||
_approachElevator.val = 0;
|
||||
_approachControls.add(&_approachElevator);
|
||||
}
|
||||
|
||||
void Airplane::addApproachControl(int control, float val)
|
||||
{
|
||||
Control* c = new Control();
|
||||
|
@ -804,6 +817,9 @@ void Airplane::solve()
|
|||
// Run an approach iteration, and do likewise
|
||||
runApproach();
|
||||
|
||||
_model.getBody()->getAngularAccel(tmp);
|
||||
float apitch0 = tmp[1];
|
||||
|
||||
_model.getBody()->getAccel(tmp);
|
||||
float alift = _approachWeight * tmp[2];
|
||||
|
||||
|
@ -840,7 +856,23 @@ void Airplane::solve()
|
|||
return;
|
||||
}
|
||||
|
||||
// And apply:
|
||||
// And the elevator control in the approach. This works just
|
||||
// like the tail incidence computation (it's solving for the
|
||||
// same thing -- pitching moment -- by diddling a different
|
||||
// variable).
|
||||
const float ELEVDIDDLE = 0.0001f;
|
||||
_approachElevator.val += ELEVDIDDLE;
|
||||
runApproach();
|
||||
_approachElevator.val -= ELEVDIDDLE;
|
||||
|
||||
_model.getBody()->getAngularAccel(tmp);
|
||||
float apitch1 = tmp[1];
|
||||
float elevDelta = -apitch0 * (ELEVDIDDLE/(apitch1-apitch0));
|
||||
|
||||
// Now apply the values we just computed. Note that the
|
||||
// "minor" variables are deferred until we get the lift/drag
|
||||
// numbers in the right ballpark.
|
||||
|
||||
applyDragFactor(dragFactor);
|
||||
applyLiftRatio(liftFactor);
|
||||
|
||||
|
@ -851,15 +883,27 @@ void Airplane::solve()
|
|||
continue;
|
||||
}
|
||||
|
||||
// OK, now we can adjust the minor variables
|
||||
// OK, now we can adjust the minor variables:
|
||||
_cruiseAoA += 0.5f*aoaDelta;
|
||||
_tailIncidence += 0.5f*tailDelta;
|
||||
_approachElevator.val += 0.5f*elevDelta;
|
||||
|
||||
_cruiseAoA = clamp(_cruiseAoA, -0.174f, 0.174f);
|
||||
_tailIncidence = clamp(_tailIncidence, -0.174f, 0.174f);
|
||||
_approachElevator.val = clamp(_approachElevator.val, -1.f, 1.f);
|
||||
|
||||
if(dragFactor < 1.00001 && liftFactor < 1.00001 &&
|
||||
aoaDelta < .000017 && tailDelta < .000017)
|
||||
fprintf(stderr, "p0 %6f p1 %6f e %5f d %5f\n",
|
||||
apitch0, apitch1, _approachElevator.val, elevDelta); // DEBUG
|
||||
|
||||
fprintf(stderr, "l %5f d %5f aoa %5f inc %5f ele %5f\n",
|
||||
_liftRatio, _dragFactor, _cruiseAoA, _tailIncidence,
|
||||
_approachElevator.val);
|
||||
|
||||
if(norm(dragFactor) < 1.00001 &&
|
||||
norm(liftFactor) < 1.00001 &&
|
||||
abs(aoaDelta) < .000017 &&
|
||||
abs(tailDelta) < .000017 &&
|
||||
abs(elevDelta) < 0.00001)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ public:
|
|||
void setApproach(float speed, float altitude, float aoa);
|
||||
void setCruise(float speed, float altitude);
|
||||
|
||||
void setElevatorControl(int control);
|
||||
void addApproachControl(int control, float val);
|
||||
void addCruiseControl(int control, float val);
|
||||
|
||||
|
@ -67,6 +68,7 @@ public:
|
|||
float getLiftRatio();
|
||||
float getCruiseAoA();
|
||||
float getTailIncidence();
|
||||
float getApproachElevator() { return _approachElevator.val; }
|
||||
char* getFailureMsg();
|
||||
|
||||
private:
|
||||
|
@ -135,6 +137,7 @@ private:
|
|||
float _liftRatio;
|
||||
float _cruiseAoA;
|
||||
float _tailIncidence;
|
||||
Control _approachElevator;
|
||||
char* _failureMsg;
|
||||
};
|
||||
|
||||
|
|
|
@ -36,6 +36,11 @@ static const float CIN2CM = 1.6387064e-5;
|
|||
FGFDM::FGFDM()
|
||||
{
|
||||
_nextEngine = 0;
|
||||
|
||||
// Map /controls/elevator to the approach elevator control. This
|
||||
// should probably be settable, but there are very few aircraft
|
||||
// who trim their approaches using things other than elevator.
|
||||
_airplane.setElevatorControl(parseAxis("/controls/elevator"));
|
||||
}
|
||||
|
||||
FGFDM::~FGFDM()
|
||||
|
|
|
@ -74,11 +74,13 @@ void YASim::report()
|
|||
float drag = 1000 * a->getDragCoefficient();
|
||||
|
||||
SG_LOG(SG_FLIGHT,SG_INFO,"YASim solution results:");
|
||||
SG_LOG(SG_FLIGHT,SG_INFO," Iterations: "<<a->getSolutionIterations());
|
||||
SG_LOG(SG_FLIGHT,SG_INFO,"Drag Coefficient: "<< drag);
|
||||
SG_LOG(SG_FLIGHT,SG_INFO," Lift Ratio: "<<a->getLiftRatio());
|
||||
SG_LOG(SG_FLIGHT,SG_INFO," Cruise AoA: "<< aoa);
|
||||
SG_LOG(SG_FLIGHT,SG_INFO," Tail Incidence: "<< tail);
|
||||
SG_LOG(SG_FLIGHT,SG_INFO," Iterations: "<<a->getSolutionIterations());
|
||||
SG_LOG(SG_FLIGHT,SG_INFO," Drag Coefficient: "<< drag);
|
||||
SG_LOG(SG_FLIGHT,SG_INFO," Lift Ratio: "<<a->getLiftRatio());
|
||||
SG_LOG(SG_FLIGHT,SG_INFO," Cruise AoA: "<< aoa);
|
||||
SG_LOG(SG_FLIGHT,SG_INFO," Tail Incidence: "<< tail);
|
||||
SG_LOG(SG_FLIGHT,SG_INFO,"Approach Elevator: "<<a->getApproachElevator());
|
||||
|
||||
|
||||
float cg[3];
|
||||
char buf[256];
|
||||
|
|
Loading…
Add table
Reference in a new issue