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

View File

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