bool updateTargetLine = false; // Indicate if target line needs updating #endregion Fields #region Constructors // Constructor // Give the navigator to which this control is for public Controls(Navigator navigator) { // Defaults window defaultWindow = new DefaultWindow(navigator); // Assign navigator field this.navigator = navigator; Debug.Log(this.navigator.ToString()); // Controls window id id = GUIUtility.GetControlID(FocusType.Keyboard); // Initial time if (navigator.UT0 == 0) { UT0 = Planetarium.GetUniversalTime(); } else { UT0 = navigator.UT0; } Debug.Log(UT0.ToString()); // Off navigator control navigatorOff = Control.Default(navigator, this); // If the navigator doesn't have saved controls, return default if (String.IsNullOrEmpty(navigator.frames) || String.IsNullOrEmpty(navigator.angle0s) || String.IsNullOrEmpty(navigator.angle1s) || String.IsNullOrEmpty(navigator.angle2s) || String.IsNullOrEmpty(navigator.throttles) || String.IsNullOrEmpty(navigator.sailons) || String.IsNullOrEmpty(navigator.durations)) { ncontrols = 1; controls = new List<Control>(); controls.Add(Control.Default(navigator, this)); } else { // Otherwise, parse saved controls // Split into arrays var frameStrings = navigator.frames.Split(delimiter); var angle0Strings = navigator.angle0s.Split(delimiter); var angle1Strings = navigator.angle1s.Split(delimiter); var angle2Strings = navigator.angle2s.Split(delimiter); var throttleStrings = navigator.throttles.Split(delimiter); var durationStrings = navigator.durations.Split(delimiter); var sailonStrings = navigator.sailons.Split(delimiter); // Find number of controls ncontrols = Math.Min(frameStrings.Length, Math.Min(angle0Strings.Length, Math.Min(angle1Strings.Length, Math.Min(angle2Strings.Length, Math.Min(throttleStrings.Length, Math.Min(durationStrings.Length, sailonStrings.Length)))))); // Initialize controls array controls = new List<Control>(); // Populate controls for(var i = 0; i < ncontrols; i++) { var angles = new float [] { Utils.ParseSingle(angle0Strings[i]), Utils.ParseSingle(angle1Strings[i]), Utils.ParseSingle(angle2Strings[i]) }; controls.Add(new Control(navigator, this, angles, Utils.ParseSingle(throttleStrings[i]), Utils.ParseBool(sailonStrings[i]), Utils.ParseDouble(durationStrings[i]), navigator.defaultIWarp, frameStrings[i])); } } // Preview preview = new Preview(navigator); }
// Constructor & calculate public void Propagate(Navigator navigator, Orbit orbit0, double UT0, double UTf, double dT, Control control, double m0in) { // Control parameters var throttle = control.throttle; var sailon = control.sailon; var frame = control.frame; // Update segment initial mass m0 = m0in; // Working orbit at each time step Orbit orbit = orbit0.Clone(); // Number of time steps int nsteps = Convert.ToInt32(Math.Ceiling((UTf - UT0) / dT)); // Last time step size double dTlast = (UTf - UT0) % dT; // Current universal time double UT; // Current mass double m0i = m0; // Reseting time step to sample orbits for saving double dTchoose = 0.0; // List of orbits to preview orbits = new List<Orbit>(); // Add initial orbit orbits.Add(orbit0.Clone()); // Iterate for nsteps for (int i = 0; i < nsteps; i++) { // Last step goes to UTf if (i == nsteps - 1) { dT = dTlast; UT = UTf; } else { UT = UT0 + i * dT; } // Spacecraft reference frame Quaternion sailFrame = frame.qfn(orbit, UT, control.angles); // Total deltaV vector Vector3d deltaVV = new Vector3d(0.0, 0.0, 0.0); // Accumulated mass change for all engines double dms = 0.0; // Iterate over engines foreach (var pe in navigator.persistentEngines) { // Only count thrust of engines that are not shut down in preview if (pe.engine.getIgnitionState) { // Thrust unit vector Vector3d thrustUV = sailFrame * new Vector3d(0.0, 1.0, 0.0); // Isp: Currently vacuum. TODO: calculate at current air pressure float isp = pe.engine.atmosphereCurve.Evaluate(0); // Thrust vector float thrust = throttle * pe.engine.maxThrust; // Calculate deltaV vector double demandMass; deltaVV += pe.CalculateDeltaVV(m0i, dT, thrust, isp, thrustUV, out demandMass); // Update mass usage dms += demandMass * pe.densityAverage; } } // Iterate over sails if (sailon) { foreach (var s in navigator.solarSails) { // Check if sail in sun double sunlightFactor = 1.0; if (!SolarSailPart.inSun(orbit, UT)) { sunlightFactor = 0.0; } // Normal vector Vector3d n = sailFrame * new Vector3d(0.0, 1.0, 0.0); // Force on sail Vector3d solarForce = SolarSailPart.CalculateSolarForce(s, orbit, n, UT) * sunlightFactor; // Sail acceleration Vector3d solarAccel = solarForce / m0i / 1000.0; // Update deltaVV deltaVV += solarAccel * dT; } } // Update starting mass for next time step m0i -= dms; // Update // Update orbit orbit.Perturb(deltaVV, UT); // Increment time step at which to sample orbits dTchoose += dT; // Orbit period double TP = orbit.period; // Decide whether to add orbit to list of orbits to draw if (i == nsteps - 1) { // Always add last orbit orbits.Add(orbit.Clone()); } else if (dTchoose >= TP / 360) { // If 1/360th of current period passed, add orbit orbits.Add(orbit.Clone()); // Reset dTchoose dTchoose = 0.0; } } // Update final mass m1 = m0i; }
public FrameWindow(Control control) { // Rectangle object frameWindowPos = new Rect(705, 50, 0, 0); // Frame window ID frameID = GUIUtility.GetControlID(FocusType.Keyboard); // Initialize frame selection window RenderingManager.AddToPostDrawQueue(3, new Callback(DrawFrameWindow)); this.control = control; }
GameObject obj; // Game object of line #endregion Fields #region Constructors public PreviewSegment(Navigator navigator, Orbit orbitInitial, double UT0, double UTf, Control control, Color color, double m0in) { this.UT0 = UT0; this.UTf = UTf; dT = TimeWarp.fixedDeltaTime * control.warp; // Update preview orbits this.Propagate(navigator, orbitInitial, UT0, UTf, dT, control, m0in); orbit0 = orbits[0]; orbitf = orbits.Last(); // Initialize LineRenderer // Remove old line if (line != null) { UnityEngine.Object.Destroy(line); } // Create new one obj = new GameObject("Preview segment"); line = obj.AddComponent<LineRenderer>(); line.useWorldSpace = false; obj.layer = 10; // Map view line.material = MapView.fetch.orbitLinesMaterial; line.SetColors(color, color); line.SetVertexCount(orbits.Count); // Calculate relative position vectors relativePoints = new Vector3d[orbits.Count]; for(var i = 0; i < orbits.Count; i++) { double UTi = orbits[i].epoch; relativePoints[i] = orbits[i].getRelativePositionAtUT(UTi).xzy; } }