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
|
||||
if not netNav then
|
||||
if not os.loadAPI("netNav") then
|
||||
error("could not load starNav API")
|
||||
end
|
||||
if not os.loadAPI("netNav") then
|
||||
error("could not load netNav API")
|
||||
end
|
||||
end
|
||||
|
||||
-- OPEN REDNET
|
||||
@ -42,9 +42,7 @@ if type(mapName) ~= "string" then
|
||||
printError("mapName must be string")
|
||||
return
|
||||
end
|
||||
if not netNav.getMap() then
|
||||
netNav.setMap(mapName, 15)
|
||||
end
|
||||
netNav.setMap(mapName, 15)
|
||||
|
||||
local exit = false
|
||||
local returning = false
|
||||
|
||||
@ -1,16 +1,13 @@
|
||||
if not remoteMap then
|
||||
if not os.loadAPI("remoteMap") then
|
||||
error("could not load remoteMap API")
|
||||
end
|
||||
end
|
||||
if not aStar then
|
||||
if not os.loadAPI("aStar") then
|
||||
error("could not load aStar API")
|
||||
end
|
||||
end
|
||||
if not location then
|
||||
if not os.loadAPI("location") then
|
||||
error("could not load location API")
|
||||
local apis = {
|
||||
"remoteMap",
|
||||
"aStar",
|
||||
"location",
|
||||
}
|
||||
for _ api in ipairs(apis) do
|
||||
if not _G[api] then
|
||||
if not os.loadAPI(api) then
|
||||
error("could not load API: "..api)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -20,9 +17,10 @@ local SESSION_MAX_DISTANCE_DEFAULT = 32
|
||||
|
||||
local SESSION_COORD_CLEAR = 1
|
||||
local SESSION_COORD_BLOCKED = 2
|
||||
|
||||
local SESSION_COORD_DISTANCE = math.huge
|
||||
local UPDATE_COORD_CLEAR = -1
|
||||
local UPDATE_COORD_BLOCKED = 1
|
||||
local UPDATE_COORD_DISTANCE = 2
|
||||
|
||||
local sessionMidPoint
|
||||
local sessionMaxDistance
|
||||
@ -33,18 +31,18 @@ local serverMap
|
||||
local function distanceFunc(a, b)
|
||||
local sessionMapA, sessionMapB = sessionMap:get(a), sessionMap:get(b)
|
||||
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
|
||||
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
|
||||
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
|
||||
return aStar.distance(a, b) -- we have found both of these coords to be clear during this session
|
||||
else
|
||||
local serverMapA, serverMapB = serverMap:get(a), serverMap:get(b)
|
||||
if serverMapA or serverMapB then
|
||||
serverMapA = serverMapA and 2^(serverMapA + 1) or 1
|
||||
serverMapB = serverMapB and 2^(serverMapB + 1) or 1
|
||||
serverMapA = serverMapA and UPDATE_COORD_DISTANCE^(serverMapA + 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
|
||||
end
|
||||
end
|
||||
@ -254,16 +252,16 @@ local function _goto(x, y, z, maxDistance)
|
||||
local goal = vector.new(tonumber(x), tonumber(y), tonumber(z))
|
||||
|
||||
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))
|
||||
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)
|
||||
if not path then
|
||||
return false, "no known path to goal"
|
||||
end
|
||||
|
||||
|
||||
while not (exit or aStar.vectorEquals(position, goal)) do
|
||||
local movePos = table.remove(path)
|
||||
while not move(position, movePos) do
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
local function printUsage()
|
||||
print("Usage:")
|
||||
print(fs.getName(shell.getRunningProgram()).." <remoteMap_name> <x_pos> <y_pos> <z_pos>")
|
||||
print("<remoteMap_name> The name of the remoteMap to connect to and use.")
|
||||
print(fs.getName(shell.getRunningProgram()).." <map_name> <x_pos> <y_pos> <z_pos> <(optional)max_distance>")
|
||||
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("<(optional)max_distance> The farthest distance allowed to travel from start position.")
|
||||
end
|
||||
|
||||
if not netNav then
|
||||
@ -40,10 +41,22 @@ for i = 2, 4 do
|
||||
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])
|
||||
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
|
||||
printError("navigation failed: ", err)
|
||||
else
|
||||
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
|
||||
if not os.loadAPI("tinyMap") then
|
||||
error("could not load tinyMap API")
|
||||
end
|
||||
end
|
||||
if not aStar then
|
||||
if not os.loadAPI("aStar") then
|
||||
error("could not load aStar API")
|
||||
end
|
||||
end
|
||||
if not location then
|
||||
if not os.loadAPI("location") then
|
||||
error("could not load location API")
|
||||
local apis = {
|
||||
"tinyMap",
|
||||
"aStar",
|
||||
"location",
|
||||
}
|
||||
for _ api in ipairs(apis) do
|
||||
if not _G[api] then
|
||||
if not os.loadAPI(api) then
|
||||
error("could not load API: "..api)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -38,13 +35,13 @@ local function distanceFunc(a, b)
|
||||
elseif aStar.distance(b, sessionMidPoint) > sessionMaxDistance then
|
||||
return SESSION_COORD_DISTANCE -- second coord is outside the search region
|
||||
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
|
||||
elseif sessionMapA == SESSION_COORD_CLEAR and sessionMapA == SESSION_COORD_CLEAR then
|
||||
return aStar.distance(a, b) -- both coords has been found to be clear 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 sessionMapB == SESSION_COORD_CLEAR then
|
||||
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
|
||||
return MAIN_COORD_DISTANCE
|
||||
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
|
||||
|
||||
local directions = {
|
||||
@ -230,7 +227,9 @@ local function move(currPos, adjPos)
|
||||
return false
|
||||
end
|
||||
|
||||
local exit = false
|
||||
local function _goto(x, y, z, maxDistance)
|
||||
exit = false
|
||||
if not mainMap then
|
||||
error("mainMap has not been specified")
|
||||
end
|
||||
@ -246,7 +245,7 @@ local function _goto(x, y, z, maxDistance)
|
||||
|
||||
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))
|
||||
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"
|
||||
end
|
||||
|
||||
while not aStar.vectorEquals(position, goal) do
|
||||
while not (exit or aStar.vectorEquals(position, goal)) do
|
||||
local movePos = table.remove(path)
|
||||
while not move(position, movePos) do
|
||||
local blockPresent, blockData = inspect(position, movePos)
|
||||
@ -293,7 +292,7 @@ local function _goto(x, y, z, maxDistance)
|
||||
|
||||
mainMap:saveAll()
|
||||
|
||||
return true
|
||||
return aStar.vectorEquals(position, goal)
|
||||
end
|
||||
|
||||
local isRunning = false
|
||||
@ -311,6 +310,11 @@ function goto(...)
|
||||
return unpack(passback, 2)
|
||||
end
|
||||
|
||||
function stop()
|
||||
if isRunning then
|
||||
exit = true
|
||||
end
|
||||
end
|
||||
function setMap(mapName)
|
||||
if type(mapName) ~= "string" then
|
||||
error("mapName must be string")
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
local function printUsage()
|
||||
print("Usage:")
|
||||
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("<(optional)max_distance> The farthest distance allowed to travel from start position.")
|
||||
end
|
||||
@ -49,4 +49,4 @@ if not ok then
|
||||
printError("navigation failed: ", err)
|
||||
else
|
||||
print("succesfully navigated to coordinates")
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user