Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
199 changes: 140 additions & 59 deletions DrillingRig/DrillingRig.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/** DrillingRig.cs v. 0.31
/** DrillingRig.cs v. 0.4

Drilling program for Space Engineers.
Author: mkazin
Expand All @@ -8,15 +8,22 @@
**/

// Number of times a rotor will swing in an arc across the current distance
// Has a linear relationship with rotor RPM.
// Generally has a linear relationship with rotor RPM. Can be reduced by using
// a multi-drill head.
// Do not lower below two, which allows for distance piston to retract.
// Setting your rotor at above 2RPM will increase the chances of the drill arm getting stuck.
const int MAX_ROTOR_SWINGS = 2;
// You can probably get away with 4 RPM, though at this speed you should be monitoring the drill.
// At 5 RPM this script has proven to fail with a cross-shaped drill head (I'm thinking
// of attaching a rotor to the drill head and maybe trying a square-shaped drill head
// to see if that saves me).
const int MAX_ROTOR_SWINGS = 3;

// Amount to increse the distance piston after we finish our swings in meters.
const float DISTANCE_DELTA = 2.0f;
// The wider the drill head on the distance axis, the bigger you can make this.
// Best to use the quotient of a the length of the piston divided by an integer to avoid remainders.
const float DISTANCE_DELTA = 2.5f;

// Amount to raise drill pistons/lower lift pistons between swing sets.
// Amount to extend drill pistons/retract lift pistons between swing sets to lower the drill head.
const float HEIGHT_DELTA = 0.4f;

// Constants which differ per drill
Expand All @@ -43,6 +50,20 @@
const string NAME_LCD = "Drill - LCD";
/**/


/*** New Cobalt Mine ****
private static List<string> NAME_DRILL_PISTONS = new List<String>() {
"Drill Piston - 1st",
"Drill Piston - 2nd"};
private static List<string> NAME_LIFT_PISTONS = new List<String>() {
"Drill - Lift Piston - Lower",
"Drill - Lift Piston - Upper" };
const string NAME_DISTANCE_PISTON = "Drill - Distance Piston";
const string NAME_ROTOR = "Drill - Advanced Rotor";
const string NAME_LCD = "Drill - LCD";
/**/


/*** Money Pit (gold & silver) ****
private static List<string> NAME_DRILL_PISTONS = new List<String>() {
"Drill Piston - 1st",
Expand All @@ -57,6 +78,22 @@
const string NAME_LCD = "Drill LCD";
/**/


//*** Money Pit Redix (more gold & silver) ****
private static List<string> NAME_DRILL_PISTONS = new List<String>() {
"Drill Piston - 1st",
"Drill Piston - 2nd",
"Drill Piston - 3rd",
"Drill Piston - 4th",
"Drill Piston - 5th" };
private static List<string> NAME_LIFT_PISTONS = new List<String>() {
"Lift Piston - Lower",
"Lift Piston - Upper" };
const string NAME_DISTANCE_PISTON = "Distance Piston";
const string NAME_ROTOR = "Drill Rotor";
const string NAME_LCD = "Drill LCD";
/**/

/*** Silver Drill (HQ) ***
private static List<string> NAME_DRILL_PISTONS = new List<String>() {
"Silver Drill - Lower Drill Piston",
Expand Down Expand Up @@ -92,7 +129,7 @@
const string NAME_LCD = "Drill B - LCD";
/**/

//*** Drill C ***
/*** Drill C ***
private static List<string> NAME_DRILL_PISTONS = new List<String>() {
"Drill C - Drill Piston - 1st",
"Drill C - Drill Piston - 2nd",
Expand All @@ -118,8 +155,11 @@
const string NAME_ROTOR = "Iron Drill - Advanced Rotor";
/**/

// How many times the rotor's direction has been reversed at the current distance/angle settings
int motorSwing = 1;

int motorSwing = 0; // How many times the rotor's direction has been reversed at the current distance/angle settings
// Direction the rotor is moving. 1 = clockwise, -1 = counter-clockwise (positive/negative sign of RPM).
float rotorDirection = 1;

// List of pistons used to adjust height of the drill. Does NOT include the distance piston.
List<IMyPistonBase> drillPistons = new List<IMyPistonBase>();
Expand Down Expand Up @@ -162,6 +202,7 @@ public Program()

distancePiston = GridTerminalSystem.GetBlockWithName(NAME_DISTANCE_PISTON) as IMyPistonBase;
rotor = GridTerminalSystem.GetBlockWithName(NAME_ROTOR) as IMyMotorAdvancedStator;
rotorDirection = rotor.TargetVelocityRPM < 0.0f ? -1.0f : 1.0f;

lcd = GridTerminalSystem.GetBlockWithName(NAME_LCD) as IMyTextSurface;
ClearLCD();
Expand All @@ -173,17 +214,20 @@ public Program()

public void Save() {
string data = "";
data += String.Format("{0:.##}", distancePiston.CurrentPosition) + DELIMITER_GROUP;
data += String.Format("{0:0.##}", distancePiston.CurrentPosition) + DELIMITER_GROUP;

foreach(IMyPistonBase piston in liftPistons) {
data += String.Format("{0:.##}", piston.CurrentPosition) + DELIMITER_ITEM;
data += String.Format("{0:0.##}", piston.CurrentPosition) + DELIMITER_ITEM;
}
data += DELIMITER_GROUP;

foreach(IMyPistonBase piston in drillPistons) {
data += String.Format("{0:.##}", piston.CurrentPosition) + DELIMITER_ITEM;
data += String.Format("{0:0.##}", piston.CurrentPosition) + DELIMITER_ITEM;
}

data += DELIMITER_GROUP;
data += haltAndCatchFire;

Storage = data;
}

Expand All @@ -198,33 +242,46 @@ public bool Load() {
Output("Storage: " + Storage);
string[] storedData = Storage.Split(DELIMITER_GROUP);
if (storedData.Length == 0) {
Output("Invalid data in Storage");
Output("Invalid data in Storage - Missing delimeters");
return false;
}

float value;
if (! float.TryParse(storedData[0], out value)) {
Output("Invalid data in Storage");
return false;
}
distancePiston.MaxLimit = value;

try {
// Backward-compatiblity support for <= 0.32 which stored empty strings for pistons at 0.0
distancePiston.MaxLimit = storedData[0].Length == 0 ? 0.0f : float.Parse(storedData[0]);
Output("Loaded " + distancePiston.CustomName + " : [[" + distancePiston.MaxLimit + "]]");

string[] liftPistonData = storedData[1].Split(DELIMITER_ITEM);
for (int index=0; index < liftPistonData.Length - 1; index++) {
liftPistons[index].MinLimit = float.Parse(liftPistonData[index]);
// Backward-compatiblity support for <= 0.32 which stored empty strings for pistons at 0.0
liftPistons[index].MinLimit = liftPistonData[index].Length == 0 ? 0.0f : float.Parse(liftPistonData[index]);
Output("Loaded " + liftPistons[index].CustomName + " : [[" + liftPistons[index].MinLimit + "]]");
}

string[] drillPistonData = storedData[2].Split(DELIMITER_ITEM);
for (int index=0; index < drillPistonData.Length - 1; index++) {
drillPistons[index].MaxLimit = float.Parse(drillPistonData[index]);
// Backward-compatiblity support for <= 0.32 which stored empty strings for pistons at 0.0
drillPistons[index].MaxLimit = drillPistonData[index].Length == 0 ? 0.0f : float.Parse(drillPistonData[index]);
Output("Loaded " + drillPistons[index].CustomName + " : [[" + drillPistons[index].MaxLimit + "]]");
}
} catch {
Output("Invalid data in Storage");
Output("Invalid data in Storage. Resetting it.");
Storage = "";
return false;
}

// Check if we stored a value for haltAndCatchFire
// (to remain backward-compatible with versions <= 0.32)
if (storedData.Length >= 4) {
haltAndCatchFire = bool.Parse(storedData[3]);
if (haltAndCatchFire) {
// Note: this will be our only output.
Output("Drilling rig completed program using current parameters.");
}
} else {
haltAndCatchFire = false;
}

return true;
}

Expand Down Expand Up @@ -252,13 +309,8 @@ public void resetPistons() {
inPistonRetract = true;
}

public void Main()
public void Main(string argument, UpdateType updateSource)
{
// if (initialSetup) {
// resetPistons();
// initialSetup = false;
// }

if (haltAndCatchFire) {
return;
}
Expand All @@ -280,27 +332,31 @@ public void Main()
}
}

if (rotorStopped()) {
rotor.TargetVelocityRPM = -rotor.TargetVelocityRPM;
if (rotorAtMax()) {
// TargetVelocityRPM is unreliable at higher velocities due to bounce-back,
// so we need to track and set clockwise/counterclockwise direction.
rotorDirection *= -1.0f;
rotor.TargetVelocityRPM = rotorDirection * Math.Abs(rotor.TargetVelocityRPM);
Output("Reversed rotor");
Output("Velocity set to:" + rotor.TargetVelocityRPM + " RPM");
Output("Velocity set to:" + formatToTwo(rotor.TargetVelocityRPM) + " RPM");
if (motorSwing < MAX_ROTOR_SWINGS) {
motorSwing += 1;
Output("Starting swing #" + motorSwing);
} else {

Output("Completed all swings (" + motorSwing + ")");
motorSwing = 0;
motorSwing = 1;

if (distancePiston.MaxLimit == distancePiston.HighestPosition) {

Output("Retracting distance piston");
distancePiston.MaxLimit = distancePiston.LowestPosition;

if (! lengthenNextPiston()) {
Output("No pistons left to extend. Reversing all pistons");
Output("No pistons left to extend. Resetting all pistons and ending program.");
inPistonRetract = true;
reverseAllPistons();
haltAndCatchFire = true;
}

Save();
Expand All @@ -310,41 +366,63 @@ public void Main()

} else {
distancePiston.MaxLimit = Math.Min(distancePiston.HighestPosition, distancePiston.MaxLimit + DISTANCE_DELTA);
Output("Setting Distance Piston's MaxLimit to:" + distancePiston.MaxLimit);
Output("Extending distance piston to:" + formatToTwo(distancePiston.MaxLimit));
// Make sure the distance piston will extend
distancePiston.Velocity = Math.Abs(distancePiston.Velocity);
}
}
} else {
// Output current status
Output("In swing #" + motorSwing);
Output(distancePiston.CustomName + " at " + distancePiston.CurrentPosition);
foreach (IMyPistonBase piston in drillPistons) {
Output(piston.CustomName + " at " + piston.CurrentPosition);
}
foreach (IMyPistonBase piston in liftPistons) {
Output(piston.CustomName + " at " + piston.CurrentPosition);
}

Output("Storage: " + Storage);
Output("Swing #" + motorSwing + " of " + MAX_ROTOR_SWINGS + " at " + formatToTwo(rotor.TargetVelocityRPM) + " RPM");
}
}

public bool isDrillPiston(IMyPistonBase piston) {
return piston.CustomName.Contains(PREFIX_DRILL_PISTON);
}
Output(distancePiston.CustomName + " at " + formatToTwo(distancePiston.CurrentPosition));
foreach (IMyPistonBase piston in drillPistons) {
Output(piston.CustomName + " at " + formatToTwo(piston.CurrentPosition));
}
foreach (IMyPistonBase piston in liftPistons) {
Output(piston.CustomName + " at " + formatToTwo(piston.CurrentPosition));
}

public bool isLiftPiston(IMyPistonBase piston) {
return piston.CustomName.Contains(PREFIX_LIFT_PISTON);
Output("Storage: " + Storage);
}


public bool rotorStopped() {

Output("Rotor Angle @ " + rotor.Angle);
Output("Range: " + rotor.LowerLimitRad + " -> " + rotor.UpperLimitRad);
if (rotor.Angle <= rotor.LowerLimitRad ||
rotor.Angle >= rotor.UpperLimitRad) {
List<String> RPM_WARNINGS = new List<String>() {
"Rotor velocity (RPM) not set.", // < .5
"", "", "", "", "", // 0.5 .. 2.5
"You're going to bang up your drills.", // 3
"Say goodbye to your warranty.", // 3.5
"That's really not a good idea", // 4
"I see you aim to misbehave.", // 4.5
"At this velocity you should expect\nyour drill to get stuck in the rock.\nOr fall off.", // 5
"Beware the wrath of Klang." }; // 5.5

// Helper function to determine if rotor is at its current target angle (or close enough)
// We calculate a margin within which the rotor is considered to have completed a swing in degrees.
// At higher rotor velocities the rotor will bounce back, which seriously slowed down
// the swing duration time as the rotor would keep trying to precisely hit the target
// at the time of the UpdateFrequency. This margin avoids the need to update faster
// (which would use more CPU cycles)
public bool rotorAtMax() {
// Formula for calculating the margin is: (360 degrees * RPM) / 60 seconds
// (I'm assuming 100 ticks is a second for simplicity's sake)
float margin = 6.0f * Math.Abs(rotor.TargetVelocityRPM);
if (margin > 15.0f) {
Output("Warning: RPM too high!");
Output(RPM_WARNINGS[(int)Math.Round(Math.Abs(rotor.TargetVelocityRPM * 2.0f))]);
Output("Margin set to safety default.");
margin = 20.0f;
}
float angle = radiansToDegrees(rotor.Angle);
Output("Rotor Angle @ " + formatToTwo(angle) + " degrees");
Output("Range: " + formatToTwo(radiansToDegrees(rotor.LowerLimitRad)) + " <-> " + formatToTwo(radiansToDegrees(rotor.UpperLimitRad)) + " degrees");
Output("Margin: " + formatToTwo(margin));
Output("Reversing at: " + formatToTwo(angle) + (rotorDirection < 0 ?
" < " + formatToTwo(radiansToDegrees(rotor.LowerLimitRad) + margin) :
" >= " + formatToTwo(radiansToDegrees(rotor.UpperLimitRad) - margin)));

if ((rotorDirection < 0 && angle <= radiansToDegrees(rotor.LowerLimitRad) + margin) ||
(rotorDirection > 0 && angle >= radiansToDegrees(rotor.UpperLimitRad) - margin)) {
return true;
}
return false;
Expand Down Expand Up @@ -400,7 +478,6 @@ public bool lengthenNextPiston() {
}
}
Output("Drill at lowest point. Returning false.");
haltAndCatchFire = true;
return false;
}

Expand All @@ -425,8 +502,12 @@ private void Output(string text) {
private void ClearLCD() {
screenText = new StringBuilder();
}


private float radiansToDegrees(float radians) {
return radians * (180.0f / (float)Math.PI);
}
private String formatToTwo(float number) {
return String.Format("{0:0.##}", number);
}
/**

Important SDK information:
Expand Down
Loading