MechJeb2

MechJeb2

4M Downloads

Agressive staging in FuelFlowSimulation causes missed manuover node execution

codepoetpbowden opened this issue ยท 1 comments

commented

I have been having a problem with MechJeb 2.0.9 - let me explain:
I have a craft that uses checmical rockets to get into orbit, electric propulsion to travel to a celestial body with an atmosphere (ie laythe), enter the atmosphere, decend (fast) on parachutes and then just before impact fire final stage of 2 seperatons to slow for impact. The electric propulsion is built into the craft that will decend. The craft file is here: http://pastebin.com/RF2TXW8f
The problem is that when I come to execute manuover nodes (which with the ion engine will take a long time) rather than starting at -10m as I would have expected, mechjeb starts the manuover at -2s. I looked into it and believe that this problem could be overcome with a change in FuelFlowSimulation::AllowedToStage. There is an assumption that if a stage is not being removed from the craft, then it is OK to stage even if it has not spent all its fuel. (as a side issue this has always annoyed me as it means that if I have a stage for seperating fairings, and another for releasing the cargo, the fairings will get released as soon as the previous stage is active). In this scenario the problem that it causes is that the fuel flow simulation fires the seperatrons as soon as the electric engine becomes active. As a consequence it considers that the craft is going to have a much higher TWR than it will with just the ion engine, and so it does not start the manuover until it is too late.
You can see what it is thinking by looking at the delta-v table that it comes up with for the whole craft. I wouls have expected the ion delta-v to show up in stage 2, but it as all been moved to to stage0. See here: http://s2.postimg.org/ato04tu6x/screenshot46.png

I believe that I can fix the problem by changing the method to be:

    //Whether we've used up the current stage
    public bool AllowedToStage()
    {
        //Debug.Log("Checking whether allowed to stage at t = " + t);

        List<FuelNode> activeEngines = FindActiveEngines();

        //Debug.Log("  activeEngines.Count = " + activeEngines.Count);

        //if no engines are active, we can always stage
        if (activeEngines.Count == 0)
        {
            //Debug.Log("Allowed to stage because no active engines");
            return true;
        }

        var burnedResources = activeEngines.SelectMany(eng => eng.BurnedResources()).Distinct();

        //if staging would decouple an active engine or non-empty fuel tank, we're not allowed to stage
        foreach (FuelNode n in nodes)
        {
            //Debug.Log(n.partName + " is sepratron? " + n.isSepratron);
            if (n.decoupledInStage == (simStage - 1) && !n.isSepratron)
            {
                if (activeEngines.Contains(n) || n.ContainsResources(burnedResources))
                {
                    //Debug.Log("Not allowed to stage because " + n.partName + " either contains resources or is an active engine");
                    return false;
                }
            }
        }

        // We are not allowed to stage if there is an active engine that still has access to resources
        foreach (FuelNode n in nodes)
        {
            if (activeEngines.Contains(n))
            {
                if (n.CanDrawNeededResources(nodes))
                {
                    Debug.Log("Not allowed to stage because " + n.partName + " is an active engine that still has resources to draw on.");
                    return false;
                }
            }
        }

        //if this isn't the last stage, we're allowed to stage because doing so wouldn't drop anything important
        if (simStage > 0)
        {
            //Debug.Log("Allowed to stage because this isn't the last stage");
            return true;
        }

        //Debug.Log("Not allowed to stage because there are active engines and this is the last stage");

        //if this is the last stage, we're not allowed to stage while there are still active engines
        return false;
    }

This change makes the delta-v table look like this: http://s10.postimg.org/8t84eo30p/screenshot46.png
and crucially the manuover nodes are executed acurately and in good time.

commented

Created a pull request for this issue, and changed the proposed solution too.