// Constructor
 public Control(Navigator navigator, Controls controls, float [] angles, float throttle, bool sailon, double duration, int iwarp, string frame)
 {
     // Navigator
     this.navigator = navigator;
     // Parent controls object
     this.controls = controls;
     // Reference frame for control angles
     this.frame = Frame.Frames[frame];
     // Frame window
     frameWindow = new FrameWindow(this);
     // Angles
     this.angles = angles;
     // Angle strings
     anglestr = new string [3];
     for (int i = 0; i < 3; i++) {
     anglestr[i] = angles[i].ToString();
     }
     // Throttle
     throttle_str = throttle.ToString();
     this.throttle = throttle;
     // Sail on
     sailon_str = sailon.ToString();
     this.sailon = sailon;
     // Time
     this.duration = duration;
     this.days = Math.Floor(duration / SecondsPerDay);
     this.days_str = days.ToString();
     this.hours = Math.Floor(duration % SecondsPerDay / SecondsPerHour);
     this.hours_str = this.hours.ToString();
     this.duration = days * SecondsPerDay + hours * SecondsPerHour;
     duration_str = duration.ToString();
     // Warp factor
     this.iwarp = iwarp;
     warp = warpLevels[iwarp];
 }
 public DefaultWindow(Navigator navigator)
 {
     this.navigator = navigator;
     windowPos = new Rect(705, 100, 0, 0);
     frameID = GUIUtility.GetControlID(FocusType.Keyboard);
     RenderingManager.AddToPostDrawQueue(3, new Callback(DrawWindow));
     fields = new Dictionary<string, string>();
     fields["Frame"] = navigator.defaultFrame;
     fields["Angle(0)"] = navigator.defaultAngle0.ToString();
     fields["Angle(1)"] = navigator.defaultAngle1.ToString();
     fields["Angle(2)"] = navigator.defaultAngle2.ToString();
     fields["Days"] = navigator.defaultDays.ToString();
     fields["Hours"] = navigator.defaultHours.ToString();
     fields["Throttle"] = navigator.defaultThrottle.ToString();
     fields["Sail on"] = navigator.defaultSailon.ToString();
 }
        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);
        }
 public static Control Default(Navigator navigator, Controls controls)
 {
     var frame = Frame.Frames[navigator.defaultFrame];
     var defaultAngles = new float [] { navigator.defaultAngle0, navigator.defaultAngle1, navigator.defaultAngle2 };
     var defaultDuration = navigator.defaultDays * SecondsPerDay + navigator.defaultHours * SecondsPerHour;
     return new Control(navigator, controls, defaultAngles, navigator.defaultThrottle, navigator.defaultSailon, defaultDuration, navigator.defaultIWarp, navigator.defaultFrame);
 }
Beispiel #5
0
        public double AOPErr;     // Error in argument of periapsis

        /// Constructor
        public Preview(Navigator navigator)
        {
            this.navigator = navigator;
        }
Beispiel #6
0
        public double m1;                 // Final mass

        /// 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;
        }
        double UTf; // final time of trajectory

        #endregion Fields

        #region Constructors

        // Constructor
        public Preview(Navigator navigator)
        {
            this.navigator = 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;
        }
        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;
            }
        }