/// <summary> /// Change the control used to zero a state previously configured /// </summary> /// <param name="state">the accel or other condition to zero</param> /// <param name="new_control">the control used to zero the state</param> /// <returns></returns> public bool EditState(StateType state, ControlType new_control) { bool result = false; mode = TrimMode.Custom; int pos = 0; foreach (TrimAxis iAxes in TrimAxes) { if (iAxes.GetStateType() == state) { TrimAxes[pos] = new TrimAxis(fdmex, fgic, state, new_control); result = true; break; } pos++; } return(result); }
/// <summary> /// Execute the trim /// </summary> /// <returns></returns> public bool DoTrim() { #if TODO trim_failed = false; int i; for (i = 0; i < fdmex.GroundReactions.NumGearUnits; i++) { fdmex.GroundReactions.GetGearUnit(i).SetReport(false); } fdmex.DisableOutput(); fgic.PRadpsIC = 0.0; fgic.QRadpsIC = 0.0; fgic.RRadpsIC = 0.0; //clear the sub iterations counts & zero out the controls for (current_axis = 0; current_axis < TrimAxes.Count; current_axis++) { //cout + current_axis + " " + TrimAxes[current_axis].GetStateName() //+ " " + TrimAxes[current_axis].GetControlName()+ endl; if (TrimAxes[current_axis].GetStateType() == StateType.Qdot) { if (mode == TrimMode.Ground) { TrimAxes[current_axis].initTheta(); } } xlo = TrimAxes[current_axis].GetControlMin(); xhi = TrimAxes[current_axis].GetControlMax(); TrimAxes[current_axis].SetControl((xlo + xhi) / 2); TrimAxes[current_axis].Run(); //TrimAxes[current_axis].AxisReport(); sub_iterations[current_axis] = 0; successful[current_axis] = 0; solution[current_axis] = false; } if (mode == TrimMode.Pullup) { log.Debug("Setting pitch rate and nlf... "); setupPullup(); log.Debug("pitch rate done ... "); TrimAxes[0].SetStateTarget(targetNlf); log.Debug("nlf done"); } else if (mode == TrimMode.Turn) { setupTurn(); //TrimAxes[0].SetStateTarget(targetNlf); } do { axis_count = 0; for (current_axis = 0; current_axis < TrimAxes.Count; current_axis++) { SetDebug(); UpdateRates(); Nsub = 0; if (!solution[current_axis]) { if (CheckLimits()) { solution[current_axis] = true; Solve(); } } else if (FindInterval()) { Solve(); } else { solution[current_axis] = false; } sub_iterations[current_axis] += Nsub; } for (current_axis = 0; current_axis < TrimAxes.Count; current_axis++) { //these checks need to be done after all the axes have run if (Debug > 0) { TrimAxes[current_axis].AxisReport(); } if (TrimAxes[current_axis].InTolerance()) { axis_count++; successful[current_axis]++; } } if ((axis_count == TrimAxes.Count - 1) && (TrimAxes.Count > 1)) { //cout + TrimAxes.size()-1 + " out of " + TrimAxes.size() + "!" + endl; //At this point we can check the input limits of the failed axis //and declare the trim failed if there is no sign change. If there //is, keep going until success or max iteration count //Oh, well: two out of three ain't bad for (current_axis = 0; current_axis < TrimAxes.Count; current_axis++) { //these checks need to be done after all the axes have run if (!TrimAxes[current_axis].InTolerance()) { if (!CheckLimits()) { // special case this for now -- if other cases arise proper // support can be added to TrimAxis if ((gamma_fallback) && (TrimAxes[current_axis].GetStateType() == StateType.Udot) && (TrimAxes[current_axis].GetControlType() == ControlType.Throttle)) { if (log.IsErrorEnabled) { log.Error(" Can't trim udot with throttle, trying flight" + " path angle. (" + N + ")"); } if (TrimAxes[current_axis].GetState() > 0) { TrimAxes[current_axis].SetControlToMin(); } else { TrimAxes[current_axis].SetControlToMax(); } TrimAxes[current_axis].Run(); //TODO delete TrimAxes[current_axis]; TrimAxes[current_axis] = new TrimAxis(fdmex, fgic, StateType.Udot, ControlType.Gamma); } else { if (log.IsErrorEnabled) { log.Error(" Sorry, " + TrimAxes[current_axis].GetStateName() + " doesn't appear to be trimmable"); } //total_its=k; trim_failed = true; //force the trim to fail } //gamma_fallback } } //solution check } //for loop } //all-but-one check N++; if (N > max_iterations) { trim_failed = true; } } while ((axis_count < TrimAxes.Count) && (!trim_failed)); if ((!trim_failed) && (axis_count >= TrimAxes.Count)) { total_its = N; if (log.IsDebugEnabled) { log.Debug(" Trim successful"); } } else { total_its = N; if (log.IsDebugEnabled) { log.Debug(" Trim failed"); } } for (i = 0; i < fdmex.GroundReactions.NumGearUnits; i++) { fdmex.GroundReactions.GetGearUnit(i).SetReport(true); } fdmex.EnableOutput(); return(!trim_failed); #endif throw new NotImplementedException("Pending upgrade to lastest version of JSBSIM"); }