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) local function listen()
if f ~= nil then while running do
local freturn = f() print("Listening for directives...")
local event, side, sendChannel, replyChannel, data, distance = os.pullEvent("modem_message")
if freturn ~= nil then print("Recieved data: " .. data)
modem.transmit(CHANNEL, CHANNEL, TOKEN .. ":" .. UNIT .. ":" .. "obj" .. ":") local token, recipient, sender, type, content = interpretData(data)
modem.transmit(CHANNEL, CHANNEL, freturn) if token == TOKEN and recipient == UNIT then
end print("Got content: " .. content)
else if string.find(content, LUA_PREFIX) == 1 then
printError("Unable to load lua string.") local luaScript = string.sub(content, string.len(LUA_PREFIX) + 1)
end print("Executing: " .. luaScript)
elseif string.find(content, MOVETO .. ":") == 1 then local f = loadstring(luaScript)
local coordsRaw = string.sub(content, string.len(MOVETO .. ":") + 1) if f ~= nil then
print("Raw coordinate data: " .. coordsRaw) local freturn = f()
local coords = captureString(coordsRaw, "([+-]?%d+)")
local x = coords[1] if freturn ~= nil then
local y = coords[2] modem.transmit(CHANNEL, CHANNEL, TOKEN .. ":" .. UNIT .. ":" .. "obj" .. ":")
local z = coords[3] modem.transmit(CHANNEL, CHANNEL, freturn)
if heading ~= nil then end
attemptStartTask(moveTo, vector.new(x,y,z), heading, rightAxis) else
else printError("Unable to load lua string.")
attemptStartTask(moveTo, vector.new(x,y,z), relHeading, relRightAxis) end
end elseif string.find(content, MOVETO .. ":") == 1 then
elseif string.find(content, MOVEBY .. ":") == 1 then local coordsRaw = string.sub(content, string.len(MOVETO .. ":") + 1)
local valuesRaw = string.sub(content, string.len(MOVEBY .. ":") + 1) print("Raw coordinate data: " .. coordsRaw)
print("Raw coordinate data: " .. valuesRaw) local coords = captureString(coordsRaw, "([+-]?%d+)")
local deltas = captureString(valuesRaw, "([+-]?%d+)") local x = coords[1]
local x = deltas[1] local y = coords[2]
local y = deltas[2] local z = coords[3]
local z = deltas[3] if heading ~= nil then
if heading ~= nil then attemptStartTask(moveTo, vector.new(x,y,z), heading, rightAxis)
print("Using actual coordinates.") else
moveBy(vector.new(x,y,z), heading, rightAxis) attemptStartTask(moveTo, vector.new(x,y,z), relHeading, relRightAxis)
else end
print("Using relative coordinates.") elseif string.find(content, MOVEBY .. ":") == 1 then
moveBy(vector.new(x,y,z), relHeading, relRightAxis) local valuesRaw = string.sub(content, string.len(MOVEBY .. ":") + 1)
end print("Raw coordinate data: " .. valuesRaw)
elseif string.find(content, STATUS .. ":") == 1 then local deltas = captureString(valuesRaw, "([+-]?%d+)")
table = { local x = deltas[1]
"relative_position"={ local y = deltas[2]
"coordinates"=relativePos, local z = deltas[3]
"forward"=relHeading, if heading ~= nil then
"right"=relRightAxis print("Using actual coordinates.")
}, attemptStartTask(moveBy, vector.new(x,y,z), heading, rightAxis)
"position"={ else
"coordinates"=position, print("Using relative coordinates.")
"forward"=heading, attemptStartTask(moveBy, vector.new(x,y,z), relHeading, relRightAxis)
"right"=rightAxis end
}, elseif string.find(content, STATUS) == 1 then
"fuel"=turtle.getFuelLevel(), status = {
"task"=taskName relative_position = {
} coordinates=relativePos,
sendLog() forward=relHeading,
end right=relRightAxis
end },
end 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)