static Phase::CirclingDirection CalcCirclingDirection(const DerivedInfo &calculated) { if (!calculated.circling) { return Phase::CirclingDirection::NO_DIRECTION; } return calculated.TurningLeft() ? Phase::CirclingDirection::LEFT : Phase::CirclingDirection::RIGHT; }
void GlideComputerAirData::UpdateLiftDatabase(const MoreData &basic, DerivedInfo &calculated, const DerivedInfo &last_calculated) { // If we just started circling // -> reset the database because this is a new thermal if (!calculated.circling && last_calculated.circling) ResetLiftDatabase(calculated); // Determine the direction in which we are circling bool left = calculated.TurningLeft(); // Depending on the direction set the step size sign for the // following loop Angle heading_step = Angle::Degrees(fixed(left ? -10 : 10)); // Start at the last heading and add heading_step until the current heading // is reached. For each heading save the current lift value into the // LiftDatabase. Last and current heading are included since they are // a part of the ten degree interval most of the time. // // This is done with Angles to deal with the 360 degrees limit. // e.g. last heading 348 degrees, current heading 21 degrees // // The loop condition stops until the current heading is reached. // Depending on the circling direction the current heading will be // smaller or bigger then the last one, because of that negative() is // tested against the left variable. for (Angle h = last_calculated.heading; left == negative((calculated.heading - h).AsDelta().Degrees()); h += heading_step) { unsigned index = heading_to_index(h); calculated.lift_database[index] = basic.brutto_vario; } // detect zero crossing if (((calculated.heading.Degrees()< fixed_90) && (last_calculated.heading.Degrees()> fixed_270)) || ((last_calculated.heading.Degrees()< fixed_90) && (calculated.heading.Degrees()> fixed_270))) { fixed h_av = fixed_zero; for (unsigned i=0; i<36; ++i) { h_av += calculated.lift_database[i]; } h_av/= 36; calculated.trace_history.CirclingAverage.push(h_av); } }