Few corrections to netNav and align starNav to recent changes in netNav

This commit is contained in:
Matt Blunt 2016-02-08 20:24:28 +00:00
parent 26f3750b00
commit 7808328601
2 changed files with 107 additions and 90 deletions

8
netNav
View File

@ -284,8 +284,8 @@ end
function setMap(mapName, mapTimeout) function setMap(mapName, mapTimeout)
if type(mapName) ~= "string" then if type(mapName) ~= "string" then
error("mapName must be string") error("mapName must be string")
if type(mapTimeout) ~= "number" or mapTimeout < 0 then
end end
if type(mapTimeout) ~= "number" or mapTimeout < 0 then
error("timeout must be positive number") error("timeout must be positive number")
end end
serverMap = remoteMap.new(mapName, mapTimeout) serverMap = remoteMap.new(mapName, mapTimeout)
@ -294,3 +294,9 @@ end
function getMap() function getMap()
return serverMap return serverMap
end end
function getPosition()
if position then
return position:value()
end
end

169
starNav
View File

@ -28,7 +28,7 @@ local MAIN_COORD_DISTANCE = 1024
local sessionMidPoint local sessionMidPoint
local sessionMaxDistance local sessionMaxDistance
local sessionMap local sessionMap
local mainMap = tinyMap.new("starNavMaps") local mainMap
local function sup_norm(a, b) local function sup_norm(a, b)
return math.max(math.abs(a.x - b.x), math.abs(a.y - b.y), math.abs(a.z - b.z)) return math.max(math.abs(a.x - b.x), math.abs(a.y - b.y), math.abs(a.z - b.z))
@ -50,106 +50,109 @@ local function distanceFunc(a, b)
return aStar.distance(a, b) -- we are assuming both coords are clear return aStar.distance(a, b) -- we are assuming both coords are clear
end end
local function getHeading() local directions = {
local i = 0 [vector.new(0, 0, 1)] = 0,
while turtle.detect() do [vector.new(-1, 0, 0)] = 1,
if i == 4 then [vector.new(0, 0, -1)] = 2,
if turtle.up() then [vector.new(1, 0, 0)] = 3,
i = 0 [vector.new(0, 1, 0)] = 4,
else [vector.new(0, -1, 0)] = 5,
error("help I'm trapped in a ridiculous place") }
local function deltaToDirection(delta)
for vec, dir in pairs(directions) do
if aStar.vectorEquals(delta, vec) then
return dir
end
end
end
local function tryMove()
for i = 1, 4 do
if turtle.forward() then
return true
end end
else
turtle.turnRight() turtle.turnRight()
i = i + 1 end
return false
end
local function findPosition()
local move = turtle.up
while not tryMove() do
if not move() then
if move == turtle.up then
move = turtle.down
move()
else
error("trapped in a ridiculous place")
end end
end end
end
local p1 = {gps.locate()} local p1 = {gps.locate()}
if #p1 == 3 then if #p1 == 3 then
p1 = vector.new(unpack(p1)) p1 = vector.new(unpack(p1))
else else
error("no gps signal - phase 1") error("no gps signal - phase 1")
end end
i = 0
while not turtle.forward() do if not turtle.back() then
if i > 5 then error("couldn't move to determine direction") end error("couldn't move to determine direction")
i = i + 1
sleep(1)
end end
local p2 = {gps.locate()} local p2 = {gps.locate()}
turtle.back()
if #p2 == 3 then if #p2 == 3 then
p2 = vector.new(unpack(p2)) p2 = vector.new(unpack(p2))
else else
error("no gps signal - phase 2") error("no gps signal - phase 2")
end end
local dir = p2 - p1
if dir.x == 1 then local direction = deltaToDirection(p1 - p2)
return 3 if direction and direction < 4 then
elseif dir.x == -1 then return location.new(p2.x, p2.y, p2.z, direction)
return 1
elseif dir.z == 1 then
return 0
elseif dir.z == -1 then
return 2
else else
error("could not determine direction - phase 3") return false
end end
end end
local function detect(currPos, adjPos) local function detect(currPos, adjPos)
local dir = adjPos - currPos local direction = deltaToDirection(adjPos - currPos)
if dir.y == 1 then if direction then
position:setHeading(direction)
if direction == 4 then
return turtle.detectUp() return turtle.detectUp()
elseif dir.y == -1 then elseif direction == 5 then
return turtle.detectDown() return turtle.detectDown()
elseif dir.x == 1 then
position:setHeading(3)
return turtle.detect()
elseif dir.x == -1 then
position:setHeading(1)
return turtle.detect()
elseif dir.z == 1 then
position:setHeading(0)
return turtle.detect()
elseif dir.z == -1 then
position:setHeading(2)
return turtle.detect()
else else
return false return turtle.detect()
end end
end
return false
end end
local function inspect(currPos, adjPos) local function inspect(currPos, adjPos)
local dir = adjPos - currPos local direction = deltaToDirection(adjPos - currPos)
if dir.y == 1 then if direction then
position:setHeading(direction)
if direction == 4 then
return turtle.inspectUp() return turtle.inspectUp()
elseif dir.y == -1 then elseif direction == 5 then
return turtle.inspectDown() return turtle.inspectDown()
elseif dir.x == 1 then
position:setHeading(3)
return turtle.inspect()
elseif dir.x == -1 then
position:setHeading(1)
return turtle.inspect()
elseif dir.z == 1 then
position:setHeading(0)
return turtle.inspect()
elseif dir.z == -1 then
position:setHeading(2)
return turtle.inspect()
else else
return false return turtle.inspect()
end end
end
return false
end end
local function updateCoord(coord, isBlocked) local function updateCoord(coord, isBlocked)
if isBlocked then if isBlocked then
sessionMap:set(pos, SESSION_COORD_BLOCKED) sessionMap:set(coord, SESSION_COORD_BLOCKED)
mainMap:set(pos, MAIN_COORD_BLOCKED) mainMap:set(coord, MAIN_COORD_BLOCKED)
else else
sessionMap:set(pos, SESSION_COORD_CLEAR) sessionMap:set(coord, SESSION_COORD_CLEAR)
mainMap:set(pos, MAIN_COORD_CLEAR) mainMap:set(coord, MAIN_COORD_CLEAR)
end end
end end
@ -205,31 +208,30 @@ local function scan(currPos)
end end
local function move(currPos, adjPos) local function move(currPos, adjPos)
if not detect(position, adjPos) then local direction = deltaToDirection(adjPos - currPos)
local dir = adjPos - currPos if direction then
if dir.y == 1 then position:setHeading(direction)
if direction == 4 then
return position:up() return position:up()
elseif dir.y == -1 then elseif direction == 5 then
return position:down() return position:down()
else else
return position:forward() return position:forward()
end end
else
return false
end end
return false
end end
function goto(x, y, z, maxDistance) function goto(x, y, z, maxDistance)
if not mainMap then
error("mainMap has not been specified")
end
if turtle.getFuelLevel() == 0 then if turtle.getFuelLevel() == 0 then
return false, "ran out of fuel" return false, "ran out of fuel"
end end
if not position then if not position then
local heading = getHeading() position = findPosition()
local currPos = {gps.locate()} if not position then
if #currPos == 3 then
local x, y, z = unpack(currPos)
position = location.new(x, y, z, heading)
else
return false, "couldn't determine location" return false, "couldn't determine location"
end end
end end
@ -244,7 +246,6 @@ function goto(x, y, z, maxDistance)
if not path then if not path then
return false, "no known path to goal" return false, "no known path to goal"
end end
while not aStar.vectorEquals(position, goal) do while not aStar.vectorEquals(position, goal) do
local movePos = table.remove(path) local movePos = table.remove(path)
while not move(position, movePos) do while not move(position, movePos) do
@ -254,11 +255,9 @@ function goto(x, y, z, maxDistance)
sleep(math.random(0, 3)) sleep(math.random(0, 3))
local blockPresent2, blockData2 = inspect(position, movePos) local blockPresent2, blockData2 = inspect(position, movePos)
if blockPresent2 and (blockData2.name == "ComputerCraft:CC-TurtleAdvanced" or blockData2.name == "ComputerCraft:CC-Turtle") then -- the turtle is still there if blockPresent2 and (blockData2.name == "ComputerCraft:CC-TurtleAdvanced" or blockData2.name == "ComputerCraft:CC-Turtle") then -- the turtle is still there
sessionMap:set(movePos, SESSION_COORD_BLOCKED)
recalculate, isTurtle = true, true recalculate, isTurtle = true, true
end end
elseif blockPresent then elseif blockPresent then
scan(position) -- update map info
recalculate = true recalculate = true
elseif turtle.getFuelLevel() == 0 then elseif turtle.getFuelLevel() == 0 then
return false, "ran out of fuel" return false, "ran out of fuel"
@ -266,15 +265,16 @@ function goto(x, y, z, maxDistance)
sleep(1) sleep(1)
end end
if recalculate then if recalculate then
scan(position)
if sessionMap:get(goal) == SESSION_COORD_BLOCKED then return false, "goal is blocked" end if sessionMap:get(goal) == SESSION_COORD_BLOCKED then return false, "goal is blocked" end
path = aStar.compute(distanceFunc, position, goal) path = aStar.compute(distanceFunc, position, goal)
if not path then if not path then
return false, "no known path to goal" return false, "no known path to goal"
end end
movePos = table.remove(path)
if isTurtle then if isTurtle then
sessionMap:set(movePos, nil) sessionMap:set(movePos, nil)
end end
movePos = table.remove(path)
end end
end end
if mainMap:get(movePos) then if mainMap:get(movePos) then
@ -284,6 +284,17 @@ function goto(x, y, z, maxDistance)
return true return true
end end
function setMap(mapName)
if type(mapName) ~= "string" then
error("mapName must be string")
end
mainMap = tinyMap.new(mapName)
end
function getMap()
return mainMap
end
function getPosition() function getPosition()
if position then if position then
return position:value() return position:value()