Exemplo n.º 1
0
 public SolverTask(RCSSolverKey key, Vector3 direction, Vector3 rotation)
 {
     this.key           = key;
     this.direction     = direction;
     this.rotation      = rotation;
     this.timeSubmitted = DateTime.Now;
 }
Exemplo n.º 2
0
        // Throttles RCS thrusters to keep a vessel balanced during translation.
        protected void AdjustRCSThrottles(FlightCtrlState s)
        {
            bool cutThrottles = false;

            if (s.X == 0 && s.Y == 0 && s.Z == 0)
            {
                solverThread.ResetThrusterForces();
            }

            // Note that FlightCtrlState doesn't use the same axes as the
            // vehicle's reference frame. FlightCtrlState coordinates are right-
            // handed, with vessel prograde being -Z. Vessel coordinates
            // are left-handed, with vessel prograde being +Y. Here's how
            // FlightCtrlState relates to various ship directions (and their
            // default keyboard shortcuts):
            //           up (i): y -1
            //         down (k): y +1
            //         left (j): x +1
            //        right (l): x -1
            //      forward (h): z -1
            //     backward (n): z +1
            // To turn this vector into a vessel-relative one, we need to negate
            // each value and also swap the Y and Z values.
            Vector3 direction = new Vector3(-s.X, -s.Z, -s.Y);

            // RCS balancing on rotation isn't supported.
            //Vector3 rotation = new Vector3(s.pitch, s.roll, s.yaw);

            RCSSolverKey.SetPrecision(calcPrecision);
            GetThrottles(direction, out throttles, out thrusters);

            // If the throttles we got were bad (due to the threaded
            // calculation not having completed yet), cut throttles. It's
            // better to not move at all than move in the wrong direction.
            if (throttles.Length != thrusters.Count)
            {
                throttles    = new double[thrusters.Count];
                cutThrottles = true;
            }

            if (cutThrottles)
            {
                for (int i = 0; i < throttles.Length; i++)
                {
                    throttles[i] = 0;
                }
            }

            // Apply the calculated throttles to all RCS parts.
            for (int i = 0; i < thrusters.Count; i++)
            {
                thrusters[i].partModule.thrusterPower = (float)throttles[i];
            }
        }
Exemplo n.º 3
0
        // The list of throttles is ordered under the assumption that you iterate
        // over the vessel as follows:
        //      foreach part in vessel.parts:
        //          foreach rcsModule in part.Modules.OfType<ModuleRCS>:
        //              ...
        // Note that rotation balancing is not supported at the moment.
        public void GetThrottles(Vessel vessel, VesselState state, Vector3 direction,
                                 out double[] throttles, out List <RCSSolver.Thruster> thrustersOut)
        {
            thrustersOut = callerThrusters;

            Vector3 rotation = Vector3.zero;

            var rcsBalancer = VesselExtensions.GetMasterMechJeb(vessel).rcsbal;

            // Update vessel info if needed.
            CheckVessel(vessel, state);

            Vector3      dir = direction.normalized;
            RCSSolverKey key = new RCSSolverKey(ref dir, rotation);

            if (thrusters.Count == 0)
            {
                throttles = double0;
            }
            else if (direction == Vector3.zero)
            {
                throttles = originalThrottles;
            }
            else if (results.TryGetValue(key, out throttles))
            {
                cacheHits++;
            }
            else
            {
                // This task hasn't been calculated. We'll handle that here.
                // Meanwhile, TryGetValue() will have set 'throttles' to null, but
                // we'll make it a 0-element array instead to avoid null checks.
                cacheMisses++;
                throttles = double0;

                if (pending.Contains(key))
                {
                    // We've submitted this key before, so we need to check the
                    // results queue.
                    while (resultsQueue.Count > 0)
                    {
                        SolverResult sr = (SolverResult)resultsQueue.Dequeue();
                        results[sr.key] = sr.throttles;
                        pending.Remove(sr.key);
                        if (sr.key == key)
                        {
                            throttles = sr.throttles;
                        }
                    }
                }
                else
                {
                    // This task was neither calculated nor pending, so we've never
                    // submitted it. Do so!
                    pending.Add(key);
                    tasks.Enqueue(new SolverTask(key, dir, rotation));
                    workEvent.Set();
                }
            }

            // Return a copy of the array to make sure ours isn't modified.
            throttles = (double[])throttles.Clone();
        }
Exemplo n.º 4
0
 public SolverResult(RCSSolverKey key, double[] throttles)
 {
     this.key       = key;
     this.throttles = throttles;
 }
Exemplo n.º 5
0
 public SolverTask(RCSSolverKey key, Vector3 direction, Vector3 rotation)
 {
     this.key = key;
     this.direction = direction;
     this.rotation = rotation;
     this.timeSubmitted = DateTime.Now;
 }
Exemplo n.º 6
0
 public SolverResult(RCSSolverKey key, double[] throttles)
 {
     this.key = key;
     this.throttles = throttles;
 }
Exemplo n.º 7
0
        // The list of throttles is ordered under the assumption that you iterate
        // over the vessel as follows:
        //      foreach part in vessel.parts:
        //          foreach rcsModule in part.Modules.OfType<ModuleRCS>:
        //              ...
        // Note that rotation balancing is not supported at the moment.
        public void GetThrottles(Vessel vessel, VesselState state, Vector3 direction,
            out double[] throttles, out List<RCSSolver.Thruster> thrustersOut)
        {
            thrustersOut = callerThrusters;

            Vector3 rotation = Vector3.zero;

            var rcsBalancer = VesselExtensions.GetMasterMechJeb(vessel).rcsbal;

            // Update vessel info if needed.
            CheckVessel(vessel, state);

            Vector3 dir = direction.normalized;
            RCSSolverKey key = new RCSSolverKey(ref dir, rotation);

            if (thrusters.Count == 0)
            {
                throttles = double0;
            }
            else if (direction == Vector3.zero)
            {
                throttles = originalThrottles;
            }
            else if (results.TryGetValue(key, out throttles))
            {
                cacheHits++;
            }
            else
            {
                // This task hasn't been calculated. We'll handle that here.
                // Meanwhile, TryGetValue() will have set 'throttles' to null, but
                // we'll make it a 0-element array instead to avoid null checks.
                cacheMisses++;
                throttles = double0;

                if (pending.Contains(key))
                {
                    // We've submitted this key before, so we need to check the
                    // results queue.
                    while (resultsQueue.Count > 0)
                    {
                        SolverResult sr = (SolverResult)resultsQueue.Dequeue();
                        results[sr.key] = sr.throttles;
                        pending.Remove(sr.key);
                        if (sr.key == key)
                        {
                            throttles = sr.throttles;
                        }
                    }
                }
                else
                {
                    // This task was neither calculated nor pending, so we've never
                    // submitted it. Do so!
                    pending.Add(key);
                    tasks.Enqueue(new SolverTask(key, dir, rotation));
                    workEvent.Set();
                }
            }

            // Return a copy of the array to make sure ours isn't modified.
            throttles = (double[])throttles.Clone();
        }