// 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; }
/// <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); }
/// <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); }
/// <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; }