Esempio n. 1
0
            // TODO [Maybe] Implement isRunning

            public NacelleStator(
                IMyMotorStator stator, bool isMirrored,
                Func <string, bool, bool, Stack <string> > logger = null)
            {
                this.stator     = stator;
                properties      = new StatorProperties(PropertyLock, isMirrored, logger);
                properties.name = stator.CustomName;
                Log             = logger;
            }
Esempio n. 2
0
            /// <summary>
            /// Compares the current angle of the stator to the target angle. Returns true if there is
            /// no target angle set. (Hopefully temporary if Keen fixes the mismatched units between
            /// getters and setters.)
            /// </summary>
            public bool CompareTargetAngle()
            {
                if (properties.targetAngleRad == StatorProperties.INFINITE_ANGLE_RADIANS)
                {
                    return(true);
                }

                // Normalize to [-180, 180]
                float normCurrentAngleDeg = StatorProperties.NormalizeDeg(StatorProperties.RadToDeg(stator.Angle));

                // Normalize to [-π, π]
                float normCurrentAngleRad = StatorProperties.NormalizeRad(stator.Angle);

                double twoPi   = 2 * Math.PI;
                float  diffRad = (float)((Math.Abs(normCurrentAngleRad - properties.targetAngleRad) + twoPi) % twoPi);
                float  diffDeg = (Math.Abs(normCurrentAngleDeg - properties.targetAngleDeg) + 360) % 360;

                if (diffRad < 0.00008f || diffDeg < 0.0035f)
                {
                    return(true);
                }
                return(false);
            }
Esempio n. 3
0
            /// <summary>
            /// Runs the stator to match the target angle in its properties.
            /// </summary>
            public Func <IEnumerator <bool> > RunManagedMovement()
            {
                int rotationDirection = 1;

                float normCurrentAngle = StatorProperties.NormalizeDeg(StatorProperties.RadToDeg(stator.Angle));

                // Get the shortest direction of travel
                if ((properties.targetAngleDeg - normCurrentAngle + 360) % 360 > 180)
                {
                    rotationDirection = rotationDirection * -1;
                }

                // Check if the shortest direction intersects the limits
                if (properties.upperLimitRad != StatorProperties.INFINITE_ANGLE_RADIANS ||
                    properties.lowerLimitRad != -StatorProperties.INFINITE_ANGLE_RADIANS)
                {
                    // Check for segment intersections
                    if (Intersect(normCurrentAngle, properties.upperLimitDeg, properties.lowerLimitDeg) ||
                        Intersect(properties.targetAngleDeg, properties.upperLimitDeg, properties.lowerLimitDeg) ||
                        Intersect(properties.upperLimitDeg, normCurrentAngle, properties.targetAngleDeg) ||
                        Intersect(properties.lowerLimitDeg, normCurrentAngle, properties.targetAngleDeg))
                    {
                        rotationDirection = rotationDirection * -1;
                    }
                }

                // Apply the rotation angle
                stator.TargetVelocity = Math.Abs(StatorProperties.RpmToRads(stator.TargetVelocity)) * rotationDirection;

                // Get the absolute distance from the current angle to the target angle
                float diff  = Math.Abs(StatorProperties.RadToDeg(stator.Angle) - properties.targetAngleDeg);
                float limit = 0;

                // Set temporary limits to avoid overshoots
                if (stator.TargetVelocity > 0f)
                {
                    stator.SetValueFloat("UpperLimit", properties.targetAngleDeg);

                    // Stop the stator from having a starting angle greater than 360 degrees
                    // from the target angle
                    if (diff > 360)
                    {
                        // Set a limit that would make the starting angle be out of bounds and
                        // force the game to update starting angle within tighter limits
                        limit = StatorProperties.RadToDeg(stator.Angle) + 181;
                        stator.SetValueFloat("LowerLimit", limit);
                    }
                }
                else
                {
                    stator.SetValueFloat("LowerLimit", properties.targetAngleDeg);

                    if (diff > 360)
                    {
                        limit = StatorProperties.RadToDeg(stator.Angle) - 181;
                        stator.SetValueFloat("UpperLimit", limit);
                    }
                }

                // Turn the stator
                stator.SafetyLock = false;
                stator.Enabled    = true;

                return(Runner);
            }
Esempio n. 4
0
        /// <summary>
        /// Gets all managed stator blocks.
        /// </summary>
        private void GetBlocks()
        {
            // Reset static variables with stator data
            referenceStator = null;
            slaveStators.Clear();
            maxStateMachines    = 0;
            mirroredStators     = 0;
            copiedStators       = 0;
            referenceStatorName = "";

            // Prepare a list of stators
            List <IMyMotorStator> statorList = new List <IMyMotorStator>();

            // Get all stator blocks
            GridTerminalSystem.GetBlocksOfType(statorList);

            // Filter stator blocks
            foreach (IMyMotorStator stator in statorList)
            {
                NacelleStator managedStator;

                // Read Custom Data
                string val = stator.CustomData.ToLower();

                // Check if stator is configured
                if (val.Contains(reference.ToLower()))
                {
                    managedStator   = new NacelleStator(stator, Log);
                    referenceStator = managedStator;
                }
                else if (val.Contains(mirror.ToLower()))
                {
                    managedStator = new NacelleStator(stator, true, Log);
                    slaveStators.Add(managedStator);
                    mirroredStators++;
                }
                else if (val.Contains(copy.ToLower()))
                {
                    managedStator = new NacelleStator(stator, Log);
                    slaveStators.Add(managedStator);
                    copiedStators++;
                }
                else
                {
                    continue;
                }

                maxStateMachines++;

                StatorProperties properties = managedStator.Update();

                // Check if stator has an offset
                try { properties.Offset(float.Parse(IsolateSetValue(val, offset))); }
                catch { }

                // Check if stator has a lower limit
                try { properties.LowerLimit(float.Parse(IsolateSetValue(val, lowerLimit))); }
                catch { }

                // Check if stator has an upper limit
                try { properties.UpperLimit(float.Parse(IsolateSetValue(val, upperLimit))); }
                catch { }

                // Check if stator has a velocity
                try { properties.Velocity(float.Parse(IsolateSetValue(val, velocity))); }
                catch { }

                properties.Commit();
            }

            if (referenceStator == null)
            {
                Log("ERROR: No reference stator.");
                return;
            }

            foreach (NacelleStator slave in slaveStators)
            {
                slave.SetReference(referenceStator);
            }

            // Get the reference stator's name (for info purposes)
            referenceStatorName = referenceStator.stator.CustomName;
        }