Files
remoteturtle/pocketgps.lua

274 lines
7.5 KiB
Lua

-- Live GPS Tracker for Pocket Computer
-- Shows your current location in real-time
local Channels = require('platform.channels')
local WebBridge = require('platform.webbridge')
local STATUS_CHANNEL = Channels.get('remoteturtle.status')
-- Setup modem
local modem = peripheral.find("modem")
if not modem then
error("No wireless modem found!")
end
-- Equip modem if on pocket computer
if pocket then
pocket.equipBack()
modem = peripheral.find("modem")
end
WebBridge.openChannels(modem, { 'remoteturtle.status' })
local w, h = term.getSize()
local myID = os.getComputerID()
local currentPos = {x = 0, y = 0, z = 0}
local lastUpdate = 0
local turtles = {}
-- Get GPS position
local function updateGPS()
local x, y, z = gps.locate(5)
if x then
currentPos = {x = math.floor(x), y = math.floor(y), z = math.floor(z)}
lastUpdate = os.clock()
return true
end
return false
end
-- Draw header
local function drawHeader()
term.setCursorPos(1, 1)
term.setBackgroundColor(colors.blue)
term.setTextColor(colors.white)
term.clearLine()
term.setCursorPos(math.floor((w - 14) / 2), 1)
term.write(" GPS TRACKER ")
end
-- Draw position info
local function drawPosition()
term.setBackgroundColor(colors.black)
term.setTextColor(colors.white)
-- Computer ID
term.setCursorPos(2, 3)
term.write("Computer ID: ")
term.setTextColor(colors.yellow)
term.write(tostring(myID))
-- Current coordinates
term.setTextColor(colors.white)
term.setCursorPos(2, 5)
term.write("Current Position:")
term.setCursorPos(4, 6)
term.setTextColor(colors.red)
term.write("X: ")
term.setTextColor(colors.white)
term.write(string.format("%d", currentPos.x))
term.setCursorPos(4, 7)
term.setTextColor(colors.green)
term.write("Y: ")
term.setTextColor(colors.white)
term.write(string.format("%d", currentPos.y))
term.setCursorPos(4, 8)
term.setTextColor(colors.blue)
term.write("Z: ")
term.setTextColor(colors.white)
term.write(string.format("%d", currentPos.z))
-- Time since last update
local timeSince = os.clock() - lastUpdate
term.setCursorPos(2, 10)
term.setTextColor(colors.gray)
if lastUpdate > 0 then
term.write(string.format("Updated %.1fs ago", timeSince))
else
term.write("No GPS fix yet...")
end
end
-- Draw nearby turtles
local function drawTurtles()
term.setBackgroundColor(colors.black)
term.setTextColor(colors.white)
term.setCursorPos(2, 12)
term.write("Nearby Turtles:")
local line = 13
local count = 0
-- Sort turtles by distance
local sortedTurtles = {}
for id, data in pairs(turtles) do
if data.position then
local dx = data.position.x - currentPos.x
local dy = data.position.y - currentPos.y
local dz = data.position.z - currentPos.z
local distance = math.sqrt(dx*dx + dy*dy + dz*dz)
table.insert(sortedTurtles, {id = id, data = data, distance = distance})
end
end
table.sort(sortedTurtles, function(a, b) return a.distance < b.distance end)
-- Display up to 5 closest turtles
for i = 1, math.min(5, #sortedTurtles) do
local turtle = sortedTurtles[i]
term.setCursorPos(4, line)
term.setTextColor(colors.yellow)
term.write(string.format("#%d", turtle.id))
term.setTextColor(colors.white)
term.write(string.format(" [%.1fm]", turtle.distance))
term.setCursorPos(6, line + 1)
term.setTextColor(colors.gray)
term.write(string.format("(%d, %d, %d)",
turtle.data.position.x,
turtle.data.position.y,
turtle.data.position.z))
line = line + 2
count = count + 1
if line >= h - 2 then break end
end
if count == 0 then
term.setCursorPos(4, line)
term.setTextColor(colors.gray)
term.write("None detected")
end
end
-- Draw footer
local function drawFooter()
term.setCursorPos(1, h)
term.setBackgroundColor(colors.gray)
term.setTextColor(colors.white)
term.clearLine()
term.setCursorPos(2, h)
term.write("[Q] Quit [R] Refresh")
end
-- Full screen refresh
local function draw()
term.setBackgroundColor(colors.black)
term.clear()
drawHeader()
drawPosition()
drawTurtles()
drawFooter()
end
-- Handle turtle status broadcasts
local function handleStatus(message)
if message.id and message.id ~= myID then
if not turtles[message.id] then
turtles[message.id] = {}
end
-- Update turtle data
if message.position then
turtles[message.id].position = message.position
end
if message.status then
turtles[message.id].status = message.status
end
if message.fuel then
turtles[message.id].fuel = message.fuel
end
turtles[message.id].lastSeen = os.clock()
end
end
-- Clean up old turtles (not seen in 30 seconds)
local function cleanupTurtles()
local now = os.clock()
for id, data in pairs(turtles) do
if data.lastSeen and (now - data.lastSeen) > 30 then
turtles[id] = nil
end
end
end
-- Main loop
local function main()
print("GPS Tracker starting...")
print("Getting initial GPS fix...")
-- Get initial GPS position
updateGPS()
draw()
local gpsTimer = os.startTimer(2) -- Update GPS every 2 seconds
local cleanupTimer = os.startTimer(10) -- Cleanup every 10 seconds
local drawTimer = os.startTimer(0.5) -- Redraw every 0.5 seconds
while true do
local event, param1, param2, param3, param4, param5 = os.pullEvent()
if event == "timer" then
if param1 == gpsTimer then
updateGPS()
gpsTimer = os.startTimer(2)
elseif param1 == cleanupTimer then
cleanupTurtles()
cleanupTimer = os.startTimer(10)
elseif param1 == drawTimer then
draw()
drawTimer = os.startTimer(0.5)
end
elseif event == "modem_message" then
local channel = param2
local replyChannel = param3
local message = param4
if channel == STATUS_CHANNEL and type(message) == "table" then
handleStatus(message)
end
elseif event == "char" then
if param1 == "q" or param1 == "Q" then
term.setBackgroundColor(colors.black)
term.setTextColor(colors.white)
term.clear()
term.setCursorPos(1, 1)
print("GPS Tracker stopped.")
return
elseif param1 == "r" or param1 == "R" then
updateGPS()
draw()
end
elseif event == "mouse_click" then
-- Check if quit button clicked (bottom bar)
if param3 == h then
term.setBackgroundColor(colors.black)
term.setTextColor(colors.white)
term.clear()
term.setCursorPos(1, 1)
print("GPS Tracker stopped.")
return
end
end
end
end
-- Run the tracker
local success, err = pcall(main)
if not success then
term.setBackgroundColor(colors.black)
term.setTextColor(colors.white)
term.clear()
term.setCursorPos(1, 1)
print("Error: " .. tostring(err))
end