Further work to align starNav and netNav functionality
This commit is contained in:
parent
a373369ba0
commit
0336cdaa2a
@ -20,9 +20,9 @@ if minZ > maxZ then minZ, maxZ = maxZ, minZ end
|
|||||||
|
|
||||||
-- LOAD NETNAV API
|
-- LOAD NETNAV API
|
||||||
if not netNav then
|
if not netNav then
|
||||||
if not os.loadAPI("netNav") then
|
if not os.loadAPI("netNav") then
|
||||||
error("could not load starNav API")
|
error("could not load netNav API")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- OPEN REDNET
|
-- OPEN REDNET
|
||||||
@ -42,9 +42,7 @@ if type(mapName) ~= "string" then
|
|||||||
printError("mapName must be string")
|
printError("mapName must be string")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if not netNav.getMap() then
|
netNav.setMap(mapName, 15)
|
||||||
netNav.setMap(mapName, 15)
|
|
||||||
end
|
|
||||||
|
|
||||||
local exit = false
|
local exit = false
|
||||||
local returning = false
|
local returning = false
|
||||||
|
|||||||
@ -1,16 +1,13 @@
|
|||||||
if not remoteMap then
|
local apis = {
|
||||||
if not os.loadAPI("remoteMap") then
|
"remoteMap",
|
||||||
error("could not load remoteMap API")
|
"aStar",
|
||||||
end
|
"location",
|
||||||
end
|
}
|
||||||
if not aStar then
|
for _ api in ipairs(apis) do
|
||||||
if not os.loadAPI("aStar") then
|
if not _G[api] then
|
||||||
error("could not load aStar API")
|
if not os.loadAPI(api) then
|
||||||
end
|
error("could not load API: "..api)
|
||||||
end
|
end
|
||||||
if not location then
|
|
||||||
if not os.loadAPI("location") then
|
|
||||||
error("could not load location API")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -20,9 +17,10 @@ local SESSION_MAX_DISTANCE_DEFAULT = 32
|
|||||||
|
|
||||||
local SESSION_COORD_CLEAR = 1
|
local SESSION_COORD_CLEAR = 1
|
||||||
local SESSION_COORD_BLOCKED = 2
|
local SESSION_COORD_BLOCKED = 2
|
||||||
|
local SESSION_COORD_DISTANCE = math.huge
|
||||||
local UPDATE_COORD_CLEAR = -1
|
local UPDATE_COORD_CLEAR = -1
|
||||||
local UPDATE_COORD_BLOCKED = 1
|
local UPDATE_COORD_BLOCKED = 1
|
||||||
|
local UPDATE_COORD_DISTANCE = 2
|
||||||
|
|
||||||
local sessionMidPoint
|
local sessionMidPoint
|
||||||
local sessionMaxDistance
|
local sessionMaxDistance
|
||||||
@ -33,18 +31,18 @@ local serverMap
|
|||||||
local function distanceFunc(a, b)
|
local function distanceFunc(a, b)
|
||||||
local sessionMapA, sessionMapB = sessionMap:get(a), sessionMap:get(b)
|
local sessionMapA, sessionMapB = sessionMap:get(a), sessionMap:get(b)
|
||||||
if aStar.distance(a, sessionMidPoint) > sessionMaxDistance then
|
if aStar.distance(a, sessionMidPoint) > sessionMaxDistance then
|
||||||
return math.huge -- first coord is outside the search region
|
return SESSION_COORD_DISTANCE -- first coord is outside the search region
|
||||||
elseif aStar.distance(b, sessionMidPoint) > sessionMaxDistance then
|
elseif aStar.distance(b, sessionMidPoint) > sessionMaxDistance then
|
||||||
return math.huge -- second coord is outside the search region
|
return SESSION_COORD_DISTANCE -- second coord is outside the search region
|
||||||
elseif sessionMapA == SESSION_COORD_BLOCKED or sessionMapB == SESSION_COORD_BLOCKED then
|
elseif sessionMapA == SESSION_COORD_BLOCKED or sessionMapB == SESSION_COORD_BLOCKED then
|
||||||
return math.huge -- we have found one of these coords to be blocked during this session
|
return SESSION_COORD_DISTANCE -- we have found one of these coords to be blocked during this session
|
||||||
elseif sessionMapA == SESSION_COORD_CLEAR and sessionMapB == SESSION_COORD_CLEAR then
|
elseif sessionMapA == SESSION_COORD_CLEAR and sessionMapB == SESSION_COORD_CLEAR then
|
||||||
return aStar.distance(a, b) -- we have found both of these coords to be clear during this session
|
return aStar.distance(a, b) -- we have found both of these coords to be clear during this session
|
||||||
else
|
else
|
||||||
local serverMapA, serverMapB = serverMap:get(a), serverMap:get(b)
|
local serverMapA, serverMapB = serverMap:get(a), serverMap:get(b)
|
||||||
if serverMapA or serverMapB then
|
if serverMapA or serverMapB then
|
||||||
serverMapA = serverMapA and 2^(serverMapA + 1) or 1
|
serverMapA = serverMapA and UPDATE_COORD_DISTANCE^(serverMapA + 1) or 1
|
||||||
serverMapB = serverMapB and 2^(serverMapB + 1) or 1
|
serverMapB = serverMapB and UPDATE_COORD_DISTANCE^(serverMapB + 1) or 1
|
||||||
return math.max(serverMapA, serverMapB) -- the remote server map is indicating one of these coords may be blocked
|
return math.max(serverMapA, serverMapB) -- the remote server map is indicating one of these coords may be blocked
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -254,16 +252,16 @@ local function _goto(x, y, z, maxDistance)
|
|||||||
local goal = vector.new(tonumber(x), tonumber(y), tonumber(z))
|
local goal = vector.new(tonumber(x), tonumber(y), tonumber(z))
|
||||||
|
|
||||||
serverMap:check() -- remove timed out data we have received from server
|
serverMap:check() -- remove timed out data we have received from server
|
||||||
sessionMap = aStar.newMap() -- reset the sessionMap
|
|
||||||
|
|
||||||
|
sessionMap = aStar.newMap() -- reset the sessionMap
|
||||||
sessionMidPoint = vector.new(math.floor((goal.x + position.x)/2), math.floor((goal.y + position.y)/2), math.floor((goal.z + position.z)/2))
|
sessionMidPoint = vector.new(math.floor((goal.x + position.x)/2), math.floor((goal.y + position.y)/2), math.floor((goal.z + position.z)/2))
|
||||||
sessionMaxDistance = (type(maxDistance) == "number" and maxDistance) or math.max(2*aStar.distance(sessionMidPoint, goal), SESSION_MAX_DISTANCE_DEFAULT)
|
sessionMaxDistance = (type(maxDistance) == "number" and maxDistance) or math.max(2*aStar.distance(sessionMidPoint, goal), SESSION_MAX_DISTANCE_DEFAULT)
|
||||||
|
|
||||||
local path = aStar.compute(distanceFunc, position, goal)
|
local 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
|
||||||
|
|
||||||
while not (exit or aStar.vectorEquals(position, goal)) do
|
while not (exit or 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
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
local function printUsage()
|
local function printUsage()
|
||||||
print("Usage:")
|
print("Usage:")
|
||||||
print(fs.getName(shell.getRunningProgram()).." <remoteMap_name> <x_pos> <y_pos> <z_pos>")
|
print(fs.getName(shell.getRunningProgram()).." <map_name> <x_pos> <y_pos> <z_pos> <(optional)max_distance>")
|
||||||
print("<remoteMap_name> The name of the remoteMap to connect to and use.")
|
print("<map_name> The name of the map to use.")
|
||||||
print("<x_pos> <y_pos> <z_pos> The GPS coordinates you want to go to.")
|
print("<x_pos> <y_pos> <z_pos> The GPS coordinates you want to go to.")
|
||||||
|
print("<(optional)max_distance> The farthest distance allowed to travel from start position.")
|
||||||
end
|
end
|
||||||
|
|
||||||
if not netNav then
|
if not netNav then
|
||||||
@ -40,10 +41,22 @@ for i = 2, 4 do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local maxDistance
|
||||||
|
if tArgs[5] ~= nil then
|
||||||
|
if tonumber(tArgs[5]) then
|
||||||
|
print("setting max_distance to: ", tArgs[5])
|
||||||
|
maxDistance = tonumber(tArgs[5])
|
||||||
|
else
|
||||||
|
printError("max_distance: number expected")
|
||||||
|
printUsage()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
print("going to coordinates = ", tArgs[2], ",", tArgs[3], ",", tArgs[4])
|
print("going to coordinates = ", tArgs[2], ",", tArgs[3], ",", tArgs[4])
|
||||||
local ok, err = netNav.goto(tArgs[2], tArgs[3], tArgs[4])
|
local ok, err = netNav.goto(tArgs[2], tArgs[3], tArgs[4], maxDistance)
|
||||||
if not ok then
|
if not ok then
|
||||||
printError("navigation failed: ", err)
|
printError("navigation failed: ", err)
|
||||||
else
|
else
|
||||||
print("succesfully navigated to coordinates")
|
print("succesfully navigated to coordinates")
|
||||||
end
|
end
|
||||||
|
|||||||
72
starNav/explore.lua
Normal file
72
starNav/explore.lua
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
local tArgs = {...}
|
||||||
|
|
||||||
|
-- FIND AREA BOUNDARIES
|
||||||
|
local minX, minY, minZ = unpack(tArgs, 2, 4)
|
||||||
|
minX, minY, minZ = tonumber(minX), tonumber(minY), tonumber(minZ)
|
||||||
|
local maxX, maxY, maxZ = unpack(tArgs, 5, 7)
|
||||||
|
maxX, maxY, maxZ = tonumber(maxX), tonumber(maxY), tonumber(maxZ)
|
||||||
|
local function isInteger(var)
|
||||||
|
return type(var) == "number" and math.floor(var) == var
|
||||||
|
end
|
||||||
|
if not isInteger(minX) then printError("minX must be integer") return end
|
||||||
|
if not isInteger(minY) then printError("minX must be integer") return end
|
||||||
|
if not isInteger(minZ) then printError("minX must be integer") return end
|
||||||
|
if not isInteger(maxX) then printError("maxX must be integer") return end
|
||||||
|
if not isInteger(maxY) then printError("maxY must be integer") return end
|
||||||
|
if not isInteger(maxZ) then printError("maxZ must be integer") return end
|
||||||
|
if minX > maxX then minX, maxX = maxX, minX end
|
||||||
|
if minY > maxY then minY, maxY = maxY, minY end
|
||||||
|
if minZ > maxZ then minZ, maxZ = maxZ, minZ end
|
||||||
|
|
||||||
|
-- LOAD STARNAV API
|
||||||
|
if not starNav then
|
||||||
|
if not os.loadAPI("starNav") then
|
||||||
|
error("could not load starNav API")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- OPEN REDNET
|
||||||
|
for _, side in ipairs({"left", "right"}) do
|
||||||
|
if peripheral.getType(side) == "modem" then
|
||||||
|
rednet.open(side)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not rednet.isOpen() then
|
||||||
|
printError("Could not open rednet")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- SET STARNAV MAP
|
||||||
|
local mapName = tArgs[1]
|
||||||
|
if type(mapName) ~= "string" then
|
||||||
|
printError("mapName must be string")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
starNav.setMap(mapName)
|
||||||
|
|
||||||
|
local exit = false
|
||||||
|
local returning = false
|
||||||
|
|
||||||
|
local function main()
|
||||||
|
local startX, startY, startZ = gps.locate(1)
|
||||||
|
while turtle.getFuelLevel() > 0 and not exit do
|
||||||
|
local x = math.random(minX, maxX)
|
||||||
|
local y = math.random(minY, maxY)
|
||||||
|
local z = math.random(minZ, maxZ)
|
||||||
|
starNav.goto(x, y, z)
|
||||||
|
end
|
||||||
|
returning = true
|
||||||
|
starNav.goto(startX, startY, startZ)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function control()
|
||||||
|
while true do
|
||||||
|
local senderID, message = rednet.receive("explore:return_to_base")
|
||||||
|
if not exit and not returning then
|
||||||
|
starNav.stop()
|
||||||
|
exit = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
parallel.waitForAny(main, control)
|
||||||
@ -1,16 +1,13 @@
|
|||||||
if not tinyMap then
|
local apis = {
|
||||||
if not os.loadAPI("tinyMap") then
|
"tinyMap",
|
||||||
error("could not load tinyMap API")
|
"aStar",
|
||||||
end
|
"location",
|
||||||
end
|
}
|
||||||
if not aStar then
|
for _ api in ipairs(apis) do
|
||||||
if not os.loadAPI("aStar") then
|
if not _G[api] then
|
||||||
error("could not load aStar API")
|
if not os.loadAPI(api) then
|
||||||
end
|
error("could not load API: "..api)
|
||||||
end
|
end
|
||||||
if not location then
|
|
||||||
if not os.loadAPI("location") then
|
|
||||||
error("could not load location API")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -38,13 +35,13 @@ local function distanceFunc(a, b)
|
|||||||
elseif aStar.distance(b, sessionMidPoint) > sessionMaxDistance then
|
elseif aStar.distance(b, sessionMidPoint) > sessionMaxDistance then
|
||||||
return SESSION_COORD_DISTANCE -- second coord is outside the search region
|
return SESSION_COORD_DISTANCE -- second coord is outside the search region
|
||||||
elseif sessionMapA == SESSION_COORD_BLOCKED or sessionMapB == SESSION_COORD_BLOCKED then
|
elseif sessionMapA == SESSION_COORD_BLOCKED or sessionMapB == SESSION_COORD_BLOCKED then
|
||||||
return SESSION_COORD_DISTANCE -- one of the coords has been found to be blocked this during this session
|
return SESSION_COORD_DISTANCE -- we have found one of these coords to be blocked during this session
|
||||||
elseif sessionMapA == SESSION_COORD_CLEAR and sessionMapA == SESSION_COORD_CLEAR then
|
elseif sessionMapA == SESSION_COORD_CLEAR and sessionMapB == SESSION_COORD_CLEAR then
|
||||||
return aStar.distance(a, b) -- both coords has been found to be clear this during this session
|
return aStar.distance(a, b) -- we have found both of these coords to be clear during this session
|
||||||
elseif mainMap:get(a) or mainMap:get(b) then
|
elseif mainMap:get(a) or mainMap:get(b) then
|
||||||
return MAIN_COORD_DISTANCE
|
return MAIN_COORD_DISTANCE
|
||||||
end
|
end
|
||||||
return aStar.distance(a, b) -- we are assuming both coords are clear
|
return aStar.distance(a, b) -- we dont know anything useful so just calc the distance
|
||||||
end
|
end
|
||||||
|
|
||||||
local directions = {
|
local directions = {
|
||||||
@ -230,7 +227,9 @@ local function move(currPos, adjPos)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local exit = false
|
||||||
local function _goto(x, y, z, maxDistance)
|
local function _goto(x, y, z, maxDistance)
|
||||||
|
exit = false
|
||||||
if not mainMap then
|
if not mainMap then
|
||||||
error("mainMap has not been specified")
|
error("mainMap has not been specified")
|
||||||
end
|
end
|
||||||
@ -246,7 +245,7 @@ local function _goto(x, y, z, maxDistance)
|
|||||||
|
|
||||||
local goal = vector.new(tonumber(x), tonumber(y), tonumber(z))
|
local goal = vector.new(tonumber(x), tonumber(y), tonumber(z))
|
||||||
|
|
||||||
sessionMap = aStar.newMap()
|
sessionMap = aStar.newMap() -- reset the sessionMap
|
||||||
sessionMidPoint = vector.new(math.floor((goal.x + position.x)/2), math.floor((goal.y + position.y)/2), math.floor((goal.z + position.z)/2))
|
sessionMidPoint = vector.new(math.floor((goal.x + position.x)/2), math.floor((goal.y + position.y)/2), math.floor((goal.z + position.z)/2))
|
||||||
sessionMaxDistance = (type(maxDistance) == "number" and maxDistance) or math.max(2*aStar.distance(sessionMidPoint, goal), SESSION_MAX_DISTANCE_DEFAULT)
|
sessionMaxDistance = (type(maxDistance) == "number" and maxDistance) or math.max(2*aStar.distance(sessionMidPoint, goal), SESSION_MAX_DISTANCE_DEFAULT)
|
||||||
|
|
||||||
@ -255,7 +254,7 @@ local function _goto(x, y, z, maxDistance)
|
|||||||
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 (exit or 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
|
||||||
local blockPresent, blockData = inspect(position, movePos)
|
local blockPresent, blockData = inspect(position, movePos)
|
||||||
@ -293,7 +292,7 @@ local function _goto(x, y, z, maxDistance)
|
|||||||
|
|
||||||
mainMap:saveAll()
|
mainMap:saveAll()
|
||||||
|
|
||||||
return true
|
return aStar.vectorEquals(position, goal)
|
||||||
end
|
end
|
||||||
|
|
||||||
local isRunning = false
|
local isRunning = false
|
||||||
@ -311,6 +310,11 @@ function goto(...)
|
|||||||
return unpack(passback, 2)
|
return unpack(passback, 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function stop()
|
||||||
|
if isRunning then
|
||||||
|
exit = true
|
||||||
|
end
|
||||||
|
end
|
||||||
function setMap(mapName)
|
function setMap(mapName)
|
||||||
if type(mapName) ~= "string" then
|
if type(mapName) ~= "string" then
|
||||||
error("mapName must be string")
|
error("mapName must be string")
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
local function printUsage()
|
local function printUsage()
|
||||||
print("Usage:")
|
print("Usage:")
|
||||||
print(fs.getName(shell.getRunningProgram()).." <map_name> <x_pos> <y_pos> <z_pos> <(optional)max_distance>")
|
print(fs.getName(shell.getRunningProgram()).." <map_name> <x_pos> <y_pos> <z_pos> <(optional)max_distance>")
|
||||||
print("<map_name> The name of the remoteMap to connect to and use.")
|
print("<map_name> The name of the map to use.")
|
||||||
print("<x_pos> <y_pos> <z_pos> The GPS coordinates you want to go to.")
|
print("<x_pos> <y_pos> <z_pos> The GPS coordinates you want to go to.")
|
||||||
print("<(optional)max_distance> The farthest distance allowed to travel from start position.")
|
print("<(optional)max_distance> The farthest distance allowed to travel from start position.")
|
||||||
end
|
end
|
||||||
@ -49,4 +49,4 @@ if not ok then
|
|||||||
printError("navigation failed: ", err)
|
printError("navigation failed: ", err)
|
||||||
else
|
else
|
||||||
print("succesfully navigated to coordinates")
|
print("succesfully navigated to coordinates")
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user