ferram4 / Ferram-Aerospace-Research

Aerodynamics model for Kerbal Space Program
Other
239 stars 131 forks source link

better RealChuteLite configs #104

Closed DaMichel closed 9 years ago

DaMichel commented 9 years ago

deployedDiameter and preDeployedDiameter are automatically scaled based on the part mass ratio to the Mk1Parachute.

Previously the chutes looked differently but this was just the model. Physics parameters were actually the same. Easy to test by free fall tests. Now terminal velocity is different for each chute.

ferram4 commented 9 years ago

Looking at this a little more closely, this shouldn't be possible; the RealChuteLite implementation includes code to estimate parachute diameters based on the drag cubes calculated by the stock game. In particular, it uses the values that are in PartDatabase.cfg for the SEMIDEPLOYED and DEPLOYED cubes. And I get different physics behavior from different chutes... you didn't delete the stock partdatabase.cfg at some point, did you?

DaMichel commented 9 years ago

Doh, didn't see this code. However, i got this NRE which i didn't notice either ...

NullReferenceException: Object reference not set to an instance of an object
  at FerramAerospaceResearch.RealChuteLite.ChuteCalculator.GetApparentDiameter (.DragCube cube) [0x00000] in <filename unknown>:0 

  at FerramAerospaceResearch.RealChuteLite.ChuteCalculator.Start () [0x00000] in <filename unknown>:0 

I checked, the references to DragCube semi, and deployed are null. Evidently PartDatabase.cfg is recreated automatically when it is not there. It has entries like this:

PART
{
    url = Squad/Parts/Utility/parachuteMk1/parachuteMk1/parachuteSingle
    DRAG_CUBE
    {
        cube = STOWED, 0.1568751,0.6572061,0.4137059, 0.1568751,0.6572724,0.4137059, 0.2767665,0.6422904,0.3861047, 0.2767665,0.8637785,0.176505, 0.1602633,0.6481676,0.614841, 0.1602633,0.6762733,0.6371409, 6.735325E-06,0.103434,0.01847693, 0.6306692,0.3626097,0.6123547
        cube = RCDEPLOYED, 0.1167979,0.6871887,0.4137059, 0.1167979,0.6871936,0.4137059, 0.2767665,0.6487702,0.2958369, 0.2767665,0.8637785,0.1775021, 0.1212076,0.677393,0.6180267, 0.1212076,0.702255,0.6466981, 6.750226E-06,0.0316802,0.01847693, 0.6306692,0.2191022,0.6123547
    }
}

For some odd reason there is neither SEMIDEPLOYED nor DEPLOYED. No idea what is going on. I removed all other mods except FAR (including my own rescales and things).

When i change the code to use RCDEPLOYED and STOWED, it works without NRE. But then the diameters become much too low, mostly below 1 m. Moreover, deployed and predeployed diameters are equal although the drag cubes are different.

After a bit more investigation, i think the problem might be related to https://github.com/ferram4/Ferram-Aerospace-Research/blob/garbage_reduction/FerramAerospaceResearch/RealChuteLite/RealChuteFAR.cs#L39 This line provides the return values for the GetDragCubeNames() API, however, DEPLOYED and SEMIDEPLOYED are omitted. (See IMultipleDragCube)

After even more investigations. I see that i have perfectly good

    MODULE
    {
        name = ModuleDragModifier
        dragCubeName = SEMIDEPLOYED
        dragModifier = 0.33
    }
    MODULE
    {
        name = ModuleDragModifier
        dragCubeName = DEPLOYED
        dragModifier = 12
    }

in my parachute part configs. Maybe the result of GetDragCubeNames() of RealCuteLite replaces the corresponding list of ModuleParachute. Unfortunately there is zero info on IMultipleDragCube available ...

ferram4 commented 9 years ago

All of that indicates that you're not using the partdatabase.cfg that comes stock with the game. Parachutes, like cargo bays and a few other weird parts have special modifications in there in order to provide proper behavior in game.

This is all very strange, and honestly I'm not sure of the correct changes to make. Most of this has been implemented by @StupidChris and I'm not sure of the exact way that everything functions.

DaMichel commented 9 years ago

No, this is the partdatabase.cfg that KSP generates after i deleted it! That is with FAR, ModuleManager and ModularFlightIntegrator installed.

Who would have thought! Here is a relevant section of partdatabase.cfg after getting Steam to update broken files.

PART
{
    url = Squad/Parts/Utility/parachuteMk1/parachuteMk1/parachuteSingle
    DRAG_CUBE
    {
        cube = PACKED, 0.1568751,0.6572061,0.4137059, 0.1568751,0.6572724,0.4137059, 0.2767665,0.6422904,0.3861047, 0.2767665,0.8637785,0.176505, 0.1602633,0.6481676,0.614841, 0.1602633,0.6762733,0.6371409, 6.735325E-06,0.103434,0.01847693, 0.6306692,0.3626097,0.6123547
        cube = SEMIDEPLOYED, 7.525329,0.2318662,0.5391445, 7.525329,0.227902,0.5391445, 0.5277259,0.06571814,4.172107, 0.5277259,0.1769343,14.9913, 7.588403,0.2288947,0.7006975, 7.588403,0.2283394,0.7967932, 6.556511E-07,8.838122,1.147389E-05, 0.8259839,17.83199,0.8210163
        cube = DEPLOYED, 72.87113,7.589109,4.578267, 72.87113,7.573455,4.578267, 52.80032,8.565606,4.172107, 52.80032,6.532588,14.9913, 73.68147,7.515025,4.551372, 73.68147,7.478681,4.551372, 6.67572E-06,8.838122,0.0001244545, 8.25984,17.83199,8.210144
    }
}

With a completely stock game, the file remains the same after launch.

Then i installed FAR Goldstein from the downloadable release zip on the github page. The result is that on launch partdatabase.cfg is replaced again with the faulty version, i.e.

PART
{
    url = Squad/Parts/Utility/parachuteMk1/parachuteMk1/parachuteSingle
    DRAG_CUBE
    {
        cube = STOWED, 0.1568751,0.6572061,0.4137059, 0.1568751,0.6572724,0.4137059, 0.2767665,0.6422904,0.3861047, 0.2767665,0.8637785,0.176505, 0.1602633,0.6481676,0.614841, 0.1602633,0.6762733,0.6371409, 6.735325E-06,0.103434,0.01847693, 0.6306692,0.3626097,0.6123547
        cube = RCDEPLOYED, 0.1167979,0.6871887,0.4137059, 0.1167979,0.6871936,0.4137059, 0.2767665,0.6487702,0.2958369, 0.2767665,0.8637785,0.1775021, 0.1212076,0.677393,0.6180267, 0.1212076,0.702255,0.6466981, 6.750226E-06,0.0316802,0.01847693, 0.6306692,0.2191022,0.6123547
    }
}

Here is my output_log.txt, in the hope that you can find something. https://www.dropbox.com/s/1odp1co80es7mvq/output_log.txt?dl=0 If not, well nevermind. I'll try to figure it out on my own. Well probably, i'll just take a break until Squad fixes some issues and hope it goes away on its own ;-)

ferram4 commented 9 years ago

Hmm, my version does not get changed like that. Very strange.

Hrm... possibly changing the code so that the SEMIDEPLOYED and DEPLOYED states remain to be picked up again would be a good choice. That would fix the bug entirely, I think.

DaMichel commented 9 years ago

At this point i'd love to know if there are other people with the same problem. I bet there are but they probably didn't notice.

I looked at what ModuleManager does. First, it can delete partdatabase.cfg. Secondly, MM seems to apply FAR patches correctly. I looked in ModuleManager.ConfigCache and found

UrlConfig
{
    name = parachuteSingle
    type = PART
    parentUrl = Squad/Parts/Utility/parachuteMk1/parachuteMk1
    url = Squad/Parts/Utility/parachuteMk1/parachuteMk1/parachuteSingle
    PART
    {
        name = parachuteSingle
        module = Part
        author = HarvesteR
        mesh = model.mu
        scale = 0.1
        node_stack_bottom = 0.0, -0.120649, 0.0, 0.0, -1.0, 0.0, 0
        node_attach = 0.0, -0.120649, 0.0, 0.0, -1.0, 0.0
        sound_parachute_open = activate
        sound_parachute_single = deploy
        TechRequired = start
        entryCost = 0
        cost = 422
        category = Utility
        subcategory = 0
        title = Mk16 Parachute
        description = The Mk16 Parachute might be considered by some to be little more than a random stitching together of the surplus parts it is, in fact, made from. But the fact remains that the Mk16 has been widely accepted as a generally better alternative to being in freefall.
        attachRules = 1,0,0,1,0
        mass = 0.1
        dragModelType = default
        angularDrag = 3
        crashTolerance = 12
        maxTemp = 2500
        emissiveConstant = 0.7
        stageOffset = -1
        bulkheadProfiles = size0, srf
        bodyLiftMultiplier = 0
        MODULE
        {
            name = ModuleParachute
            semiDeployedAnimation = semiDeploySmall
            fullyDeployedAnimation = fullyDeploySmall
            invertCanopy = true
            autoCutSpeed = 0.5
            capName = cap
            canopyName = canopy
            stowedDrag = 0
            semiDeployedDrag = 1
            fullyDeployedDrag = 500
            minAirPressureToOpen = 0.04
            clampMinAirPressure = 0.04
            deployAltitude = 1000
            deploymentSpeed = 0.12
            semiDeploymentSpeed = 0.5
            chuteMaxTemp = 650
        }
        MODULE
        {
            name = ModuleTestSubject
            environments = 4
            useStaging = True
            useEvent = False
        }
        MODULE
        {
            name = ModuleDragModifier
            dragCubeName = SEMIDEPLOYED
            dragModifier = 0.33
        }
        MODULE
        {
            name = ModuleDragModifier
            dragCubeName = DEPLOYED
            dragModifier = 12
        }
        MODULE
        {
            name = GeometryPartModule
        }
        MODULE
        {
            name = FARAeroPartModule
        }
        MODULE
        {
            name = RealChuteFAR
            semiDeployedAnimation = semiDeploySmall
            fullyDeployedAnimation = fullyDeploySmall
            invertCanopy = true
            autoCutSpeed = 0.5
            capName = cap
            canopyName = canopy
            stowedDrag = 0
            semiDeployedDrag = 1
            fullyDeployedDrag = 500
            minAirPressureToOpen = 0.04
            clampMinAirPressure = 0.04
            deployAltitude = 1000
            deploymentSpeed = 0.12
            semiDeploymentSpeed = 0.5
            chuteMaxTemp = 650
        }
        EFFECTS
        {
            rcpredeploy
            {
                AUDIO
                {
                    channel = Ship
                    clip = sound_parachute_open
                    volume = 1
                }
            }
            rcdeploy
            {
                AUDIO
                {
                    channel = Ship
                    clip = sound_parachute_single
                    volume = 1
                }
            }
            rccut
            {
                AUDIO
                {
                    channel = Ship
                    clip = FerramAerospaceResearch/RealChuteLite/Sounds/sound_parachute_cut
                    volume = 1
                }
            }
            rcrepack
            {
                AUDIO
                {
                    channel = Ship
                    clip = FerramAerospaceResearch/RealChuteLite/Sounds/sound_parachute_repack
                    volume = 1
                }
            }
        }
        MODULE
        {
            name = FARPartModule
        }
    }
}

So there is the stock module as well as RealCutes. I suppose this is intended, and i expect deployed and semideployed drag cubes to be created by the stock module.

Still not really a hint. Everything points to another strange stock quirk.

ferram4 commented 9 years ago

I have an idea. What might be happening is that KSP assumes that only one of the PartModules on a part will use IMultipleDragCube, and so when it goes to build them, only one of them is saved to the part database. So what's happening is the RCL module is overwriting what ModuleParachute wants to be there.

So a quick fix might be to simply set up the code to handle the deploy and semideploy animations properly, and possibly remove the stock ModuleParachute module (if need be). I'm not sure if it'll work, but it possibly could.

DaMichel commented 9 years ago

I had this idea, too. Something super strange is going on here. Have a look at this. I added some debug stuff to GetDragCubeNames() of RealChuteFAR.

        //Gives DragCube names
        public string[] GetDragCubeNames()
        {   
            Debug.Log("RealChuteLite: GetDragCubeNames on " + part.name);
            string[] result = cubeNames;
            foreach (PartModule mod in part.Modules)
            {
                IMultipleDragCube mdc = mod as IMultipleDragCube;
                Debug.Log("visit "+mod.GetType().ToString()+" "+(mdc==null ? "IMultipleDragCube missing" :  "ok"));
                if (mdc != null && mdc != this)
                {
                    result.AddUniqueRange(mdc.GetDragCubeNames());
                }
            }
            StringBuilder b = new StringBuilder();
            foreach (string s in result)
                b.Append(" "+s);
            Debug.Log("RealChuteLite: GetDragCubeNames -> "+b.ToString());
            return result;
        }

the result in output_log.txt is as follows (cleaned from line number spam). Also i deleted partdatabase.cfg beforehand.

PartLoader: Compiling Part 'Squad/Parts/Utility/parachuteMk1/parachuteMk1/parachuteSingle'
Added sound_parachute_open to FXGroup activate
PartLoader: Part 'Squad/Parts/Utility/parachuteMk1/parachuteMk1/parachuteSingle' has no database record. Creating.
DragCubeSystem: Creating drag cubes for part 'parachuteSingle'
RealChuteLite: GetDragCubeNames on parachuteSingle(Clone) Drag Rendering Clone
visit ModuleTestSubject IMultipleDragCube missing
visit ModuleDragModifier IMultipleDragCube missing
visit ModuleDragModifier IMultipleDragCube missing
visit FerramAerospaceResearch.FARPartGeometry.GeometryPartModule IMultipleDragCube missing
visit FerramAerospaceResearch.FARAeroComponents.FARAeroPartModule IMultipleDragCube missing
visit FerramAerospaceResearch.RealChuteLite.RealChuteFAR ok
visit ferram4.FARPartModule IMultipleDragCube missing
RealChuteLite: GetDragCubeNames ->  STOWED RCDEPLOYED

So ModuleParachute is not encountered. I doubt that this is the intended behavior of the game. But in the in-game config debug menu (F12 -> database -> configs), ModuleParachute is the first module in the configuration displayed.

ferram4 commented 9 years ago

Oh, I think I know what's up; OnLoad removes any ModuleParachutes that exist. Not sure why they're not removed in the MM configs, but I trust there's a sane reason for that.

I assume then that if that code runs without ModuleParachute code that we can add PACKED, SEMIDEPLOYED and DEPLOYED to the DragCube list (with code to set the part state the same as ModuleParachute would) and everything should be fine.

DaMichel commented 9 years ago

Okay. I guess ModuleParachutes is supposed to enable the creation of drag cubes for DEPLOYED and SEMIDEPLOYED states. I assume that MM would remove the Module too early. Then, when the game is finally initialized ModuleParachutes is ready to be removed since all of its other functions are superseded by RLC.

Except that it does not work for me ...

Just checked: as guessed, MM stuff is spammed in output_log.txt before the drag cube stuff comes.

I agree on the last part. We should try that. Then we could just remove ModuleParachute with a MM config. It seems more robust and the game will more likely end up in a nice consistent state.

DaMichel commented 9 years ago

Uhm yeah, OnLoad of RCL is called before DragCubeSystem: Creating drag cubes for part 'parachuteSingle is printed.

DaMichel commented 9 years ago

I attempted to handle all of the deployment states via RCL. It appears to work for me. Parachutes deploy in flight and they are different from one another. However, i don't really know what i'm doing. The code is still full of commented out debug statements. Sorry about that.

https://github.com/DaMichel/Ferram-Aerospace-Research/commit/52b7e8e777b64c3e457ed6bc316068b3c6f85ae2

It needs a rebase, too. Do you want me to clean this up for a PR?

ferram4 commented 9 years ago

It looks good, except for the specifics of the animation details.

I'd say that the speeds have to be set to 0 for each one, remember that we don't want them animating for any of this. I'd also say to have every block with full deployment to set the semideployment animation to 0, every block with semideployment to set the full deployment to 0, and for anything with neither to set both animations to 0. That'll ensure no weird edge-cases in the order of operations going on here.

Otherwise, yeah, clean it up and make it a PR.