public void Main(string args = "START") { Config config = new Config(Me.CustomData); config.Set(ref thrustersGroupName, "thrustersGroupName"); config.Set(ref referenceBlockName, "referenceBlockName"); config.Set(ref lcdSearchName, "lcdSearchName"); config.Set <double>(ref marginOfErrorThrust, "marginOfErrorThrust"); config.Set <double>(ref targetSpeed, "targetSpeed"); config.Set <double>(ref targetSpeedVariation, "targetSpeedVariation"); config.Set <double>(ref gravityTreshold, "gravityTreshold"); controlBlock = GridTerminalSystem.GetBlockWithName(referenceBlockName) as IMyShipController; lcds = SearchBlocksWithName <IMyTextPanel>(lcdSearchName); if (args == "START") { Runtime.UpdateFrequency = UpdateFrequency.Update10; reachedTopSpeedOnce = false; turnAndBurn = null; } lcds.ForEach(lcd => { lcd.WritePublicTitle("Launch control"); lcd.WritePublicText(""); // Clear LCD }); if (controlBlock == null) { WriteLine("No control block found on grid."); WriteLine("Terminating script."); return; } thrusters = GetBlocksInGroup <IMyThrust>(thrustersGroupName); thrustController = new ThrustController(thrusters); gyros = GetBlocksOfType <IMyGyro>(); gyroController = new GyroController(controlBlock, gyros, Base6Directions.Direction.Down, 0.8); gravity = controlBlock.GetNaturalGravity(); gravityStrength = gravity.Length(); var escaped = gravityStrength <= gravityTreshold; gravity.Normalize(); if (gravityStrength != 0) { lastObservedGravity = gravity; } if (thrusters == null || thrusters.Count == 0) { WriteLine($"No thrusters found in \"{thrustersGroupName}\" group."); WriteLine("Terminating script."); return; } speed = controlBlock.GetShipSpeed(); if (speed > targetSpeed) { reachedTopSpeedOnce = true; } WriteLine($"Ship speed: {Math.Round(speed, 1)} m/s"); WriteLine($"Target: {Math.Round(targetSpeed, 1)} m/s"); if (!escaped) { ApplyThrust(); gyroController.Align(gravity); angle = Math.Acos( Vector3D.Dot( Vector3D.Normalize(controlBlock.GetNaturalGravity()), Vector3D.Normalize(-controlBlock.GetShipVelocities().LinearVelocity) ) ) * 180 / Math.PI; WriteLine($"Angle deviation: {Math.Round(angle)}°"); } if (escaped) { if (turnAndBurn == null) { thrustController.Stop(); SetDampeners(false); } turnAndBurn = gyroController.Align(lastObservedGravity, Base6Directions.Direction.Up) ? "aligned" : "started"; WriteLine($"Turn and burn: {turnAndBurn}"); } if (args == "STOP" || (escaped && turnAndBurn == "aligned")) { thrustController.Stop(); gyroController.Stop(); SetDampeners(true); Runtime.UpdateFrequency = UpdateFrequency.None; ClearOutput(); WriteLine("Launch control ended."); } }
public void Main(string input) { lcds = SearchBlocksWithName <IMyTextPanel>(lcdSearchName); ClearOutput(); if (input == "start") { Runtime.UpdateFrequency = UpdateFrequency.Update10; Autopilot = true; } IMyShipController controlBlock = (IMyShipController)GridTerminalSystem.GetBlockWithName(ShipControllerName); double altitude = 0; bool InsideNaturalGravity = controlBlock.TryGetPlanetElevation(MyPlanetElevation.Surface, out altitude); Vector3D velocity3D = controlBlock.GetShipVelocities().LinearVelocity; if (!InsideNaturalGravity) { if (Autopilot) { WriteLine("Waiting for entering natural gravity"); if (input == "stop") { Autopilot = false; WriteLine("Autopilot deactivated (manually)"); } } return; } else { if (Autopilot && AutoFall) { if (!AutoFallUsed) { input = "fall"; AutoFallUsed = true; } } } List <IMyThrust> thrusters = GetBlocksInGroup <IMyThrust>(HydrogenThrustersGroupName); ThrustController thrustController = new ThrustController(thrusters); gyros = GetBlocksOfType <IMyGyro>(); gyroController = new GyroController(controlBlock, gyros, Base6Directions.Direction.Down, RotationSpeedLimit); Vector3D gravity = controlBlock.GetNaturalGravity(); Vector3D position = controlBlock.GetPosition(); // ship coords double gravityStrength = gravity.Length(); // gravity in m/s^2 double totalMass = controlBlock.CalculateShipMass().TotalMass; // ship total mass including cargo mass double baseMass = controlBlock.CalculateShipMass().BaseMass; // mass of the ship without cargo double cargoMass = totalMass - baseMass; // mass of the cargo double actualMass = baseMass + (cargoMass / InventoryMultiplier); // the mass the game uses for physics calculation double shipWeight = actualMass * gravityStrength; // weight in newtons of the ship double velocity = controlBlock.GetShipSpeed(); // ship velocity double brakeDistance = CalculateBrakeDistance(gravityStrength, actualMass, altitude, thrustController.availableThrust, velocity); double brakeAltitude = StopAltitude + brakeDistance; // at this altitude the ship will start slowing Down if (Autopilot) { gyroController.Align(gravity); if (input == "fall") { // This is a workaround to a game bug (ship speed greater than speed limit when free falling in natural gravity) // Pros: your ship will not crash. Cons: you will waste a tiny amount of hydrogen. thrustController.ApplyThrust(1); } if (altitude <= (brakeAltitude + AltitudeMargin)) { // BRAKE!!! thrustController.ApplyFullThrust(); // Maybe just enable dampeners } if (altitude <= (StopAltitude + DisableMargin + AltitudeMargin)) { if (velocity < StopSpeed) { gyroController.Stop(); WriteLine("Autopilot deactivated (automatically)"); } if (SmartDeactivation) { if (OldVelocity3D.X * velocity3D.X < 0 || OldVelocity3D.Y * velocity3D.Y < 0 || OldVelocity3D.Z * velocity3D.Z < 0) { gyroController.Stop(); WriteLine("Autopilot deactivated (automatically)"); } } } } OldVelocity3D = velocity3D; if (input == "stop") { Runtime.UpdateFrequency = UpdateFrequency.None; gyroController.Stop(); thrustController.Stop(); WriteLine("Autopilot deactivated (manually)"); } }