feat: Add Live GPS Tracker for Pocket Computer with real-time location display
This commit is contained in:
270
pocketgps.lua
Normal file
270
pocketgps.lua
Normal file
@@ -0,0 +1,270 @@
|
||||
-- Live GPS Tracker for Pocket Computer
|
||||
-- Shows your current location in real-time
|
||||
|
||||
local STATUS_CHANNEL = 102
|
||||
|
||||
-- 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
|
||||
|
||||
modem.open(STATUS_CHANNEL)
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user