Changing the thresholds to be bigger in the previous patch isn't
really useful unless we simultaneously change the per-iteration deltas to be smaller. Add another pseudo-tunable to control the speed with which we change values across iterations. As it turns out, this is much more effective than the threshold tunable. It does come at the cost of lower solution performance, however.
This commit is contained in:
parent
5c8e6a5841
commit
ba84ec24bf
1 changed files with 17 additions and 12 deletions
|
@ -15,6 +15,18 @@ namespace yasim {
|
||||||
inline float norm(float f) { return f<1 ? 1/f : f; }
|
inline float norm(float f) { return f<1 ? 1/f : f; }
|
||||||
inline float abs(float f) { return f<0 ? -f : f; }
|
inline float abs(float f) { return f<0 ? -f : f; }
|
||||||
|
|
||||||
|
// Solver threshold. How close to the solution are we trying
|
||||||
|
// to get? Trying too hard can result in oscillations about
|
||||||
|
// the correct solution, which is bad. Stick this in as a
|
||||||
|
// compile time constant for now, and consider making it
|
||||||
|
// settable per-model.
|
||||||
|
const float STHRESH = 1;
|
||||||
|
|
||||||
|
// How slowly do we change values in the solver. Too slow, and
|
||||||
|
// the solution converges very slowly. Too fast, and it can
|
||||||
|
// oscillate.
|
||||||
|
const float SOLVE_TWEAK = 0.3226;
|
||||||
|
|
||||||
Airplane::Airplane()
|
Airplane::Airplane()
|
||||||
{
|
{
|
||||||
_emptyWeight = 0;
|
_emptyWeight = 0;
|
||||||
|
@ -787,7 +799,7 @@ void Airplane::runApproach()
|
||||||
|
|
||||||
void Airplane::applyDragFactor(float factor)
|
void Airplane::applyDragFactor(float factor)
|
||||||
{
|
{
|
||||||
float applied = Math::sqrt(factor);
|
float applied = Math::pow(factor, SOLVE_TWEAK);
|
||||||
_dragFactor *= applied;
|
_dragFactor *= applied;
|
||||||
_wing->setDragScale(_wing->getDragScale() * applied);
|
_wing->setDragScale(_wing->getDragScale() * applied);
|
||||||
_tail->setDragScale(_tail->getDragScale() * applied);
|
_tail->setDragScale(_tail->getDragScale() * applied);
|
||||||
|
@ -804,7 +816,7 @@ void Airplane::applyDragFactor(float factor)
|
||||||
|
|
||||||
void Airplane::applyLiftRatio(float factor)
|
void Airplane::applyLiftRatio(float factor)
|
||||||
{
|
{
|
||||||
float applied = Math::sqrt(factor);
|
float applied = Math::pow(factor, SOLVE_TWEAK);
|
||||||
_liftRatio *= applied;
|
_liftRatio *= applied;
|
||||||
_wing->setLiftRatio(_wing->getLiftRatio() * applied);
|
_wing->setLiftRatio(_wing->getLiftRatio() * applied);
|
||||||
_tail->setLiftRatio(_tail->getLiftRatio() * applied);
|
_tail->setLiftRatio(_tail->getLiftRatio() * applied);
|
||||||
|
@ -929,13 +941,6 @@ void Airplane::solve()
|
||||||
applyDragFactor(dragFactor);
|
applyDragFactor(dragFactor);
|
||||||
applyLiftRatio(liftFactor);
|
applyLiftRatio(liftFactor);
|
||||||
|
|
||||||
// Solver threshold. How close to the solution are we trying
|
|
||||||
// to get? Trying too hard can result in oscillations about
|
|
||||||
// the correct solution, which is bad. Stick this in as a
|
|
||||||
// compile time constant for now, and consider making it
|
|
||||||
// settable per-model.
|
|
||||||
float STHRESH = 1.6;
|
|
||||||
|
|
||||||
// DON'T do the following until the above are sane
|
// DON'T do the following until the above are sane
|
||||||
if(normFactor(dragFactor) > STHRESH*1.0001
|
if(normFactor(dragFactor) > STHRESH*1.0001
|
||||||
|| normFactor(liftFactor) > STHRESH*1.0001)
|
|| normFactor(liftFactor) > STHRESH*1.0001)
|
||||||
|
@ -944,8 +949,8 @@ void Airplane::solve()
|
||||||
}
|
}
|
||||||
|
|
||||||
// OK, now we can adjust the minor variables:
|
// OK, now we can adjust the minor variables:
|
||||||
_cruiseAoA += 0.5f*aoaDelta;
|
_cruiseAoA += SOLVE_TWEAK*aoaDelta;
|
||||||
_tailIncidence += 0.5f*tailDelta;
|
_tailIncidence += SOLVE_TWEAK*tailDelta;
|
||||||
|
|
||||||
_cruiseAoA = clamp(_cruiseAoA, -0.175f, 0.175f);
|
_cruiseAoA = clamp(_cruiseAoA, -0.175f, 0.175f);
|
||||||
_tailIncidence = clamp(_tailIncidence, -0.175f, 0.175f);
|
_tailIncidence = clamp(_tailIncidence, -0.175f, 0.175f);
|
||||||
|
@ -960,7 +965,7 @@ void Airplane::solve()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Otherwise, adjust and do the next iteration
|
// Otherwise, adjust and do the next iteration
|
||||||
_approachElevator.val += 0.8 * elevDelta;
|
_approachElevator.val += SOLVE_TWEAK * elevDelta;
|
||||||
if(abs(_approachElevator.val) > 1) {
|
if(abs(_approachElevator.val) > 1) {
|
||||||
_failureMsg = "Insufficient elevator to trim for approach";
|
_failureMsg = "Insufficient elevator to trim for approach";
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue