bool initialize() { // setup cockpit List <IMyShipController> cockpits = new List <IMyShipController>(); GridTerminalSystem.GetBlocksOfType <IMyShipController>(cockpits, cockpit => { if (cockpit.IsMainCockpit || cockpit.CanControlShip) { return(true); } return(false); }); if (cockpits.Count > 0) { // use first cockpit cockpit_ = cockpits[0]; // setup gyros List <IMyGyro> gyroscopes = new List <IMyGyro>(); GridTerminalSystem.GetBlocksOfType <IMyGyro>(gyroscopes); gyroController_ = new GyroController(gyroscopes, cockpit_); } // search landing gears gears_ = new List <IMyLandingGear>(); GridTerminalSystem.GetBlocksOfType <IMyLandingGear>(gears_); messages_ = new LCDMessages(this); return(true); }
public HoverModule(CustomDataConfig config, GyroController gyroController, IMyShipController cockpit) { this.config = config; this.gyroController = gyroController; this.cockpit = cockpit; gyroResponsiveness = config.Get <int>("gyroResponsiveness"); maxPitch = config.Get <double>("maxPitch"); maxRoll = config.Get <double>("maxRoll"); AddAction("disabled", (args) => { gyroController.SetGyroOverride(false); }, null); AddAction("smart", (string[] args) => { smartDelayTimer = 0; setSpeed = (args.Length > 0 && args[0] != null) ? Int32.Parse(args[0]) : 0; }, () => { if (cockpit.MoveIndicator.Length() > 0.0f || cockpit.RotationIndicator.Length() > 0.0f) { desiredPitch = -(pitch - 90); desiredRoll = (roll - 90); gyroController.SetGyroOverride(false); smartDelayTimer = 0; } else if (smartDelayTimer > config.Get <int>("smartDelayTime")) { gyroController.SetGyroOverride(true); desiredPitch = Math.Atan((worldSpeedForward - setSpeed) / gyroResponsiveness) / Helpers.halfPi * maxPitch; desiredRoll = Math.Atan(worldSpeedRight / gyroResponsiveness) / Helpers.halfPi * maxRoll; } else { smartDelayTimer++; } }); AddAction("stop", null, () => { desiredPitch = Math.Atan(worldSpeedForward / gyroResponsiveness) / Helpers.halfPi * maxPitch; desiredRoll = Math.Atan(worldSpeedRight / gyroResponsiveness) / Helpers.halfPi * maxRoll; }); AddAction("glide", null, () => { desiredPitch = 0; desiredRoll = Math.Atan(worldSpeedRight / gyroResponsiveness) / Helpers.halfPi * maxRoll; }); AddAction("freeglide", null, () => { desiredPitch = 0; desiredRoll = 0; }); }
public VectorModule(CustomDataConfig config, GyroController gyroController, IMyShipController cockpit) { this.gyroController = gyroController; this.cockpit = cockpit; thrustVector = GetThrustVector(config.Get <string>("spaceMainThrust")); AddAction("disabled", (args) => { gyroController.SetGyroOverride(false); }, null); AddAction("brake", (args) => { startSpeed = cockpit.GetShipSpeed(); cockpit.DampenersOverride = false; }, SpaceBrake); AddAction("prograde", null, () => { TargetOrientation(-Vector3D.Normalize(cockpit.GetShipVelocities().LinearVelocity)); }); AddAction("retrograde", null, () => { TargetOrientation(Vector3D.Normalize(cockpit.GetShipVelocities().LinearVelocity)); }); }
public Program() { Runtime.UpdateFrequency = UpdateFrequency.Update1; configReader = new CustomDataConfig(Me, defaultConfig); GetBlocks(); gyroController = new GyroController(gyros, cockpit); hoverModule = new HoverModule(configReader, gyroController, cockpit); vectorModule = new VectorModule(configReader, gyroController, cockpit); string startCommand = configReader.Get <string>("startCommand"); if (startCommand != null) { ProcessCommand(startCommand); } else { gyroController.SetGyroOverride(false); } }
public void Update() { if (isFirstUpdate || configCache != Me.CustomData || Me.CustomData == "") { var config = new ConfigSection("main"); config.Read(Me.CustomData); blockGroupName = config.Get <string>("block_group_name", "Heli Assist"); start_mode = config.Get <string>("start_mode", "flight"); rememberLastMode = config.Get <bool>("remember_mode", true); maxFlightPitch = config.Get <float>("max_pitch", 40.0f); maxFlightRoll = config.Get <float>("max_roll", 40.0f); maxLandingPitch = config.Get <float>("max_landing_pitch", 15.0f); maxLandingRoll = config.Get <float>("max_landing_roll", 15.0f); precisionAimFactor = config.Get <float>("precision", 16.0f); mouseSpeed = config.Get <float>("mouse_speed", 0.5f); if (Me.CustomData == "") { Me.CustomData = configCache = config.write(); } else { configCache = Me.CustomData; } } var blockGroup = GridTerminalSystem.GetBlockGroupWithName(blockGroupName); if (blockGroup == null) { throw new Exception("Could not find block group with name '" + blockGroupName + "'"); } controllerCache.Clear(); blockGroup.GetBlocksOfType <IMyShipController>(controllerCache); if (!controllerCache.Any()) { throw new Exception("Ship must have at least one ship controller"); } controller = null; foreach (var controller in controllerCache) { if (controller.IsUnderControl || (controller.IsMainCockpit && this.controller == null)) { this.controller = controller; } } if (this.controller == null) { this.controller = controllerCache.First(); } gyroCache.Clear(); blockGroup.GetBlocksOfType <IMyGyro>(gyroCache); if (!gyroCache.Any()) { throw new Exception("Ship must have atleast one gyroscope"); } thrustCache.Clear(); blockGroup.GetBlocksOfType <IMyThrust>(thrustCache); if (!thrustCache.Any()) { throw new Exception("Ship must have atleast one thruster"); } if (thrustController == null) { thrustController = new ThrusterController(controller, thrustCache); } else { thrustController.Update(controller, thrustCache); } if (gyroController == null) { gyroController = new GyroController(controller, gyroCache); } else { gyroController.Update(controller, gyroCache); } if (isFirstUpdate && rememberLastMode && IsValidMode(Storage)) { SwitchToMode(Storage); } else if (isFirstUpdate) { SwitchToMode(start_mode); } isFirstUpdate = false; updateFinished = true; }
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)"); } }