Jump to content

RzTen1

Members
  • Posts

    33
  • Joined

  • Last visited

Posts posted by RzTen1

  1. I've applied the Toolbar fix from the pull request, but it looks like KeepFit is still failing to startup properly on 1.2.  I'm seeing this in the log:

    Spoiler

    [LOG 18:27:42.670] 10/26/2016 6:27:42 PM,KeepFitScenarioModule,Constructor,.
    [LOG 18:27:42.672] 10/26/2016 6:27:42 PM,KeepFitScenarioModule,OnAwake,Scene[SPACECENTER]
    [EXC 18:27:42.680] NotSupportedException: The invoked member is not supported in a dynamic module.
        System.Reflection.Emit.AssemblyBuilder.GetExportedTypes ()
        KeepFit.CLSClient+<>c.<GetCLS>b__2_0 (.LoadedAssembly a)
        System.Linq.Enumerable+<CreateSelectManyIterator>c__Iterator12`2[AssemblyLoader+LoadedAssembly,System.Type].MoveNext ()
        System.Linq.Enumerable.Single[Type] (IEnumerable`1 source, System.Func`2 predicate, Fallback fallback)
        System.Linq.Enumerable.SingleOrDefault[Type] (IEnumerable`1 source, System.Func`2 predicate)
        KeepFit.CLSClient.GetCLS ()
        KeepFit.KeepFitScenarioModule.OnAwake ()
        ScenarioModule.Awake ()
        UnityEngine.GameObject:AddComponent(Type)
        ScenarioRunner:AddModule(String)
        ScenarioRunner:AddModule(ConfigNode)
        ProtoScenarioModule:Load(ScenarioRunner)
        ScenarioRunner:LoadModules(List`1)
        ScenarioRunner:SetProtoModules(List`1)
        Game:Load()
        <Start>c__IteratorC0:MoveNext()
        UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
    [LOG 18:27:42.683] 10/26/2016 6:27:42 PM,GameConfig,Load,configNodeName[KeepFitSavedGameSettings]
    [LOG 18:27:42.685] 10/26/2016 6:27:42 PM,GameConfig,Load,load complete [succeeded]
    [LOG 18:27:42.685] 10/26/2016 6:27:42 PM,KeepFitScenarioModule,OnLoad: ,Loaded gameConfig
    [ERR 18:27:42.686] Exception loading ScenarioModule KeepFitScenarioModule: System.NullReferenceException: Object reference not set to an instance of an object
      at KeepFit.KeepFitScenarioModule.OnLoad (.ConfigNode gameNode) [0x00000] in <filename unknown>:0 
      at ScenarioModule.Load (.ConfigNode node) [0x00000] in <filename unknown>:0 
      at ScenarioRunner.AddModule (.ConfigNode node) [0x00000] in <filename unknown>:0 

    I don't have Connected Living Space loaded.  If I modify the GetCLS() function to always return null, both errors disappear and the button appears as expected.  I suspect loading CLS would also fix the issue.

  2. I just wanted to give you a heads up, it looks like Final Frontier is conflicting with the new Contract Configurator:

    Spoiler

    [ERR 16:31:24.994] Exception handling event onGUIApplicationLauncherReady in class FinalFrontier:System.NotSupportedException: The invoked member is not supported in a dynamic module.
      at System.Reflection.Emit.AssemblyBuilder.GetExportedTypes () [0x00000] in <filename unknown>:0
      at FinalFrontierAdapter.ToolbarTypes.<getType>b__0 (.LoadedAssembly a) [0x00000] in <filename unknown>:0
      at System.Linq.Enumerable+<CreateSelectManyIterator>c__Iterator12`2[AssemblyLoader+LoadedAssembly,System.Type].MoveNext () [0x00000] in <filename unknown>:0
      at System.Linq.Enumerable.Single[Type] (IEnumerable`1 source, System.Func`2 predicate, Fallback fallback) [0x00000] in <filename unknown>:0
      at System.Linq.Enumerable.SingleOrDefault[Type] (IEnumerable`1 source, System.Func`2 predicate) [0x00000] in <filename unknown>:0
      at FinalFrontierAdapter.ToolbarTypes.getType (System.String name) [0x00000] in <filename unknown>:0
      at FinalFrontierAdapter.GameScenesVisibility..ctor (.GameScenes[] gameScenes) [0x00000] in <filename unknown>:0
      at Nereid.FinalFrontier.FinalFrontier.AddBlizzysToolbarButtons () [0x00000] in <filename unknown>:0
      at Nereid.FinalFrontier.FinalFrontier.OnGUIAppLauncherReady () [0x00000] in <filename unknown>:0
      at EventVoid.Fire () [0x00000] in <filename unknown>:0

    It looks like this is due to an out of date dependency in blizzy toolbar.  More info and the code to fix it is here:

    The merge in question is here: https://github.com/blizzy78/ksp_toolbar/commit/141485a715d11ac3d15d8d6f0ffafe5a01d853ba

  3. 8 hours ago, tjt said:

    I have a long term mission ship that's experiencing boil-off despite having powered cryo-tanks. Sounds like it's the bug mentioned above. Is there some way I can turn that off at least until you fix the Mod? I'd hate to have my team stranded in deep space. :)

    Thanks

    If you don't mind editing your save file, you can change all the occurrences of 'BoiloffOccuring = True' to 'BoiloffOccuring = False' to stop it from happening.

    You'll need to do that again if you lose and regain power though.  Make sure you make a copy of the file before changing it.

  4. Holy crap those magnetic fields are amazing.

    I have some news from the Cryo thread.  It looks like EC should be constant:
     

    On Monday, August 01, 2016 at 0:20 AM, Nertea said:

    Ec usage is constant no matter what the amount in the tank is, so that's not a problem if I'm understanding you right. 

    On Monday, August 01, 2016 at 4:20 PM, RzTen1 said:

    Shouldn't this code segment cause the EC usage to vary depending on tank volume?
    https://github.com/ChrisAdderley/CryoTanks/blob/master/Source/ModuleSimpleBoiloff.cs#L86
    coolingCost = fuelAmount/1000.0 * CoolingCost;

    9 hours ago, Nertea said:

    That does seem to reveal a bug - that code is supposed to only run on OnStart to configure the total energy use. However it's supposed to operate on max fuel amount, not fuel amount. Good find. 

  5. 15 hours ago, Nertea said:

    Ec usage is constant no matter what the amount in the tank is, so that's not a problem if I'm understanding you right.

    Shouldn't this code segment cause the EC usage to vary depending on tank volume?
    https://github.com/ChrisAdderley/CryoTanks/blob/master/Source/ModuleSimpleBoiloff.cs#L86
    coolingCost = fuelAmount/1000.0 * CoolingCost;

    I don't see it getting redefined anywhere but I could be reading it wrong.

  6. 11 hours ago, ShotgunNinja said:

    @RzTen1 Just checked, cryotank also calculate this when you load the vessel:

    
    coolingCost = fuelAmount/1000.0 * CoolingCost;

    that is then used in the calculation you mention, and in fact the one done by Kerbalism is equivalent.

    I realize that but that doesn't seem to be the way CryoTanks actually works:
    20160730142651_1.jpg

    I tried unloading and reloading the vessel on the off chance it ONLY computes this on load, and it still remains at 9.72ec/s even with the tank almost empty.

    I'm not sure if this is intentional or not, there were major changes in Cryo recently and I think the version in GitHub looks to be out of date.  I see strings in the compiled dll that aren't present in the GitHub source.  I'll mention this in the NearFuture thread as well.

  7. 4 hours ago, ShotgunNinja said:

    New release, mostly bugfixes: 1.0.8

      - fix: wrong amount of ec consumed by cryotank background simulation

    I'm still having the EC drain issue with 1.0.8.  It looks like it may be this:

    Kerbalism computes the EC cost on the Cryo Tanks as follows:
    ec.Consume(cooling_cost * fuel.amount * 0.001 * elapsed_s)

    SimpleBoiloff uses:
    part.RequestResource("ElectricCharge", coolingCost * TimeWarp.fixedDeltaTime)

    I'm not sure why Simple doesn't include the amount of fuel in the energy calculation, but that seems to be what's throwing it off.

  8. I think I may have found an issue with Kerbalism's background processing.  If I put use the CryoTanks from NearFuture the power draw in simulation and in the background are totally different.  In sim it works normally and matches the VAB but when I switch back to the space center the batteries flat line in a couple of seconds.

    The helper in the VAB is showing perpetual power.  The issue occurs with both reactors and solar panels.  If I remove Kerbalism the problem no longer occurs, so I don't think it's a NearFuture issue.

  9. Hi.  I think I may have found a bug in SimpleBoiloff in the CryoTanks part of the mod.  It looks like whenever a tank stops cooling when it's re-enabled (or re-powered) it never stops boiling off.  It persists across scene changes as well.  The GUI shows that the tanks are insulated but there is still a drain shown in the resource panel equal to when the tank was uninsulated.

    BoiloffOccuring appears to be getting set when cooling stops and then never getting unset. I poked around the repo to try and pin it down but I can't find the 'BoiloffOccuring' string anywhere.  I'm using 0.3.5.

  10. Hi, I just switched to 0.9.9.5 and I've noticed an odd bug with time compression.   When at 1000x or lower, oxygen and food deplete at the rates shown on right click vessel status menu, but going faster than 1000x appears to cause oxygen to drain at a vastly increased rate.

    On my current test craft I've got 14days of food and 17days of oxygen left, but if I accelerate time to 10000x I'll run out of air in 4-5 days.  That's the amount of time reported with the scrubber disabled, so it looks like it may be cutting out.  I've got enough power and I'm not getting any alarms until oxygen gets low.

    Edit: Also it looks like it's doing the same thing in the tracking station.

  11. I noticed that DMagic and UniversalStorage parts aren't getting the ScienceTweaks the stock parts are getting.  This appears to be due to DMagic using DMModuleScienceAnimate instead of ModuleScienceExperiment.  Changing the ScienceTweaks.cfg file from ModuleScienceExperiment to *Science* fixes this issue.

    Here's the top of the file with the changes in it:

    Spoiler

    // ============================================================================
    // Experiments data is either transmissible completely or not at all
    // ============================================================================


    @PART[*]:HAS[@MODULE[*Science*]]:FOR[Kerbalism]
    {
      @MODULE[*Science*]:HAS[#experimentID[crewReport]]
      {
        @xmitDataScalar = 1
      }

      @MODULE[*Science*]:HAS[#experimentID[evaReport]]
      {
        @xmitDataScalar = 1
      }

      @MODULE[*Science*]:HAS[#experimentID[mysteryGoo]]
      {
        @xmitDataScalar = 0
      }

      @MODULE[*Science*]:HAS[#experimentID[surfaceSample]]
      {
        @xmitDataScalar = 0
      }

      @MODULE[*Science*]:HAS[#experimentID[mobileMaterialsLab]]
      {
        @xmitDataScalar = 0
      }

      @MODULE[*Science*]:HAS[#experimentID[temperatureScan]]
      {
        @xmitDataScalar = 1
      }

      @MODULE[*Science*]:HAS[#experimentID[barometerScan]]
      {
        @xmitDataScalar = 1
      }

      @MODULE[*Science*]:HAS[#experimentID[seismicScan]]
      {
        @xmitDataScalar = 1
      }

      @MODULE[*Science*]:HAS[#experimentID[gravityScan]]
      {
        @xmitDataScalar = 1
      }

      @MODULE[*Science*]:HAS[#experimentID[atmosphereAnalysis]]
      {
        @xmitDataScalar = 1
      }
    }

     

     

  12. 5 hours ago, Box of Stardust said:

    The antenna ranges are actually noted in set distances (Mm). The quic tool tip (Our planetary system) entails just the Kerbin system.

    Ah, I found it.  I wasn't expecting it to be on the right click menu after it had been attached.

    Do you think you could add base ranges to the right click description in the builder?  It would make things easier to compare without having to attach every antenna to the craft.

  13. Hi.  I just switched to this mod since TAC isn't working in 1.1 yet and I gotta say it's pretty awesome.  :)

    I had one comments: It would be nice if the status window shows which parts are broken on the dropdown, or they glowed a bit like in DangIt.  It's a bit of a pain to find which solar panel has failed on a craft that has 20 of them.

    Also, do the antenna's have different ranges now?  It's not clear what the range is from the description and it kinda looks like the basic antenna will work for the entire solar system.  I'm not sure if that's correct, but I did like the part of RT that longer ranges required bigger dishes.

  14. 3 hours ago, FreeThinker said:

    Thanks. I think I will also add Lithium to other tanks as it will become a important propellant for fusion propulsion

    What is interesting is that I read that aluminum could also be used as an alternative for lithium when used as a propellant,,  which is great as aluminum  stuff is much  cheaper and easier to be found in the wild.like on our own moon

    Aluminum would be a pretty interesting propellant.  I think it'd make even more sense to have some sort of hot-tank for it as the melting point is quite a bit higher than lithium.  Plus, it'd be interesting to have something generate wasteheat that wasn't an engine or reactor/generator.

    Btw, that new engine is pretty awesome looking.  :)

  15. I've submitted a pull request with a recommendation on SETI and power usage that hopefully looks good.  I've also figured out my issue with the lithium radial can:

    It looks like all the other hex cans have an attachment rules of 1,1,1,1,0.  The lithium can has "attachRules = 1,0,1,1,0".  The second bit allows surface mounting, which is what I was trying to do.  I was also wondering if the can should actually draw power since lithium doesn't actually melt until its temperature exceeds 180C.  Even with full solar exposure it would have to be heated, not to mention if it's in shadow.  It might be interesting if the can acted more like a cryo tank except instead of boiling off it just stopped providing fuel if power ran out.

  16. Yep, it's this section that's doing it: (Patches/USI_NF_Mode.cfg)

    @PART[*]:HAS[@MODULE[FNAntimatterReactor]]:NEEDS[NearFutureElectrical|SETI]:FOR[WarpPlugin]
    {
            @MODULE[FNAntimatterReactor]
            {
                    @upgradedPowerOutput *= 0.002
                    @neutronEmbrittlementDivider *= 0.002
                    %fuelUsePerMJMult = 500
                    %wasteHeatMultiplier = 0.002
                    %powerOutputMultiplier = 0.002
            }
    }

    Should this be making the change for SETI as well?  I understand tweaking the values if NearFuture is there so that it's more in line with their reactors, but I don't believe vanilla SETI is changing any power/thermal numbers.  It also seems somewhat inconsistent as it's only tweaking some of the reactors (looks like just the anti-mater) but not all of them.  Plus, with these settings thermal nozzles would need a massive boost to be even minimally useful.

  17. 20 hours ago, FreeThinker said:

    Are you sure you haven't installed NFT-E or SETI? it reduces all reactors power by a factor 500. But I will verify the 2 Antimatter reactor still work. Something might have broken

    I had removed SETI, but I missed one of the contract packs for it.  I've narrowed it down to this section of module-manager code from SETI-Contracts:

    @CONTRACT_TYPE[KerbinLanding]:FOR[SETI]:NEEDS[RealChute]
    {
    }

    Yes, seriously, just that.  If I comment those three line out, I get 120GW.  Load it back in and the antimater reactor drops to 480KW.  I don't see anything in the module manager that would account for this behavior.  Even more oddly, only pre-1.7.0(e) appears to have issues. 1.6.9 works regardless of this patch existing.  I've tried both my local compiled copy and the one from git and they both do the same thing.

    Best guess:  FOR[SETI] causes MM to set the flag that indicates that SETI is installed, even though it isn't.  Another config file has to be changing the reactor values.

  18. NFT-E wasn't installed but SETI was.  I pulled it and nothing changed so I pulled almost every other mod I had loaded and the numbers went back to normal.  Something else appears to be messing with just those three reactors for some reason, I'll try and track that down later.

    I still can't get the lithium radial to attach though.  Is there another tank that will accept lithium?

  19. I noticed some weirdness in the current build.  I'm getting correct thrust numbers for everything I've thrown at it, but three reactors are acting up:

    1. The 'Reactor: Antimatter' reactor is only generating 480KW of power.  The thermal mechanics helper and the reactor control panel both show the same numbers.
    2. The 'Antimatter Initiated Fusion Reactor' is only generating 81KW.  Same as above in the helper/panel.
    3. The 'Magneto Internal Fusion Reactor' is generating 13.5MW, which seems correct, but the thermal nozzle will only accept Lithium as the fuel source.  I can't get the Lithium cans to attach for some reason, so I can't test with it.

    The 'Magnetic Confinement Fusion Reactor' seems unaffected and is generating an expected 27MW.

    Also both generators seem to have issues attaching to the rocket:
    floaty.png

     

  20. I wasn't all that happy with the prior code I submitted, it was close but still off in odd ways depending on engine/reactor combo, so I've redone all of it.  Orbital thrust and isp now match exactly with actual in game values.  Atmospheric readings are still off by a couple of percent, but that seems to be due to the EarthAtmospherePressureAtSeaLevel constant reading 101.325 while I get closer to 100 on the pad.  In any case, atmospheric is much better and actually usable for orbital insertion calculations.

    I also redid the section for BetterBurnTime to accurately calculate the actual maximum thrust so that it matches in flight values exactly.

    Buoyancy calculations are still missing, so the open gas core reactor's numbers are optimistic at best.

    Here is a diff compared to the current version in github (the last commit added my first patch attempt).  A new vairable has been added to both in-flight sections to avoid stepping on other code, calculatedMaxThrust.  This will contain the maximum thrust at full throttle for the engine at the current altitude both while running and idle, as long as the engine is active.

    Spoiler

    diff -ub ThermalNozzleController.cs ThermalNozzleController.cs.new
    --- ThermalNozzleController.cs  2016-03-17 23:26:59.994654300 -0600
    +++ ThermalNozzleController.cs.new      2016-03-17 23:27:04.141891500 -0600
    @@ -875,11 +875,33 @@
                 {
                     _maxISP = Mathf.Sqrt(AttachedReactor.CoreTemperature) * (PluginHelper.IspCoreTempMult + IspTempMultOffset) * GetIspPropellantModifier();

    -                float thrust = GetPowerThrustModifier() * GetHeatThrustModifier() * AttachedReactor.MaximumPower / _maxISP / PluginHelper.GravityConstant * GetHeatExchangerThrustDivisor() * _thrustPropellantMultiplier;
    +                float thrust = GetPowerThrustModifier() * GetHeatThrustModifier() * AttachedReactor.MaximumPower / _maxISP / PluginHelper.GravityConstant * GetHeatExchangerThrustDivisor();
    +                float max_thrust_in_space = thrust;
    +                thrust *= _thrustPropellantMultiplier;
                     myAttachedEngine.maxFuelFlow = thrust / (PluginHelper.GravityConstant * _maxISP);
                     myAttachedEngine.maxThrust = thrust;

    -                _minISP = _maxISP * ((thrust - maxPressureThresholdAtKerbinSurface) / thrust) * GetHeatExchangerThrustDivisor();
    +                //_minISP = _maxISP * ((thrust - maxPressureThresholdAtKerbinSurface) / thrust) * GetHeatExchangerThrustDivisor();
    +                //atmospherecurve.Add(0, _maxISP, 0, 0);
    +                //atmospherecurve.Add(1, _minISP, 0, 0);
    +
    +                float max_thrust_in_current_atmosphere = max_thrust_in_space;
    +
    +                // update engine thrust/ISP for thermal noozle
    +                if (!_currentpropellant_is_jet)
    +                {
    +                    pressureTreshold = exitArea * (float)GameConstants.EarthAtmospherePressureAtSeaLevel;
    +                    if (_maxISP > GameConstants.MaxThermalNozzleIsp )
    +                        pressureTreshold *= 10;
    +
    +                    max_thrust_in_current_atmosphere = max_thrust_in_space - pressureTreshold;
    +
    +                    var thrustAtmosphereRatio = max_thrust_in_space > 0 ? Math.Max(max_thrust_in_current_atmosphere / max_thrust_in_space, 0.01 ) : 0.01;
    +                    _minISP = _maxISP * (float)thrustAtmosphereRatio;
    +                }
    +                else
    +                    _minISP = _maxISP;
    +
                     atmospherecurve.Add(0, _maxISP, 0, 0);
                     atmospherecurve.Add(1, _minISP, 0, 0);

    @@ -988,19 +1010,26 @@

                     _maxISP = (float)(Math.Sqrt((double)AttachedReactor.CoreTemperature) * (PluginHelper.IspCoreTempMult + IspTempMultOffset) * GetIspPropellantModifier());

    -                expectedMaxThrust = (float)(AttachedReactor.MaximumPower * GetPowerThrustModifier() * GetHeatThrustModifier() / PluginHelper.GravityConstant / _maxISP);
    +                expectedMaxThrust = (float)(AttachedReactor.MaximumPower * GetPowerThrustModifier() * GetHeatThrustModifier() / PluginHelper.GravityConstant / _maxISP * (float)GetHeatExchangerThrustDivisor());
    +                float calculatedMaxThrust = expectedMaxThrust;
                     expectedMaxThrust *= _thrustPropellantMultiplier * (1f - sootAccumulationPercentage / 200f);

    -                myAttachedEngine.maxThrust = expectedMaxThrust;
    -
    -                // suggested by RzTen1 to improve compatibility with BetterBurnTime
                     max_fuel_flow_rate = (float)(expectedMaxThrust / _maxISP / PluginHelper.GravityConstant);

    -                pressureTreshold = _currentpropellant_is_jet ? 0 : exitArea * (float)FlightGlobals.getStaticPressure(vessel.transform.position);
    +                if (!_currentpropellant_is_jet)
    +                {
    +                    pressureTreshold = exitArea * (float)FlightGlobals.getStaticPressure(vessel.transform.position);
    +                    if (_maxISP > GameConstants.MaxThermalNozzleIsp)
    +                        pressureTreshold *= 10;
    +                }
    +                else
    +                    pressureTreshold = 0;

                     var thrustAtmosphereRatio = expectedMaxThrust <= 0 ? 0 : Math.Max(0, expectedMaxThrust - pressureTreshold) / expectedMaxThrust;

                     current_isp = _maxISP * (float)thrustAtmosphereRatio;
    +                calculatedMaxThrust -= pressureTreshold;
    +                calculatedMaxThrust *= (float)_thrustPropellantMultiplier * (1f - sootAccumulationPercentage / sootThrustDivider);

                     FloatCurve newISP = new FloatCurve();
                     var effectiveIsp = isJet ? Mathf.Min(current_isp, PluginHelper.MaxThermalNozzleIsp) : current_isp;
    @@ -1012,8 +1041,12 @@
                         double vcurve_at_current_velocity = myAttachedEngine.velCurve.Evaluate((float)vessel.srf_velocity.magnitude);

                         if (vcurve_at_current_velocity > 0 && !double.IsInfinity(vcurve_at_current_velocity) && !double.IsNaN(vcurve_at_current_velocity))
    +                    {
                             max_fuel_flow_rate = (float)(max_fuel_flow_rate / vcurve_at_current_velocity);
    +                        calculatedMaxThrust = calculatedMaxThrust / (float)vcurve_at_current_velocity;
    +                    }
                     }
    +                myAttachedEngine.maxThrust = calculatedMaxThrust > 0 ? calculatedMaxThrust : 0;

                     // set engines maximum fuel flow
                     myAttachedEngine.maxFuelFlow = Math.Min(1000f, (float)max_fuel_flow_rate);
    @@ -1072,11 +1105,13 @@
                 heatExchangerThrustDivisor = (float)GetHeatExchangerThrustDivisor();
                 radiusModifier = (heatExchangerThrustDivisor * 100).ToString("0.00") + "%";
                 engineMaxThrust = 0.01f;
    +            float calculatedMaxThrust = 0;
                 if (_availableThermalPower > 0)
                 {
                     var ispRatio = _currentpropellant_is_jet ? current_isp / _maxISP : 1;
                     var thrustLimit = myAttachedEngine.thrustPercentage / 100.0f;
                     engineMaxThrust = (float)Math.Max(thrustLimit * GetPowerThrustModifier() * GetHeatThrustModifier() * thermal_power_received / _maxISP / PluginHelper.GravityConstant * heatExchangerThrustDivisor * ispRatio / myAttachedEngine.currentThrottle, 0.01);
    +                calculatedMaxThrust = GetPowerThrustModifier() * GetHeatThrustModifier() * AttachedReactor.MaximumPower / _maxISP / PluginHelper.GravityConstant * heatExchangerThrustDivisor * ispRatio;
                 }

                 max_thrust_in_space = engineMaxThrust / myAttachedEngine.thrustPercentage * 100;
    @@ -1097,13 +1132,21 @@
                     var thrustAtmosphereRatio = max_thrust_in_space > 0 ? Math.Max(max_thrust_in_current_atmosphere / max_thrust_in_space, 0.01 ) : 0.01;
                     UpdateIspEngineParams(thrustAtmosphereRatio);
                     current_isp = _maxISP * (float)thrustAtmosphereRatio;
    +                calculatedMaxThrust -= pressureTreshold;
                 }
                 else
                     current_isp = _maxISP;

    -            final_max_engine_thrust = !Single.IsInfinity(max_thrust_in_current_atmosphere) && !Single.IsNaN(max_thrust_in_current_atmosphere)
    -                ? max_thrust_in_current_atmosphere * _thrustPropellantMultiplier * (1f - sootAccumulationPercentage / sootThrustDivider)
    -                : 0.000001f;
    +            if (!Single.IsInfinity(max_thrust_in_current_atmosphere) && !Single.IsNaN(max_thrust_in_current_atmosphere))
    +            {
    +                final_max_engine_thrust = max_thrust_in_current_atmosphere * _thrustPropellantMultiplier * (1f - sootAccumulationPercentage / sootThrustDivider);
    +                calculatedMaxThrust *= (float)_thrustPropellantMultiplier * (1f - sootAccumulationPercentage / sootThrustDivider);
    +            }
    +            else
    +            {
    +                final_max_engine_thrust = 0.000001f;
    +                calculatedMaxThrust = final_max_engine_thrust;
    +            }

                 // amount of fuel being used at max throttle with no atmospheric limits
                 if (_maxISP <= 0) return;
    @@ -1116,10 +1159,17 @@
                     vcurveAtCurrentVelocity = myAttachedEngine.velCurve.Evaluate((float)(vessel.speed / vessel.speedOfSound));

                     if (vcurveAtCurrentVelocity > 0 && !double.IsInfinity(vcurveAtCurrentVelocity) && !double.IsNaN(vcurveAtCurrentVelocity))
    +                {
                         max_fuel_flow_rate = (float)(max_fuel_flow_rate * vcurveAtCurrentVelocity);
    +                    calculatedMaxThrust *= (float)vcurveAtCurrentVelocity;
    +                }
                     else
    +                {
                         max_fuel_flow_rate = 0.000001f;
    +                    calculatedMaxThrust = 0;
    +                }
                 }
    +            myAttachedEngine.maxThrust = calculatedMaxThrust > 0 ? calculatedMaxThrust : 0;

                 if (atmospheric_limit > 0 && atmospheric_limit != 1 && !double.IsInfinity(atmospheric_limit) && !double.IsNaN(atmospheric_limit))
                     max_fuel_flow_rate = max_fuel_flow_rate * atmospheric_limit;

     

    In case that's hard to read, here are the changed functions in their entirety.

    EstimateEditorPerformance:
     

    Spoiler

            public void EstimateEditorPerformance()
            {
                FloatCurve atmospherecurve = new FloatCurve();
                UpdateRadiusModifier();

                if (AttachedReactor != null)
                {
                    _maxISP = Mathf.Sqrt(AttachedReactor.CoreTemperature) * (PluginHelper.IspCoreTempMult + IspTempMultOffset) * GetIspPropellantModifier();

                    float thrust = GetPowerThrustModifier() * GetHeatThrustModifier() * AttachedReactor.MaximumPower / _maxISP / PluginHelper.GravityConstant * GetHeatExchangerThrustDivisor();
                    float max_thrust_in_space = thrust;
                    thrust *= _thrustPropellantMultiplier;
                    myAttachedEngine.maxFuelFlow = thrust / (PluginHelper.GravityConstant * _maxISP);
                    myAttachedEngine.maxThrust = thrust;

                    //_minISP = _maxISP * ((thrust - maxPressureThresholdAtKerbinSurface) / thrust) * GetHeatExchangerThrustDivisor();
                    //atmospherecurve.Add(0, _maxISP, 0, 0);
                    //atmospherecurve.Add(1, _minISP, 0, 0);
                    
                    float max_thrust_in_current_atmosphere = max_thrust_in_space;
                
                    // update engine thrust/ISP for thermal noozle
                    if (!_currentpropellant_is_jet)
                    {
                        pressureTreshold = exitArea * (float)GameConstants.EarthAtmospherePressureAtSeaLevel;
                        if (_maxISP > GameConstants.MaxThermalNozzleIsp )
                            pressureTreshold *= 10;

                        max_thrust_in_current_atmosphere = max_thrust_in_space - pressureTreshold;

                        var thrustAtmosphereRatio = max_thrust_in_space > 0 ? Math.Max(max_thrust_in_current_atmosphere / max_thrust_in_space, 0.01 ) : 0.01;
                        _minISP = _maxISP * (float)thrustAtmosphereRatio;
                    }
                    else
                        _minISP = _maxISP;

                    atmospherecurve.Add(0, _maxISP, 0, 0);
                    atmospherecurve.Add(1, _minISP, 0, 0);

                    myAttachedEngine.atmosphereCurve = atmospherecurve;
                }
                else
                {
                    atmospherecurve.Add(0, 0.00001f, 0, 0);
                    myAttachedEngine.maxThrust = 0;
                    myAttachedEngine.atmosphereCurve = atmospherecurve;
                }
            }

    OnFixedUpdate -  if myAttachedEngine.isOperational block:
     

    Spoiler

                if (myAttachedEngine.isOperational && myAttachedEngine.currentThrottle > 0)
                    GenerateThrustFromReactorHeat();
                else
                {
                    //requestedReactorThermalPower = String.Empty;
                    //requestedReactorChargedPower = String.Empty;
                    //recievedReactorPower = String.Empty;

                    consumedWasteHeat = 0;

                    atmospheric_limit = GetAtmosphericLimit();

                    _maxISP = (float)(Math.Sqrt((double)AttachedReactor.CoreTemperature) * (PluginHelper.IspCoreTempMult + IspTempMultOffset) * GetIspPropellantModifier());

                    expectedMaxThrust = (float)(AttachedReactor.MaximumPower * GetPowerThrustModifier() * GetHeatThrustModifier() / PluginHelper.GravityConstant / _maxISP * (float)GetHeatExchangerThrustDivisor());
                    float calculatedMaxThrust = expectedMaxThrust;
                    expectedMaxThrust *= _thrustPropellantMultiplier * (1f - sootAccumulationPercentage / 200f);

                    max_fuel_flow_rate = (float)(expectedMaxThrust / _maxISP / PluginHelper.GravityConstant);

                    if (!_currentpropellant_is_jet)
                    {
                        pressureTreshold = exitArea * (float)FlightGlobals.getStaticPressure(vessel.transform.position);
                        if (_maxISP > GameConstants.MaxThermalNozzleIsp)
                            pressureTreshold *= 10;
                    }
                    else
                        pressureTreshold = 0;
                
                    var thrustAtmosphereRatio = expectedMaxThrust <= 0 ? 0 : Math.Max(0, expectedMaxThrust - pressureTreshold) / expectedMaxThrust;

                    current_isp = _maxISP * (float)thrustAtmosphereRatio;
                    calculatedMaxThrust -= pressureTreshold;
                    calculatedMaxThrust *= (float)_thrustPropellantMultiplier * (1f - sootAccumulationPercentage / sootThrustDivider);

                    FloatCurve newISP = new FloatCurve();
                    var effectiveIsp = isJet ? Mathf.Min(current_isp, PluginHelper.MaxThermalNozzleIsp) : current_isp;
                    newISP.Add(0, effectiveIsp, 0, 0);
                    myAttachedEngine.atmosphereCurve = newISP;

                    if (myAttachedEngine.useVelCurve)
                    {
                        double vcurve_at_current_velocity = myAttachedEngine.velCurve.Evaluate((float)vessel.srf_velocity.magnitude);

                        if (vcurve_at_current_velocity > 0 && !double.IsInfinity(vcurve_at_current_velocity) && !double.IsNaN(vcurve_at_current_velocity))
                        {
                            max_fuel_flow_rate = (float)(max_fuel_flow_rate / vcurve_at_current_velocity);
                            calculatedMaxThrust = calculatedMaxThrust / (float)vcurve_at_current_velocity;
                        }
                    }
                    myAttachedEngine.maxThrust = calculatedMaxThrust > 0 ? calculatedMaxThrust : 0;

                    // set engines maximum fuel flow
                    myAttachedEngine.maxFuelFlow = Math.Min(1000f, (float)max_fuel_flow_rate);

                    if (myAttachedEngine is ModuleEnginesFX && !String.IsNullOrEmpty(_particleFXName))
                    {
                        part.Effect(_particleFXName, 0);
                    }
                }

    GenerateThrustFromReactorHeat:
     

    Spoiler

    private void GenerateThrustFromReactorHeat()
            {
                if (!AttachedReactor.IsActive)
                    AttachedReactor.EnableIfPossible();

                GetMaximumIspAndThrustMultiplier();

                float chargedPowerModifier = _isNeutronAbsorber ? 1 : (AttachedReactor.FullPowerForNonNeutronAbsorbants ? 1 : (float)_myAttachedReactor.ChargedPowerRatio);

                thermal_modifiers = myAttachedEngine.currentThrottle * GetAtmosphericLimit() * _myAttachedReactor.GetFractionThermalReciever(id) * chargedPowerModifier;

                var maximum_requested_thermal_power = _currentMaximumPower * thermal_modifiers;

                var neutronAbsorbingModifier = _isNeutronAbsorber ? 1 : (AttachedReactor.FullPowerForNonNeutronAbsorbants ? 1 : 0);
                requested_thermal_power = Math.Min(_availableThermalPower * thermal_modifiers, AttachedReactor.MaximumThermalPower * delayedThrottle * neutronAbsorbingModifier);

                thermal_power_received = consumeFNResource(requested_thermal_power * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_THERMALPOWER) * _myAttachedReactor.ThermalPropulsionEfficiency / TimeWarp.fixedDeltaTime;

                if (thermal_power_received < maximum_requested_thermal_power)
                {
                    var chargedParticleRatio = (float)Math.Pow(getResourceBarRatio(FNResourceManager.FNRESOURCE_CHARGED_PARTICLES), 2);
                    requested_charge_particles = Math.Min((maximum_requested_thermal_power - thermal_power_received), AttachedReactor.MaximumChargedPower) * chargedParticleRatio;

                    thermal_power_received += consumeFNResource(requested_charge_particles * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_CHARGED_PARTICLES) / TimeWarp.fixedDeltaTime;
                }

                UpdateSootAccumulation();

                var extraWasteheatRedution = AttachedReactor.FullPowerForNonNeutronAbsorbants
                    ? TimeWarp.fixedDeltaTime * getResourceAvailability(FNResourceManager.FNRESOURCE_WASTEHEAT) * myAttachedEngine.currentThrottle
                    : 0;

                var sootModifier = 1f - (sootAccumulationPercentage / sootHeatDivider);

                consumedWasteHeat = sootModifier * (float)Math.Max(AttachedReactor.ProducedWasteHeat + extraWasteheatRedution, thermal_power_received);

                // consume wasteheat
                consumeFNResource(consumedWasteHeat * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_WASTEHEAT);
                
                // calculate max thrust
                heatExchangerThrustDivisor = (float)GetHeatExchangerThrustDivisor();
                radiusModifier = (heatExchangerThrustDivisor * 100).ToString("0.00") + "%";
                engineMaxThrust = 0.01f;
                float calculatedMaxThrust = 0;
                if (_availableThermalPower > 0)
                {
                    var ispRatio = _currentpropellant_is_jet ? current_isp / _maxISP : 1;
                    var thrustLimit = myAttachedEngine.thrustPercentage / 100.0f;
                    engineMaxThrust = (float)Math.Max(thrustLimit * GetPowerThrustModifier() * GetHeatThrustModifier() * thermal_power_received / _maxISP / PluginHelper.GravityConstant * heatExchangerThrustDivisor * ispRatio / myAttachedEngine.currentThrottle, 0.01);
                    calculatedMaxThrust = GetPowerThrustModifier() * GetHeatThrustModifier() * AttachedReactor.MaximumPower / _maxISP / PluginHelper.GravityConstant * heatExchangerThrustDivisor * ispRatio;
                }

                max_thrust_in_space = engineMaxThrust / myAttachedEngine.thrustPercentage * 100;

                var nozzleStaticPresure = (float)FlightGlobals.getStaticPressure(vessel.transform.position);

                max_thrust_in_current_atmosphere = max_thrust_in_space;
                
                // update engine thrust/ISP for thermal noozle
                if (!_currentpropellant_is_jet)
                {
                    pressureTreshold = exitArea * nozzleStaticPresure;
                    if (_maxISP > GameConstants.MaxThermalNozzleIsp )
                        pressureTreshold *= 10;

                    max_thrust_in_current_atmosphere = Mathf.Max(max_thrust_in_space - pressureTreshold, Mathf.Max(myAttachedEngine.currentThrottle * 0.01f, 0.0001f));

                    var thrustAtmosphereRatio = max_thrust_in_space > 0 ? Math.Max(max_thrust_in_current_atmosphere / max_thrust_in_space, 0.01 ) : 0.01;
                    UpdateIspEngineParams(thrustAtmosphereRatio);
                    current_isp = _maxISP * (float)thrustAtmosphereRatio;
                    calculatedMaxThrust -= pressureTreshold;
                }
                else
                    current_isp = _maxISP;

                if (!Single.IsInfinity(max_thrust_in_current_atmosphere) && !Single.IsNaN(max_thrust_in_current_atmosphere))
                {
                    final_max_engine_thrust = max_thrust_in_current_atmosphere * _thrustPropellantMultiplier * (1f - sootAccumulationPercentage / sootThrustDivider);
                    calculatedMaxThrust *= (float)_thrustPropellantMultiplier * (1f - sootAccumulationPercentage / sootThrustDivider);
                }
                else
                {
                    final_max_engine_thrust = 0.000001f;
                    calculatedMaxThrust = final_max_engine_thrust;
                }

                // amount of fuel being used at max throttle with no atmospheric limits
                if (_maxISP <= 0) return;
                
                // calculate maximum fuel flow rate
                max_fuel_flow_rate = final_max_engine_thrust / current_isp / PluginHelper.GravityConstant / myAttachedEngine.currentThrottle;

                if (myAttachedEngine.useVelCurve && myAttachedEngine.velCurve != null)
                {
                    vcurveAtCurrentVelocity = myAttachedEngine.velCurve.Evaluate((float)(vessel.speed / vessel.speedOfSound));

                    if (vcurveAtCurrentVelocity > 0 && !double.IsInfinity(vcurveAtCurrentVelocity) && !double.IsNaN(vcurveAtCurrentVelocity))
                    {
                        max_fuel_flow_rate = (float)(max_fuel_flow_rate * vcurveAtCurrentVelocity);
                        calculatedMaxThrust *= (float)vcurveAtCurrentVelocity;
                    }
                    else
                    {
                        max_fuel_flow_rate = 0.000001f;
                        calculatedMaxThrust = 0;
                    }
                }
                myAttachedEngine.maxThrust = calculatedMaxThrust > 0 ? calculatedMaxThrust : 0;

                if (atmospheric_limit > 0 && atmospheric_limit != 1 && !double.IsInfinity(atmospheric_limit) && !double.IsNaN(atmospheric_limit))
                    max_fuel_flow_rate = max_fuel_flow_rate * atmospheric_limit;

                engineHeatProduction = (max_fuel_flow_rate >= 0.0001) ? baseHeatProduction * 350 / max_fuel_flow_rate /(float)Math.Pow(_maxISP, 0.8)  : baseHeatProduction;
                myAttachedEngine.heatProduction = engineHeatProduction;

                // set engines maximum fuel flow
                myAttachedEngine.maxFuelFlow = Math.Min(1000, max_fuel_flow_rate);

                if (myAttachedEngine is ModuleEnginesFX && !String.IsNullOrEmpty(_particleFXName))
                {
                    part.Effect(_particleFXName, Mathf.Max(0.1f * myAttachedEngine.currentThrottle,  Mathf.Min((float)Math.Pow(thermal_power_received / requested_thermal_power, 0.5), delayedThrottle)));
                }

                if (_fuelToxicity > 0 && max_fuel_flow_rate > 0 && nozzleStaticPresure > 1)
                {
                    _savedReputationCost += (float)(max_fuel_flow_rate * _fuelToxicity * TimeWarp.fixedDeltaTime * Math.Pow(nozzleStaticPresure / 100, 3));
                    if (_savedReputationCost > 1)
                    {
                        float flooredReputationCost = (int)Math.Floor(_savedReputationCost);

                        if (Reputation.Instance != null)
                            Reputation.Instance.addReputation_discrete(-flooredReputationCost, TransactionReasons.None);
                        else
                            UnityEngine.Debug.Log("[KSPI] - ThermalNozzleController - No Reputation found, was not able to reduce reputation by " + flooredReputationCost);

                        ScreenMessages.PostScreenMessage("You are poisoning the environment with " + _fuelmode + " from your exhaust!", 5.0f, ScreenMessageStyle.LOWER_CENTER);
                        _savedReputationCost -= flooredReputationCost;
                    }
                }
            }

     

  21. On a related note, BetterBurnTime was also throwing incorrect numbers.  It looks like it depends on engine.MaxThrust to calculate the burn time and it's  just pulled out of the engine config file and never updated.  Since this already getting calculated while the engine is running I just added it into OnFixedUpdate for ThermalNozzleController.cs:

                    expectedMaxThrust = (float)(AttachedReactor.MaximumPower * GetPowerThrustModifier() * GetHeatThrustModifier() / PluginHelper.GravityConstant / _maxISP);
    
                    expectedMaxThrust *= _thrustPropellantMultiplier * (1f - sootAccumulationPercentage / 200f);
    
                    myAttachedEngine.maxThrust = expectedMaxThrust;

    The last line is the only change.  Here's a diff of the changes I've made so far compared to the latest from github:

    Spoiler

    diff ThermalNozzleController.cs.old ThermalNozzleController.cs -b
    885c885,894
    <                 _minISP = _maxISP * 0.4f;
    ---
    >                 //_minISP = _maxISP * 0.4f;
    >                 //atmospherecurve.Add(0, _maxISP, 0, 0);
    >                 //atmospherecurve.Add(1, _minISP, 0, 0);
    >
    >                 //thrust = (float)(AttachedReactor.MaximumPower * GetPowerThrustModifier() * GetHeatThrustModifier() / PluginHelper.GravityConstant / _maxISP);
    >                 thrust = ((float)GetPowerThrustModifier() * (float)GetHeatThrustModifier() * AttachedReactor.MaximumPower / _maxISP / PluginHelper.GravityConstant * (float)GetHeatExchangerThrustDivisor() * _thrustPropellantMultiplier);
    >                 myAttachedEngine.maxFuelFlow = thrust / (PluginHelper.GravityConstant * _maxISP);
    >                 myAttachedEngine.maxThrust = thrust;
    >
    >                 _minISP = _maxISP * ((thrust - maxPressureThresholdAtKerbinSurface) / thrust) * (float)GetHeatExchangerThrustDivisor();
    889,890d897
    <                 thrust = (float)(AttachedReactor.MaximumPower * GetPowerThrustModifier() * GetHeatThrustModifier() / PluginHelper.GravityConstant / _maxISP);
    <                 myAttachedEngine.maxThrust = thrust;
    999a1007,1008
    >                 myAttachedEngine.maxThrust = expectedMaxThrust;
    >

     

  22. I have a bug in the code I posted, I was using AttachedReactor.MaximumThermalPower in the thrust calculation instead of AttachedReactor.MaximumPower.  That was skewing reactors with charged particles.

    Fixing that puts everything pretty close to the editor estimate:

    Spoiler

     

    this is in the format "alt amount shown in editor :: actual in game amount measured by KER"
    all numbers with liquid fuel

    omega
    vac 2209.6 isp - 3115.13kN :: 2209.5 isp - 3049.80kN
    sea 1994.0 isp - 2811.94kN :: 1992.2 isp - 2749.29kN

    pebble
    vac 781.2 - 1566.38 :: 781.2 - 1566.29
    sea 629.6 - 1262.41 :: 631.6 - 1266.33

    dumbo
    vac 781.2 - 3132.77 :: 781.2 - 3132.60
    sea 705.4 - 2828.79 :: 706.4 - 2832.71

    salt
    sea 199.2 - 113.44 :: 206.1 - 117.35

    dusty
    sea 627.5 - 511.45 :: 632.4 - 515.44

    antimater
    sea 6082.9 - 3388.03 :: 6090.2 - 3392.05
    vac 6628.7 - 3692.00 :: 6628.7 - 3690.56

     

     

  23.  

    14 hours ago, FreeThinker said:

    except for some minor details it is looking good. It appears I haven't maintained this part of the code for quite some time. If it doesn't break anything, I will integrrate it in the code for next release

    Thanks!  I've been playing with that new code and swapping out different reactors and I've come across two things of note:

    1. reactor / thermal nozzle combinations that have no thrust at sealevel can cause minISP to go negative.  It looks like the correct way to fix it would be to add another atmospherecurve with the altitude where the engine actually hit's 0.1isp and clamp sealevel to zero, but it may just be a visual problem and not game impacting as negative values don't seem to break anything.

    2. the 'gas core' reactor.  The buoyancy effect causes weird things to happen, even with stock code.  100% throttle actually produces slightly less engine thrust then when set to around 60%.  The reactor control window also seems off, thermal power is lower at 60% (as expected) even though more of it seems to be hitting the engine.  There really needs to be a readout on the buoyancy impact.  I also feel like the reactor needs a tiny boost in total thermal power as you lose a pretty large chunk of it while accelerating, which seems odd for a reactor that looks to be designed for thermal nozzles.

    All of this also means that the thrust estimate is still way off on the gas core: 371kN vac is reported on the engine and in KER with the new code, but in space it's usually quite a bit lower.  I'm not sure how to calculate the thrust for this engine as it'll need to take into account both stage mass and throttle position, but I'll keep poking at it.

×
×
  • Create New...