Fix various bugs and inconsistencies.

This commit is contained in:
Anna Rose 2025-02-07 09:06:42 -05:00
parent 44d161f5c0
commit 445c1205f9
2 changed files with 83 additions and 44 deletions

View File

@ -3,77 +3,100 @@
// * Connect any Connectors whose names start with "Docking Port" that are ready to connect. // * Connect any Connectors whose names start with "Docking Port" that are ready to connect.
// * Turn off all engines. // * Turn off all engines.
// * Set all O2 and Hydrogen tanks to Stockpile. // * Set all O2 and Hydrogen tanks to Stockpile.
// * Set all batteries to Recharge. //
// Recharging batteries needs to be done manually, since the script can't finish with the
// batteries disabled.
// //
// When you activate the script with "-undock" it will reverse all of these actions. // When you activate the script with "-undock" it will reverse all of these actions.
// //
// TODO: None of the below switches work yet. // TODO: None of the below switches work yet.
// You can selectively disable some functionality with switches. // You can selectively disable some functionality with switches.
// * "-no-refuel" to disable refueling // * "-no-refuel" to disable refueling
// * "-no-recharge" to disable battery recharge
// (batteries will be left in whatever state they are already in)
MyCommandLine cli; MyCommandLine cli;
IEnumerator<bool> state;
List<IMyShipConnector> dockingPorts; List<IMyShipConnector> dockingPorts;
List<IMyThrust> thrusters; List<IMyThrust> thrusters;
List<IMyBatteryBlock> batteries;
List<IMyGasTank> tanks; List<IMyGasTank> tanks;
public void Program() { public Program() {
cli = new MyCommandLine(); cli = new MyCommandLine();
state = null;
dockingPorts = new List<IMyShipConnector>(); dockingPorts = new List<IMyShipConnector>();
List<IMyShipConnector> allConnectors = new List<IMyShipConnector>(); List<IMyShipConnector> allConnectors = new List<IMyShipConnector>();
foreach(IMyShipConnector connector in allConnectors) { GridTerminalSystem.GetBlocksOfType(allConnectors);
if (connector.CustomName.StartsWith("Docking Port")) { foreach(IMyShipConnector connector in allConnectors) {
dockingPorts.Add(connector); if (connector.CustomName.StartsWith("Docking Port")) {
} dockingPorts.Add(connector);
} }
}
thrusters = new List<IMyThrust>(); thrusters = new List<IMyThrust>();
GridTerminalSystem.GetBlocksOfType(thrusters); GridTerminalSystem.GetBlocksOfType(thrusters);
batteries = new List<IMyBatteryBlock>(); tanks = new List<IMyGasTank>();
GridTerminalSystem.GetBlocksOfType(batteries); GridTerminalSystem.GetBlocksOfType(tanks);
tanks = new List<IMyGasTank>(); Echo($"Found {dockingPorts.Count} docking ports.");
GridTerminalSystem.GetBlocksOfType(tanks); Echo($"Found {thrusters.Count} thrusters");
Echo($"Found {tanks.Count} tanks");
} }
public void Main(string argument, UpdateType updateSource) { public void Main(string argument, UpdateType updateSource) {
cli.TryParse(argument); if (state == null) {
if (cli.Switch("undock")) Undock(); cli.TryParse(argument);
else Dock(); if (cli.Switch("undock")) state = Undock();
else state = Dock();
Runtime.UpdateFrequency = UpdateFrequency.Update100;
return;
}
if (!state.MoveNext()) {
Runtime.UpdateFrequency = UpdateFrequency.None;
state.Dispose();
state = null;
}
} }
private void Dock() { private IEnumerator<bool> Dock() {
Echo("Initiating docking operation.");
foreach (IMyShipConnector dockingPort in dockingPorts) { foreach (IMyShipConnector dockingPort in dockingPorts) {
if (dockingPort.Status == MyShipConnectorStatus.Connectable) { if (dockingPort.Status == MyShipConnectorStatus.Connectable) {
dockingPort.Connect(); dockingPort.Connect();
} }
} }
bool docked = false;
while (!docked) {
yield return true;
foreach (IMyShipConnector dockingPort in dockingPorts) {
if (dockingPort.Status == MyShipConnectorStatus.Connected) {
docked = true;
break;
}
}
}
Echo("Docking clamp engaged. Shutting down systems.");
foreach (IMyThrust thruster in thrusters) { foreach (IMyThrust thruster in thrusters) {
thruster.Enabled = false; thruster.Enabled = false;
} }
foreach (IMyBatteryBlock battery in batteries) {
battery.ChargeMode = ChargeMode.Recharge;
}
foreach (IMyGasTank tank in tanks) { foreach (IMyGasTank tank in tanks) {
tank.Stockpile = true; tank.Stockpile = true;
} }
yield return false;
} }
private void Undock() { private IEnumerator<bool> Undock() {
foreach (IMyBatteryBlock battery in batteries) { Echo("Initiating undocking operation.");
battery.ChargeMode = ChargeMode.Recharge;
}
foreach (IMyGasTank tank in tanks) { foreach (IMyGasTank tank in tanks) {
tank.Stockpile = true; tank.Stockpile = false;
} }
foreach (IMyThrust thruster in thrusters) { foreach (IMyThrust thruster in thrusters) {
@ -82,7 +105,9 @@ private void Undock() {
foreach (IMyShipConnector dockingPort in dockingPorts) { foreach (IMyShipConnector dockingPort in dockingPorts) {
if (dockingPort.Status == MyShipConnectorStatus.Connected) { if (dockingPort.Status == MyShipConnectorStatus.Connected) {
dockingPort.Disconnect(); dockingPort.Disconnect();
} }
} }
yield return false;
} }

View File

@ -23,29 +23,32 @@ public class Panel {
ParseConfig(); ParseConfig();
} }
// For these two functions, IMyMotorStator.Angle reports radians, but
// IMyMotorStator.RotateToAngle() expects degrees...
public void OpenPanel() { public void OpenPanel() {
Hinge.RotorLock = false; Hinge.RotorLock = false;
TargetAngle = OpenAngle; TargetAngle = DegToRad(OpenAngle);
Hinge.RotateToAngle(MyRotationDirection.AUTO, TargetAngle, Velocity); Hinge.RotateToAngle(MyRotationDirection.AUTO, OpenAngle, Velocity);
} }
public void ClosePanel() { public void ClosePanel() {
Hinge.RotorLock = false; Hinge.RotorLock = false;
TargetAngle = ClosedAngle; TargetAngle = DegToRad(ClosedAngle);
Hinge.RotateToAngle(MyRotationDirection.AUTO, TargetAngle, Velocity); Hinge.RotateToAngle(MyRotationDirection.AUTO, ClosedAngle, Velocity);
} }
// Call this function every tick after OpenPanel or ClosePanel. // Call this function every tick after OpenPanel or ClosePanel.
// It will return true when the panel has finished moving. // It will return true when the panel has finished moving.
public bool Monitor() { public bool Monitor() {
if (Math.Abs(Hinge.Angle - TargetAngle) < 0.01) { if (Math.Abs(Hinge.Angle - TargetAngle) < 0.001) {
Hinge.RotorLock = true; Hinge.RotorLock = true;
} }
return Hinge.RotorLock; return Hinge.RotorLock;
} }
private IMyMotorStator Hinge { get; set; } // TODO: these are public for debugging
private float TargetAngle { get; set; } public IMyMotorStator Hinge { get; set; }
public float TargetAngle { get; set; }
private float OpenAngle { get; set; } = 90F; private float OpenAngle { get; set; } = 90F;
private float ClosedAngle { get; set; } = 0F; private float ClosedAngle { get; set; } = 0F;
private float Velocity { get; set; } = 5F; private float Velocity { get; set; } = 5F;
@ -68,6 +71,12 @@ public class Panel {
} }
} }
} }
// TODO: a utility class or function would be lovely...
// In general, the encapsulation feels a little screwy here.
private float DegToRad(float degrees) {
return degrees * ((float)Math.PI / 180F);
}
} }
public Program() { public Program() {
@ -76,13 +85,14 @@ public Program() {
panels = new List<Panel>(); panels = new List<Panel>();
List<IMyMotorStator> allHinges = new List<IMyMotorStator>(); List<IMyMotorStator> allHinges = new List<IMyMotorStator>();
GridTerminalSystem.GetBlocksOfType(allHinges);
foreach(IMyMotorStator hinge in allHinges) { foreach(IMyMotorStator hinge in allHinges) {
if (hinge.CustomName.StartsWith("Maintenance")) { if (hinge.CustomName.StartsWith("Maintenance")) {
panels.Add(new Panel(hinge)); panels.Add(new Panel(hinge));
} }
} }
Echo($"Found {panels.Length} panels."); Echo($"Found {panels.Count} panels.");
} }
public void Main(string argument, UpdateType updateSource) { public void Main(string argument, UpdateType updateSource) {
@ -95,6 +105,7 @@ public void Main(string argument, UpdateType updateSource) {
} }
if (!state.MoveNext()) { if (!state.MoveNext()) {
Echo("Operation Complete.");
state.Dispose(); state.Dispose();
state = null; state = null;
Runtime.UpdateFrequency = UpdateFrequency.None; Runtime.UpdateFrequency = UpdateFrequency.None;
@ -122,7 +133,10 @@ private IEnumerator<bool> MonitorPanels() {
Echo("Monitoring panels."); Echo("Monitoring panels.");
bool done = true; // assume we've finished, then falsify it below bool done = true; // assume we've finished, then falsify it below
foreach (Panel panel in panels) { foreach (Panel panel in panels) {
if (!panel.Monitor()) done = false; if (!panel.Monitor()) {
Echo($"{panel.TargetAngle} {panel.Hinge.Angle}");
done = false;
}
} }
if (done) yield break; if (done) yield break;
yield return true; yield return true;