Async task system and relative movement complete.

This commit is contained in:
Harrison Deng 2021-05-02 16:02:35 -05:00
parent 2b856ef355
commit 6a791d2741
2 changed files with 131 additions and 88 deletions

View File

@ -14,6 +14,9 @@ local LUA_PREFIX = "?"
local MOVEBY = "moveby"
local MOVETO = "moveto"
local STATUS = "status"
local POSITION = "position"
local HEADING = "heading"
local QUARRY = "quarry"
-- Constant log
local LOG = "LOG"
local REQUEST = "REQ"
@ -22,7 +25,7 @@ local BLOCKED = "blocked"
local ITEM = "item"
local FAILED = "failed"
local running = true
running = true
local modem = peripheral.find("modem")
if (modem == nil) then
@ -71,6 +74,12 @@ local function listenForCommands()
sendDirective(LEADER, MOVETO .. ":" .. coords[1] .. "," .. coords[2] .. "," .. coords[3])
elseif string.find(input, STATUS) == 1 then
sendDirective(LEADER, STATUS)
elseif string.find(input, POSITION) == 1 then
sendDirective(LEADER, POSITION)
elseif string.find(input, HEADING) == 1 then
sendDirective(LEADER, HEADING)
elseif string.find(input, QUARRY) == 1 then
sendDirective(LEADER, input)
end
end
end

View File

@ -10,6 +10,9 @@ local LUA_PREFIX = "?"
local MOVEBY = "moveby"
local MOVETO = "moveto"
local STATUS = "status"
local POSITION = "position"
local HEADING = "heading"
local QUARRY = "quarry"
-- Constant log
local LOG = "LOG"
local REQUEST = "REQ"
@ -20,8 +23,9 @@ local ITEM = "item"
-- INIT SEQUENCE
print("Initiating leader mining turtle.")
local running = true
running = true
local task = nil
local taskArgs = {}
local modem = nil
local heading = nil
local position = nil
@ -181,7 +185,7 @@ local function attemptMoveRight()
if attemptMove(turtle.turnRight) then
local previousHeading = relHeading
relHeading = relRightAxis
relRightAxis = previousHeading
relRightAxis = -previousHeading
if heading ~= nil then
local previousHeading = heading
@ -205,27 +209,30 @@ local function orient(v, forward, right)
attemptMoveRight()
attemptMoveRight()
end
print("Orientation complete.")
end
local function attemptStartTask(f, ...)
sendLog("attempting to start a task.")
if task ~= nil then
sendLog("failed: unable to start task due to another task running.")
return
end
task = f
taskArgs = arg
end
local function attemptStartTask(f, ...) {
if (coroutine.status(task) ~= "dead") then
sendLog("failed: unable to start task due to another task running.")
return false
end
task = coroutine.create(f)
table.remove(args, "n")
task.resume(args)
return true
}
-- actions
local function locatePosition()
sendLog("position: using GPS to determine position.")
local x, y, z = gps.locate()
if x == nil then sendLog("failed: could not locate.") end
position = vector.new(x, y, z)
end
local function determineHeading()
sendLog("heading: calculating heading.")
if position == nil then
sendLog("failed: no current position")
return
@ -262,90 +269,117 @@ local function determineHeading()
end
local function moveBy(delta, forward, right)
sendLog("Attempting to move by (" .. x .. "," .. y .. "," .. z .. ") (x,y,z).")
sendLog("Attempting to move by (" .. delta.x .. "," .. delta.y .. "," .. delta.z .. ") (x,y,z).")
-- x first
if delta.x ~= 0 then orient(vector.new(delta.x, 0, 0):normalize(), forward, right) end
for x=1,math.abs(delta.x) do
attemptMoveForward()
if delta.x ~= 0 then
sendLog("Moving on x axis by: " .. delta.x)
orient(vector.new(delta.x, 0, 0):normalize(), forward, right)
for x=1,math.abs(delta.x) do
attemptMoveForward()
end
end
if delta.z ~= 0 then orient(vector.new(0, 0, delta.z):normalize(), forward, right) end
for z=1,math.abs(delta.z) do
attemptMoveForward()
if delta.z ~= 0 then
sendLog("Moving on z axis by: " .. delta.z)
orient(vector.new(0, 0, delta.z):normalize(), forward, right)
for z=1,math.abs(delta.z) do
attemptMoveForward()
end
end
if delta.y > 0 then
for z=1,delta.y do
sendLog("Moving on y axis by: " .. delta.y)
for y=1,delta.y do
attemptMoveUp()
end
elseif delta.y < 0 then
for z=1,math.abs(delta.y) do
sendLog("Moving on y axis by: " .. delta.y)
for y=1,math.abs(delta.y) do
attemptMoveDown()
end
end
end
while running do
print("Listening for directives...")
local event, side, sendChannel, replyChannel, data, distance = os.pullEvent("modem_message")
print("Recieved data: " .. data)
local token, recipient, sender, type, content = interpretData(data)
if token == TOKEN and recipient == UNIT then
print("Got content: " .. content)
if string.find(content, LUA_PREFIX) == 1 then
local luaScript = string.sub(content, string.len(LUA_PREFIX) + 1)
print("Executing: " .. luaScript)
local f = loadstring(luaScript)
if f ~= nil then
local freturn = f()
local function executeTasks()
while running do
if task ~= nil then
task(unpack(taskArgs))
task = nil
end
sleep(5)
end
end
if freturn ~= nil then
modem.transmit(CHANNEL, CHANNEL, TOKEN .. ":" .. UNIT .. ":" .. "obj" .. ":")
modem.transmit(CHANNEL, CHANNEL, freturn)
end
else
printError("Unable to load lua string.")
end
elseif string.find(content, MOVETO .. ":") == 1 then
local coordsRaw = string.sub(content, string.len(MOVETO .. ":") + 1)
print("Raw coordinate data: " .. coordsRaw)
local coords = captureString(coordsRaw, "([+-]?%d+)")
local x = coords[1]
local y = coords[2]
local z = coords[3]
if heading ~= nil then
attemptStartTask(moveTo, vector.new(x,y,z), heading, rightAxis)
else
attemptStartTask(moveTo, vector.new(x,y,z), relHeading, relRightAxis)
end
elseif string.find(content, MOVEBY .. ":") == 1 then
local valuesRaw = string.sub(content, string.len(MOVEBY .. ":") + 1)
print("Raw coordinate data: " .. valuesRaw)
local deltas = captureString(valuesRaw, "([+-]?%d+)")
local x = deltas[1]
local y = deltas[2]
local z = deltas[3]
if heading ~= nil then
print("Using actual coordinates.")
moveBy(vector.new(x,y,z), heading, rightAxis)
else
print("Using relative coordinates.")
moveBy(vector.new(x,y,z), relHeading, relRightAxis)
end
elseif string.find(content, STATUS .. ":") == 1 then
table = {
"relative_position"={
"coordinates"=relativePos,
"forward"=relHeading,
"right"=relRightAxis
},
"position"={
"coordinates"=position,
"forward"=heading,
"right"=rightAxis
},
"fuel"=turtle.getFuelLevel(),
"task"=taskName
}
sendLog()
end
end
end
local function listen()
while running do
print("Listening for directives...")
local event, side, sendChannel, replyChannel, data, distance = os.pullEvent("modem_message")
print("Recieved data: " .. data)
local token, recipient, sender, type, content = interpretData(data)
if token == TOKEN and recipient == UNIT then
print("Got content: " .. content)
if string.find(content, LUA_PREFIX) == 1 then
local luaScript = string.sub(content, string.len(LUA_PREFIX) + 1)
print("Executing: " .. luaScript)
local f = loadstring(luaScript)
if f ~= nil then
local freturn = f()
if freturn ~= nil then
modem.transmit(CHANNEL, CHANNEL, TOKEN .. ":" .. UNIT .. ":" .. "obj" .. ":")
modem.transmit(CHANNEL, CHANNEL, freturn)
end
else
printError("Unable to load lua string.")
end
elseif string.find(content, MOVETO .. ":") == 1 then
local coordsRaw = string.sub(content, string.len(MOVETO .. ":") + 1)
print("Raw coordinate data: " .. coordsRaw)
local coords = captureString(coordsRaw, "([+-]?%d+)")
local x = coords[1]
local y = coords[2]
local z = coords[3]
if heading ~= nil then
attemptStartTask(moveTo, vector.new(x,y,z), heading, rightAxis)
else
attemptStartTask(moveTo, vector.new(x,y,z), relHeading, relRightAxis)
end
elseif string.find(content, MOVEBY .. ":") == 1 then
local valuesRaw = string.sub(content, string.len(MOVEBY .. ":") + 1)
print("Raw coordinate data: " .. valuesRaw)
local deltas = captureString(valuesRaw, "([+-]?%d+)")
local x = deltas[1]
local y = deltas[2]
local z = deltas[3]
if heading ~= nil then
print("Using actual coordinates.")
attemptStartTask(moveBy, vector.new(x,y,z), heading, rightAxis)
else
print("Using relative coordinates.")
attemptStartTask(moveBy, vector.new(x,y,z), relHeading, relRightAxis)
end
elseif string.find(content, STATUS) == 1 then
status = {
relative_position = {
coordinates=relativePos,
forward=relHeading,
right=relRightAxis
},
position={
coordinates=position,
forward=heading,
right=rightAxis
},
fuel=turtle.getFuelLevel(),
status=coroutine.status(task)
}
sendLog("status:" .. textutils.serialise(status))
elseif string.find(content, POSITION) == 1 then
locatePosition()
elseif string.find(content, HEADING) == 1 then
determineHeading()
elseif string.find(content, QUARRY) == 1 then
end
end
end
end
parallel.waitForAll(listen, executeTasks)