public void Reset()
 {
     // lambda and lambdaDot are deliberately not cleared here
     //Debug.Log("call stack: + " + Environment.StackTrace);
     if (p != null)
     {
         p.KillThread();
         p = null;
     }
     status              = PVGStatus.INITIALIZING;
     last_stage_time     = 0.0;
     last_optimizer_time = 0.0;
     last_coasting_time  = 0.0;
     last_success_time   = 0.0;
     autowarp            = false;
     if (!MuUtils.PhysicsRunning())
     {
         core.warp.MinimumWarp();
     }
 }
Exemplo n.º 2
0
        private void converge()
        {
            if (p == null)
            {
                status = PVGStatus.INITIALIZING;
                return;
            }

            if (p.last_success_time > 0)
            {
                last_success_time = p.last_success_time;
            }

            // FIXME: should make this use wall clock time rather than simulation time and drop it down to
            // 10 seconds or so (phys warp means that this timeout could be 1/4 of the wall time and the
            // optimizer may commonly take 3-4 seconds to reconverge in a suboptimal setting -- TF failure case, etc)
            if (p.running_time(vesselState.time) > 30)
            {
                p.KillThread();
                p.last_failure_cause = "Optimizer watchdog timeout"; // bit dirty poking other people's data
            }

            if (p.solution == null)
            {
                /* we have a solver but no solution */
                status = PVGStatus.INITIALIZING;
            }
            else
            {
                /* we have a solver and have a valid solution */
                if (isTerminalGuidance())
                {
                    return;
                }

                /* hardcoded 10 seconds of terminal guidance */
                if (tgo < 10)
                {
                    // drop out of warp for terminal guidance (smaller time ticks => more accuracy)
                    core.warp.MinimumWarp();
                    status = PVGStatus.TERMINAL;
                    return;
                }
            }

            if ((vesselState.time - last_optimizer_time) < MuUtils.Clamp(pvgInterval, 1.00, 30.00))
            {
                return;
            }

            // if we have unstable ullage then continuously update the "staging" timer until we are not
            if ((vesselState.lowestUllage < VesselState.UllageState.Stable) && !isCoasting())
            {
                last_stage_time = vesselState.time;
            }

            if (p.solution != null)
            {
                // The current_tgo is the "booster" stage of the solution, it is allowed to go negative, for staging freeze
                // running the optimizer for 4 seconds on either side of staging.
                if (Math.Abs(p.solution.current_tgo(vesselState.time)) < 4)
                {
                    return;
                }

                // Also if we just triggered a KSP stage separation or just started coasting, then wait for 4 seconds for
                // stats to settle before running the optimizer again.
                if (vesselState.time < last_stage_time + 4)
                {
                    return;
                }
            }

            p.threadStart(vesselState.time);
            //if ( p.threadStart(vesselState.time) )
            //Debug.Log("MechJeb: started optimizer thread");

            if (status == PVGStatus.INITIALIZING && p.solution != null)
            {
                status = PVGStatus.CONVERGED;
            }

            last_optimizer_time = vesselState.time;
        }