Skip to content

Instantly share code, notes, and snippets.

@object-Object
Last active November 4, 2021 14:38
Show Gist options
  • Save object-Object/54a5d3fe1f94009419819b755785a325 to your computer and use it in GitHub Desktop.
Save object-Object/54a5d3fe1f94009419819b755785a325 to your computer and use it in GitHub Desktop.
Program to run a BuildCraft-style quarry with the Create mod for Minecraft.
--[[
top: y gearshift (on = -y, off = +y)
bottom: z gearshift (on = down, off = up)
front:
red: x gearshift (on = -x, off = +x)
blue: z up endstop
yellow: z down endstop
purple: y endstop
green: x endstop
back: x gantry (on = move) - inverted
left: y gantry (on = move) - inverted
right: z clutch (on = move) - inverted
]]
-- delays calculated for 96 RPM gantry speed
WAIT_DELAY = 1 -- delay in loops waiting for endstops to trigger
X_STEP_DELAY = 0.29
PRE_Y_STEP_DELAY = 0.1
Y_STEP_DELAY = 0.29
X_MIN, Y_MIN = 1, 1 -- leave this as 1, 1
X_MAX, Y_MAX = 31, 31 -- lengths of X and Y gantries
HEAD_X, HEAD_Y = 3, 3 -- size of the drill head
x, y = X_MIN, Y_MIN
function clamp(n, min, max)
return math.min(math.max(n, min), max)
end
function getXEndstop()
return rs.testBundledInput("front", colors.green)
end
function getYEndstop()
return rs.testBundledInput("front", colors.purple)
end
function getZDownEndstop()
return rs.testBundledInput("front", colors.yellow)
end
function getZUpEndstop()
return rs.testBundledInput("front", colors.blue)
end
function setXDirPositive()
rs.setBundledOutput("front", 0) -- this is fine because everything else on front is a receiver
end
function setXDirNegative()
rs.setBundledOutput("front", colors.red) -- this is fine because everything else on front is a receiver
end
function setYDirPositive()
rs.setOutput("top", false)
end
function setYDirNegative()
rs.setOutput("top", true)
end
function setZDirUp()
rs.setOutput("bottom", false)
end
function setZDirDown()
rs.setOutput("bottom", true)
end
function moveX()
rs.setOutput("back", true)
end
function stopX()
rs.setOutput("back", false)
end
function moveY()
rs.setOutput("left", true)
end
function stopY()
rs.setOutput("left", false)
end
function moveZ()
rs.setOutput("right", true)
end
function stopZ()
rs.setOutput("right", false)
end
function stepX(steps, doLog) -- blocks
steps = clamp(steps + x, X_MIN, X_MAX) - x
if steps == 0 then
return false
elseif steps < 0 then
setXDirNegative()
else
setXDirPositive()
end
moveX()
sleep(X_STEP_DELAY * math.abs(steps))
stopX()
setXDirPositive()
x = x + steps
return true
end
function stepY(steps) -- blocks
steps = clamp(steps + y, Y_MIN, Y_MAX) - y
if steps == 0 then
return false
elseif steps < 0 then
setYDirNegative()
else
setYDirPositive()
end
moveY()
sleep(PRE_Y_STEP_DELAY + Y_STEP_DELAY * math.abs(steps))
stopY()
setYDirPositive()
y = y + steps
return true
end
function homeX()
setXDirNegative()
moveX()
while not getXEndstop() do sleep(WAIT_DELAY) end
stopX()
setXDirPositive()
x = X_MIN
end
function homeY()
setYDirNegative()
moveY()
while not getYEndstop() do sleep(WAIT_DELAY) end
stopY()
setYDirPositive()
y = Y_MIN
end
function homeZ()
setZDirUp()
moveZ()
while not getZUpEndstop() do sleep(WAIT_DELAY) end
stopZ()
end
function savePosition(xPos, yPos)
local f = fs.open("quarry_pos.txt", "w")
f.writeLine(xPos..","..yPos)
f.close()
end
function loadPosition()
if not fs.exists("quarry_pos.txt", "r") then
return false, false
end
local f = fs.open("quarry_pos.txt", "r")
local data = f.readLine()
f.close()
local xPos, yPos = data:match("(%d+),(%d+)")
return tonumber(xPos), tonumber(yPos)
end
function findNextPosition()
local nextY = y + HEAD_Y
if nextY > Y_MAX then
return x + HEAD_X, 1
end
return x, nextY
end
function home()
stopX()
stopY()
stopZ()
setXDirPositive()
setYDirPositive()
setZDirUp()
x, y = X_MAX, Y_MAX
print("Homing Z.")
homeZ()
print("Homing Y.")
homeY()
print("Homing X.")
homeX()
print("Done homing.")
end
function drill()
print("Drilling column ("..math.ceil(x / HEAD_X)..", "..math.ceil(y / HEAD_Y)..") at position ("..x..", "..y..").")
setZDirDown()
moveZ()
savePosition(x, y)
sleep(5)
while not getZDownEndstop() do sleep(WAIT_DELAY) end
savePosition(findNextPosition())
homeZ()
end
home()
prevX, prevY = loadPosition()
if prevX and prevY then
if prevX > X_MAX or prevY > Y_MAX then
error("Quarry has finished, or an invalid position was saved.")
end
stepX(prevX - 1)
stepY(prevY - 1)
end
repeat
repeat
drill()
until not stepY(HEAD_Y)
homeY()
until not stepX(HEAD_X)
print("Done.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment