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); }