Пример #1
0
 private void ResetPlugin()
 {
     Cleanup();
     SetRotatingFrameThresholds();
     RemoveBuggyTidalLocking();
     plugin_construction_ = DateTime.Now;
     Dictionary<String, ConfigNode> name_to_gravity_model = null;
     var gravity_model_configs =
     GameDatabase.Instance.GetConfigs(principia_gravity_model_config_name);
     var cartesian_configs =
     GameDatabase.Instance.GetConfigs(principia_initial_state_config_name);
     if (gravity_model_configs.Length == 1) {
       name_to_gravity_model =
       gravity_model_configs[0].config.GetNodes("body").
       ToDictionary(node => node.GetValue("name"));
     } else if (gravity_model_configs.Length > 1) {
       Log.Fatal("too many gravity models (" + gravity_model_configs.Length +
     ")");
     }
     if (cartesian_configs.Length > 0) {
       plugin_source_ = PluginSource.CARTESIAN_CONFIG;
       if (cartesian_configs.Length > 1) {
     Log.Fatal("too many Cartesian configs (" + cartesian_configs.Length +
       ")");
       }
       if (name_to_gravity_model == null) {
     Log.Fatal("Cartesian config without gravity models");
       }
       try {
     ConfigNode initial_states =
     GameDatabase.Instance.GetConfigs(principia_initial_state_config_name)[0].config;
     plugin_ =
     Interface.NewPlugin(initial_states.GetValue("game_epoch"),
                     initial_states.GetValue("solar_system_epoch"),
                     Planetarium.InverseRotAngle);
     var name_to_initial_state =
     initial_states.GetNodes("body").
     ToDictionary(node => node.GetValue("name"));
     BodyProcessor insert_body = body => {
       Log.Info("Inserting " + body.name + "...");
       ConfigNode gravity_model;
       if (!name_to_gravity_model.TryGetValue(body.name,
                                      out gravity_model)) {
      Log.Fatal("missing gravity model for " + body.name);
       }
       ConfigNode initial_state;
       if (!name_to_initial_state.TryGetValue(body.name,
                                      out initial_state)) {
      Log.Fatal("missing Cartesian initial state for " + body.name);
       }
       int? parent_index = body.orbit?.referenceBody.flightGlobalsIndex;
       var body_parameters = new BodyParameters{
       name = body.name,
       gravitational_parameter =
       gravity_model.GetValue("gravitational_parameter"),
       reference_instant       =
       double.Parse(gravity_model.GetValue("reference_instant")),
       mean_radius             = gravity_model.GetValue("mean_radius"),
       axis_right_ascension    =
       gravity_model.GetValue("axis_right_ascension"),
       axis_declination        =
       gravity_model.GetValue("axis_declination"),
       reference_angle         =
       gravity_model.GetValue("reference_angle"),
       angular_frequency       =
       gravity_model.GetValue("angular_frequency"),
       j2                      = gravity_model.GetValue("j2"),
       reference_radius        =
       gravity_model.GetValue("reference_radius")};
       plugin_.InsertCelestialAbsoluteCartesian(
       celestial_index         : body.flightGlobalsIndex,
       parent_index            : parent_index,
       body_parameters         : body_parameters,
       x                       : initial_state.GetValue("x"),
       y                       : initial_state.GetValue("y"),
       z                       : initial_state.GetValue("z"),
       vx                      : initial_state.GetValue("vx"),
       vy                      : initial_state.GetValue("vy"),
       vz                      : initial_state.GetValue("vz"));
     };
     insert_body(Planetarium.fetch.Sun);
     ApplyToBodyTree(insert_body);
     plugin_.EndInitialization();
     plugin_.AdvanceTime(Planetarium.GetUniversalTime(),
                 Planetarium.InverseRotAngle);
       } catch (Exception e) {
     Log.Fatal("Exception while reading initial state: " + e.ToString());
       }
     } else {
       plugin_source_ = PluginSource.ORBITAL_ELEMENTS;
       // We create the plugin at time 0, rather than
       // |Planetarium.GetUniversalTime()|, in order to get a deterministic
       // initial state.
       for(;;) {
     plugin_ = Interface.NewPlugin("0 s", "0 s",
                           Planetarium.InverseRotAngle);
     BodyProcessor insert_body = body => {
       Log.Info("Inserting " + body.name + "...");
       ConfigNode gravity_model = null;
       if (name_to_gravity_model?.TryGetValue(body.name,
                                      out gravity_model) == true) {
     Log.Info("using custom gravity model");
       }
       Orbit orbit = unmodified_orbits_.GetValueOrNull(body);
       var body_parameters = new BodyParameters{
       name = body.name,
       gravitational_parameter =
       (gravity_model?.GetValue("gravitational_parameter")).
           GetValueOrDefault(body.gravParameter + " m^3/s^2"),
       // J2000, because that's when we start non-config games.  We
       // should really parse real-life dates from strings.
       // The origin of rotation in KSP is the x of Barycentric, rather
       // than the y axis as is the case for Earth, so the right
       // ascension is -90 deg.
       reference_instant    = double.Parse(
       (gravity_model?.GetValue("reference_instant")).
           GetValueOrDefault("2451545.0")),
       mean_radius          =
       (gravity_model?.GetValue("mean_radius")).
           GetValueOrDefault(body.Radius + " m"),
       axis_right_ascension =
       (gravity_model?.GetValue("axis_right_ascension")).
           GetValueOrDefault("-90 deg"),
       axis_declination     =
       (gravity_model?.GetValue("axis_declination")).
           GetValueOrDefault("90 deg"),
       reference_angle      =
       (gravity_model?.GetValue("reference_angle")).
           GetValueOrDefault(body.initialRotation.ToString() +
                             " deg"),
       angular_frequency    =
       (gravity_model?.GetValue("angular_frequency")).
           GetValueOrDefault(body.angularV.ToString() + " rad/s"),
       j2                   = gravity_model?.GetValue("j2"),
       reference_radius     =
       gravity_model?.GetValue("reference_radius")};
       plugin_.InsertCelestialJacobiKeplerian(
       celestial_index             : body.flightGlobalsIndex,
       parent_index                :
       orbit?.referenceBody.flightGlobalsIndex,
       body_parameters             : body_parameters,
       keplerian_elements          : orbit?.Elements());
     };
     insert_body(Planetarium.fetch.Sun);
     ApplyToBodyTree(insert_body);
     plugin_.EndInitialization();
     if (plugin_.IsKspStockSystem()) {
       Interface.DeletePlugin(ref plugin_);
       Fix631();
     } else {
       break;
     }
       }
     }
     plotting_frame_selector_.reset(
     new ReferenceFrameSelector(this,
                        plugin_,
                        UpdateRenderingFrame,
                        "Plotting frame"));
     flight_planner_.reset(new FlightPlanner(this, plugin_));
     VesselProcessor insert_vessel = vessel => {
       Log.Info("Inserting " + vessel.name + "...");
       bool inserted =
       plugin_.InsertOrKeepVessel(
       vessel.id.ToString(),
       vessel.orbit.referenceBody.flightGlobalsIndex);
       if (!inserted) {
     Log.Fatal("Plugin initialization: vessel not inserted");
       } else {
     plugin_.SetVesselStateOffset(vessel.id.ToString(),
                          new QP{q = (XYZ)vessel.orbit.pos,
                                 p = (XYZ)vessel.orbit.vel});
       }
     };
     ApplyToVesselsOnRailsOrInInertialPhysicsBubbleInSpace(insert_vessel);
 }