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); }
private void ResetPlugin() { Cleanup(); SetRotatingFrameThresholds(); RemoveBuggyTidalLocking(); ResetRenderedTrajectory(); plugin_construction_ = DateTime.Now; if (GameDatabase.Instance.GetConfigs(kPrincipiaInitialState).Length > 0) { plugin_source_ = PluginSource.CARTESIAN_CONFIG; if (GameDatabase.Instance.GetConfigs( kPrincipiaGravityModel).Length == 0) { Log.Fatal("missing gravity models"); } if (GameDatabase.Instance.GetConfigs(kPrincipiaInitialState).Length > 1 || GameDatabase.Instance.GetConfigs( kPrincipiaGravityModel).Length > 1) { Log.Fatal("too many configs"); } try { ConfigNode initial_states = GameDatabase.Instance.GetConfigs(kPrincipiaInitialState)[0].config; ConfigNode gravity_models = GameDatabase.Instance.GetConfigs(kPrincipiaGravityModel)[0].config; plugin_ = Interface.NewPlugin(double.Parse(initial_states.GetValue("epoch")), Planetarium.InverseRotAngle); var name_to_initial_state = new Dictionary<String, ConfigNode>(); var name_to_gravity_model = new Dictionary<String, ConfigNode>(); foreach (ConfigNode node in initial_states.GetNodes("body")) { name_to_initial_state.Add(node.GetValue("name"), node); } foreach (ConfigNode node in gravity_models.GetNodes("body")) { name_to_gravity_model.Add(node.GetValue("name"), node); } ConfigNode sun_gravity_model = name_to_gravity_model[Planetarium.fetch.Sun.name]; ConfigNode sun_initial_state = name_to_initial_state[Planetarium.fetch.Sun.name]; plugin_.InsertCelestialAbsoluteCartesian( celestial_index: Planetarium.fetch.Sun.flightGlobalsIndex, parent_index: IntPtr.Zero, gravitational_parameter: sun_gravity_model.GetValue("gravitational_parameter"), axis_right_ascension: sun_gravity_model.HasValue("axis_right_ascension") ? sun_gravity_model.GetValue("axis_right_ascension") : null, axis_declination: sun_gravity_model.HasValue("axis_declination") ? sun_gravity_model.GetValue("axis_declination") : null, j2: sun_gravity_model.HasValue("j2") ? sun_gravity_model.GetValue("j2") : null, reference_radius: sun_gravity_model.HasValue("reference_radius") ? sun_gravity_model.GetValue("reference_radius") : null, x: sun_initial_state.GetValue("x"), y: sun_initial_state.GetValue("y"), z: sun_initial_state.GetValue("z"), vx: sun_initial_state.GetValue("vx"), vy: sun_initial_state.GetValue("vy"), vz: sun_initial_state.GetValue("vz")); BodyProcessor insert_body = body => { Log.Info("Inserting " + body.name + "..."); ConfigNode gravity_model = name_to_gravity_model[body.name]; ConfigNode initial_state = name_to_initial_state[body.name]; int parent_index = body.orbit.referenceBody.flightGlobalsIndex; plugin_.InsertCelestialAbsoluteCartesian( celestial_index: body.flightGlobalsIndex, parent_index: ref parent_index, gravitational_parameter: gravity_model.GetValue("gravitational_parameter"), axis_right_ascension: gravity_model.HasValue("axis_right_ascension") ? gravity_model.GetValue("axis_right_ascension") : null, axis_declination: gravity_model.HasValue("axis_declination") ? gravity_model.GetValue("axis_declination") : null, j2: gravity_model.HasValue("j2") ? gravity_model.GetValue("j2") : null, reference_radius: gravity_model.HasValue("reference_radius") ? gravity_model.GetValue("reference_radius") : null, 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")); }; 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. plugin_ = Interface.NewPlugin(0, Planetarium.InverseRotAngle); plugin_.InsertSun(Planetarium.fetch.Sun.flightGlobalsIndex, Planetarium.fetch.Sun.gravParameter); BodyProcessor insert_body = body => { Log.Info("Inserting " + body.name + "..."); Orbit orbit = unmodified_orbits_[body]; double mean_motion = 2 * Math.PI / orbit.period; plugin_.InsertCelestialJacobiKeplerian( celestial_index : body.flightGlobalsIndex, parent_index : body.referenceBody.flightGlobalsIndex, gravitational_parameter : body.gravParameter + " m^3/s^2", axis_right_ascension : null, axis_declination : null, j2 : null, reference_radius : null, eccentricity : orbit.eccentricity, mean_motion : mean_motion + " rad/s", inclination : orbit.inclination + " deg", longitude_of_ascending_node : orbit.LAN + " deg", argument_of_periapsis : orbit.argumentOfPeriapsis + " deg", mean_anomaly : orbit.meanAnomalyAtEpoch - orbit.epoch * mean_motion + " rad"); }; ApplyToBodyTree(insert_body); plugin_.EndInitialization(); } 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); }