ShotgunNinja / Kerbalism

Hundreds of Kerbals were killed in the making of this mod.
The Unlicense
43 stars 19 forks source link

Temperature inconsistency between loaded / unloaded vessels #114

Closed gotmachine closed 7 years ago

gotmachine commented 7 years ago

When a vessel is in atmosphere, the environment temperature returned by Sim.Temperature() vary according to the vessel being loaded or not.

The code use the skin temperature of the vessel root part when the vessel is loaded, I think the intent was to account for reentry/atmospheric heat in the climatization rule, but then the Sim.Temperature() function can't be used to get the environment temperature.

To fix this, the "stock loaded temperature blending" should be moved to the Sim.TempDiff() function that is directly and only used to calculate the climatization rule modifier.

Problematic code in Sim.cs near line 351 :

    // if inside atmosphere
    if (body.atmosphere && v.altitude < body.atmosphereDepth)
    {
      // calculate atmospheric temperature
      double atmo_temp = v.loaded ? v.rootPart.skinTemperature : body.GetTemperature(v.altitude);

      // mix between our temperature and the stock atmospheric model
      temp = Lib.Mix(atmo_temp, temp, Lib.Clamp(v.altitude / body.atmosphereDepth, 0.0, 1.0));
    }
ShotgunNinja commented 7 years ago

The temperature model was never extended to simulate atmospheric climate. Therefore I had to rely on the stock atmospheric temperature simulation. That is why I use the root part surface temperature when a vessel is inside an atmosphere (that in turn gave the re-entry heating for free). The code you mention does 'blending' between stock atmo temp and my own non-atmo temp, based on normalized atmospheric altitude, to avoid a sudden change in temperature at the atmosphere->space boundary.

When the vessel is unloaded, the root part surface temperature is not available anymore. In that case I simply call body.GetTemperature(v.altitude). That of course gives different results from the root part surface temp, and that is the different loaded/unloaded results you are seeing.

To fix this I would have to simulate atmospheric climate myself, to some degree, so that the same values are available for both loaded and unloaded vessels.

An alternative may be to simply always use the value returned by body.GetTemperature(v.altitude). That is available for both loaded and unloaded vessels, but we'll lose the re-entry heating effect on climatization (it may be a good thing in fact, that was never planned in the first place, it just happened).

So by rewriting the code you posted to:

if (body.atmosphere && v.altitude < body.atmosphereDepth)
{
  // calculate atmospheric temperature
  double atmo_temp = body.GetTemperature(v.altitude); //< this changed

  // mix between our temperature and the stock atmospheric model
  temp = Lib.Mix(atmo_temp, temp, Lib.Clamp(v.altitude / body.atmosphereDepth, 0.0, 1.0));
}

we'll get the exact same atmospheric temperature for both loaded and unloaded vessels. What you think?

ShotgunNinja commented 7 years ago

I've implemented the 'fix' mentioned in my previous post, for now.