2 * API index: https://github.com/malware-dev/MDK-SE/wiki/Api-Index
3 * Vector transformation: https://github.com/malware-dev/MDK-SE/wiki/Vector-Transformations-with-World-Matrices
4 * How to get rotation/position: https://forum.keenswh.com/threads/how-do-i-get-the-world-position-and-rotation-of-a-ship.7363867/
8 using Sandbox
.Game
.EntityComponents
;
9 using Sandbox
.ModAPI
.Ingame
;
10 using Sandbox
.ModAPI
.Interfaces
;
12 using SpaceEngineers
.Game
.ModAPI
.Ingame
;
15 using System
.Collections
;
16 using System
.Collections
.Generic
;
17 using System
.Collections
.Immutable
;
22 using VRage
.Collections
;
24 using VRage
.Game
.Components
;
25 using VRage
.Game
.GUI
.TextPanel
;
26 using VRage
.Game
.ModAPI
.Ingame
;
27 using VRage
.Game
.ModAPI
.Ingame
.Utilities
;
28 using VRage
.Game
.ObjectBuilders
.Definitions
;
31 using VRageMath
.Spatial
;
33 namespace IngameScript
35 partial class Program
: MyGridProgram
37 const int CONSOLE_NB_LINES
= 9;
38 const float MAX_SPEED
= 0.15f; // In rad per second.
39 const int NB_OF_GYRO
= 1000; // To limit the number of gyros set to overdrive.
43 NORMAL
, // Normal state: Manual commands.
48 State state
= State
.NORMAL
;
50 readonly Output output
;
52 IMyRemoteControl remoteController
;
54 readonly List
<IMyGyro
> gyros
= new List
<IMyGyro
>();
56 IMyBroadcastListener connnectorMinerPositionListener
;
57 MatrixD connectorMinerPosition
;
61 this.grid
= this.Me
.CubeGrid
;
63 var cockpits
= new List
<IMyCockpit
>();
64 this.GridTerminalSystem
.GetBlocksOfType(cockpits
);
65 IMyCockpit cockpit
= null;
66 foreach (var c
in cockpits
)
68 if (c
.CubeGrid
== this.grid
)
77 this.Echo("Can't find a cockpit");
81 this.output
= new Output(cockpit
, CONSOLE_NB_LINES
);
83 this.output
.Print("Intializing navigation control...");
85 var remoteControls
= new List
<IMyRemoteControl
>();
86 this.GridTerminalSystem
.GetBlocksOfType(remoteControls
);
87 foreach (var rc
in remoteControls
)
89 if (rc
.CubeGrid
== this.grid
)
91 this.remoteController
= rc
;
96 this.GridTerminalSystem
.GetBlocksOfType(
98 (IMyGyro gyro
) => gyro
.CubeGrid
== this.grid
101 if (this.remoteController
== null)
103 this.output
.Print("Can't find a remote controller");
108 this.connnectorMinerPositionListener
= this.IGC
.RegisterBroadcastListener("POSITION_CONNECTOR_MINER");
111 var sensor = this.GridTerminalSystem.GetBlockWithName("Sensor") as IMySensorBlock;
112 var entities = new List<MyDetectedEntityInfo>();
113 sensor.DetectedEntities(entities);
114 foreach (var entity in entities)
117 this.output.Print(entity.Name);
120 this.Runtime
.UpdateFrequency
= UpdateFrequency
.Update10
;
122 this.output
.Print("Navigation control initializing complete");
129 void UpdateStateAutoStabilization()
131 //var pos = this.remoteController.Position;
132 var gravity
= this.remoteController
.GetNaturalGravity().Normalized();
134 if (!Vector3D
.IsZero(gravity
))
136 var worldMatrix
= this.remoteController
.WorldMatrix
;
137 var up
= worldMatrix
.Up
;
138 var forward
= worldMatrix
.Forward
;
139 var left
= worldMatrix
.Left
;
141 //this.Print(gravity.ToString());
142 //gravity.ToString();
144 $"Gravity: {gravity.ToString("f2")}\n" +
145 $"Up: {up.ToString("f2")}\n" +
146 $"Foward: {forward.ToString("f2")}\n" +
147 $"Left: {left.ToString("f2")}\n",
151 var alpha
= (float)Math
.Asin(up
.Dot(gravity
));
152 var beta
= (float)Math
.Asin(left
.Dot(gravity
));
155 $"Alpha: {alpha}\n" +
157 $"Is under control: {this.remoteController.IsUnderControl}",
161 for (int i
= 0; i
< NB_OF_GYRO
&& i
< this.gyros
.Count
; i
++)
163 var gyro
= this.gyros
[i
];
164 gyro
.Pitch
= MathHelper
.Clamp(-alpha
, -MAX_SPEED
, MAX_SPEED
);
165 gyro
.Roll
= MathHelper
.Clamp(beta
, -MAX_SPEED
, MAX_SPEED
);
170 void UpdateStateAutoDocking()
172 if (this.connnectorMinerPositionListener
.HasPendingMessage
)
173 this.connectorMinerPosition
= this.connnectorMinerPositionListener
.AcceptMessage().As
<MatrixD
>();
175 if (this.connectorMinerPosition
.IsValid())
177 this.output
.Display($"Connector position:\n{this.connectorMinerPosition}", 3);
181 this.output
.Display($"NOPE", 3);
189 case State
.AUTO_STABILIZATION
:
190 this.UpdateStateAutoStabilization();
192 case State
.AUTO_DOCKING
:
193 this.UpdateStateAutoDocking();
200 void UpdateStateMachine(State newState
)
202 if (this.state
== newState
)
205 if (newState
== State
.NORMAL
)
209 case State
.AUTO_STABILIZATION
:
210 foreach (var gyro
in this.gyros
)
211 gyro
.GyroOverride
= false;
212 this.state
= State
.NORMAL
;
213 this.output
.Print("Auto stabilization disabled");
215 case State
.AUTO_DOCKING
:
216 this.state
= State
.NORMAL
;
217 this.output
.Print("Auto docking disabled");
226 this.UpdateStateMachine(State
.NORMAL
);
229 case State
.AUTO_STABILIZATION
:
230 for (int i
= 0; i
< NB_OF_GYRO
&& i
< this.gyros
.Count
; i
++)
232 var gyro
= this.gyros
[i
];
233 gyro
.GyroOverride
= true;
239 this.state
= State
.AUTO_STABILIZATION
;
240 this.output
.Print("Auto stabilization enabled");
242 case State
.AUTO_DOCKING
:
243 this.state
= State
.AUTO_DOCKING
;
244 this.output
.Print("Auto docking enabled");
252 public void Main(string argument
, UpdateType updateSource
)
254 if ((updateSource
& UpdateType
.Update10
) != 0)
258 else if ((updateSource
& (UpdateType
.Terminal
| UpdateType
.Trigger
)) != 0)
262 case "SWITCH_AUTO_STABILIZATION":
263 if (this.state
!= State
.AUTO_STABILIZATION
)
264 this.UpdateStateMachine(State
.AUTO_STABILIZATION
);
266 this.UpdateStateMachine(State
.NORMAL
);
269 case "SWITCH_AUTO_DOCKING":
270 if (this.state
!= State
.AUTO_DOCKING
)
271 this.UpdateStateMachine(State
.AUTO_DOCKING
);
273 this.UpdateStateMachine(State
.NORMAL
);
277 this.output
.Print($"Uknown command: {argument}");