double GlidePolar::SinkRate(double V, double n) { double w0 = SinkRate(polar_a,polar_b,polar_c,0.0,0.0,V); n = max(0.1,fabs(n)); // double v1 = V/max(1,Vbestld); double v2 = Vbestld/max((double)Vbestld/2,V); return w0-(V/(2*bestld))* (n*n-1)*(v2*v2); }
void GlidePolar::UpdateSMax() { assert(polar.IsValid()); Smax = SinkRate(Vmax); }
void GlidePolar::update() { update_polar(); Smax = SinkRate(Vmax); solve_min(); set_mc(mc); }
fixed GlidePolar::SinkRate(const fixed V, const fixed n) const { const fixed w0 = SinkRate(V); const fixed vl = VbestLD / max(VbestLD * fixed_half, V); return max(fixed_zero, w0 + (V / (fixed_two * bestLD)) * (n * n - fixed_one) * vl * vl); }
fixed GlidePolar::SinkRate(const fixed V, const fixed n) const { const fixed w0 = SinkRate(V); const fixed vl = VbestLD / std::max(Half(VbestLD), V); return std::max(fixed(0), w0 + (V / Double(bestLD)) * (sqr(n) - fixed(1)) * sqr(vl)); }
fixed GlidePolar::SinkRate(const fixed V, const fixed n) const { const fixed w0 = SinkRate(V); const fixed vl = VbestLD / max(half(VbestLD), V); return max(fixed_zero, w0 + (V / Double(bestLD)) * (sqr(n) - fixed_one) * sqr(vl)); }
double GlidePolar::SinkRate(const double V, const double n) const { const auto w0 = SinkRate(V); const auto vl = VbestLD / std::max(Half(VbestLD), V); return std::max(0., w0 + (V / Double(bestLD)) * (n * n - 1) * vl * vl); }
void GlidePolar::solve_min() { /* // this method to be used if polar is not parabolic GlidePolarMinSink gpminsink(*this, Vmax); Vmin = gpminsink.find_min(Vmin); */ Vmin = min(Vmax, -polar_b/(fixed_two*polar_a)); Smin = SinkRate(Vmin); }
double GlidePolar::SinkRate(double V, double n) { double w0 = SinkRate(polar_a,polar_b,polar_c,0.0,0.0,V); n = max(0.1,fabs(n)); // double v1 = V/max(1,Vbestld); double v2 = Vbestld/max((double)Vbestld/2,V); #if BUGSTOP LKASSERT(bestld>0); #endif if (bestld<=0) bestld=1; // UNMANAGED return w0-(V/(2*bestld))* (n*n-1)*(v2*v2); }
void GlidePolar::solve_ld() { /* // this method to be used if polar is not parabolic GlidePolarVopt gpvopt(*this, Vmin, Vmax); VbestLD = gpvopt.find_min(VbestLD); */ assert(!negative(mc)); VbestLD = max(Vmin, min(Vmax, sqrt((polar_c+mc)/polar_a))); SbestLD = SinkRate(VbestLD); bestLD = VbestLD / SbestLD; }
void GlidePolar::UpdateSMin() { #if 0 // this method to be used if polar is not parabolic GlidePolarMinSink gpminsink(*this, Vmax); Vmin = gpminsink.find_min(Vmin); #else assert(polar.IsValid()); Vmin = std::min(Vmax, -polar.b / Double(polar.a)); Smin = SinkRate(Vmin); #endif UpdateBestLD(); }
void GlidePolar::UpdateBestLD() { #if 0 // this method to be used if polar is not parabolic GlidePolarVopt gpvopt(*this, Vmin, Vmax); VbestLD = gpvopt.find_min(VbestLD); #else assert(polar.IsValid()); assert(!negative(mc)); VbestLD = Clamp(sqrt((polar.c + mc) / polar.a), Vmin, Vmax); SbestLD = SinkRate(VbestLD); bestLD = VbestLD / SbestLD; #endif }
fixed GlidePolar::MSinkRate(const fixed V) const { return SinkRate(V) + mc; }
void GlidePolar::SetBallast() { LockFlightData(); double BallastWeight; BallastLitres = WEIGHTS[2] * BALLAST; BallastWeight = GetAUW(); if (WingArea>0.1) { WingLoading = BallastWeight/WingArea; } else { WingLoading = 0; } BallastWeight = (double)sqrt(BallastWeight); LKASSERT(BUGS!=0); if (BUGS==0) BUGS=1; double bugfactor = 1.0/BUGS; LKASSERT(BallastWeight!=0); if (BallastWeight==0) BallastWeight=1; polar_a = POLAR[0] / BallastWeight*bugfactor; polar_b = POLAR[1] * bugfactor; polar_c = POLAR[2] * BallastWeight*bugfactor; // do preliminary scan to find min sink and best LD // this speeds up mcready calculations because we have a reduced range // to search across. // this also limits speed to fly to logical values (will never try // to fly slower than min sink speed) minsink = 10000.0; bestld = 0.0; int i; // Rounding errors could make SAFTEYSPEED 0.00xx and not 0 // Now below 3kmh we consider the speed wrong // MAXSAFETYSPEED WAS 200, = 720kmh!! if ((SAFTEYSPEED<1)||(SAFTEYSPEED>=MAXSAFETYSPEED)) { SAFTEYSPEED=MAXSAFETYSPEED-1; } iSAFETYSPEED=(int)SAFTEYSPEED; // sinkratecache is an array for m/s values!! i is the speed in m/s for(i=4;i<=MAXSPEED;i++) { double vtrack = (double)i; // TAS along bearing in cruise double thesinkrate = -SinkRate(polar_a,polar_b,polar_c,0,0,vtrack); LKASSERT(thesinkrate!=0); if (thesinkrate==0) thesinkrate=0.001; double ld = vtrack/thesinkrate; if (ld>=bestld) { bestld = ld; Vbestld = i; } if (thesinkrate<= minsink) { minsink = thesinkrate; Vminsink = i; } sinkratecache[i] = -thesinkrate; } UnlockFlightData(); }
double GlidePolar::SinkRate(double V) { return SinkRate(polar_a,polar_b,polar_c,0.0,0.0,V); }
double GlidePolar::MSinkRate(const double V) const { return SinkRate(V) + mc; }