Advertisement
Doob

[OpenComputers] fgps

May 14th, 2017
342
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.90 KB | None | 0 0
  1. local component = require('component')
  2. if not component.isAvailable('eeprom') then
  3.   print('Required eeprom component')
  4.   os.exit()
  5. end
  6. local eeprom = component.eeprom
  7. local coords
  8. local ARGS = {...}
  9. if #ARGS == 3 then
  10.   local c = 0
  11.   for i = 1, 3 do
  12.     if type(tonumber(ARGS[i])) == 'number' then
  13.       c = c + 1
  14.     end
  15.   end
  16.   if c == 3 then
  17.     coords = 'X, Y, Z = '..table.concat(ARGS, ', ')
  18.   end
  19. end
  20.  
  21. local bios = [[local CHANNEL_GPS = 65534
  22. local modem = component.proxy(component.list('modem')())
  23. modem.open(CHANNEL_GPS)
  24. modem.setWakeMessage('PING')
  25. local function round(v, m)
  26.   m = m or 1.0
  27.   return {
  28.     x = math.floor((v.x+(m*0.5))/m)*m,
  29.     y = math.floor((v.y+(m*0.5))/m)*m,
  30.     z = math.floor((v.z+(m*0.5))/m)*m
  31.   }
  32. end
  33.  
  34. local function len(v)
  35.   return math.sqrt(v.x^2 + v.y^2 + v.z^2)
  36. end
  37.  
  38. local function cross(v, b)
  39.   return {x = v.y*b.z-v.z*b.y, y = v.z*b.x-v.x*b.z, z = v.x*b.y-v.y*b.x}
  40. end
  41.  
  42. local function dot(v, b)
  43.   return v.x*b.x + v.y*b.y + v.z*b.z
  44. end
  45.  
  46. local function add(v, b)
  47.   return {x = v.x+b.x, y = v.y+b.y, z = v.z+b.z}
  48. end
  49.  
  50. local function sub(v, b)
  51.   return {x = v.x-b.x, y = v.y-b.y, z = v.z-b.z}
  52. end
  53.  
  54. local function mul(v, m)
  55.   return {x = v.x*m, y = v.y*m, z = v.z*m}
  56. end
  57.  
  58. local function norm(v)
  59.   return mul(v, 1/len(v))
  60. end
  61.  
  62. local function trilaterate(A, B, C)
  63.   local a2b = {x = B.x-A.x, y = B.y-A.y, z = B.z-A.z}
  64.   local a2c = {x = C.x-A.x, y = C.y-A.y, z = C.z-A.z}
  65.   if abs(dot(norm(a2b), norm(a2c))) > 0.999 then
  66.     return nil
  67.   end
  68.   local d = len(a2b)
  69.   local ex = norm(a2b)
  70.   local i = dot(ex, a2c)
  71.   local ey = norm(sub(mul(ex, i), a2c))
  72.   local j = dot(ey, a2c)
  73.   local ez = cross(ex, ey)
  74.   local r1 = A.d
  75.   local r2 = B.d
  76.   local r3 = C.d
  77.   local x = (r1^2 - r2^2 + d^2) / (2*d)
  78.   local y = (r1^2 - r3^2 - x^2 + (x-i)^2 + j^2) / (2*j)
  79.   local result = add(A, add(mul(ex, x), mul(ey, y)))
  80.   local zSquared = r1^2 - x^2 - y^2
  81.   if zSquared > 0 then
  82.     local z = sqrt( zSquared )
  83.     local result1 = add(result, mul(ez, z))
  84.     local result2 = add(result, mul(ez, z))
  85.     local rounded1, rounded2 = round(result1, 0.01), round(result2, 0.01)
  86.     if rounded1.x ~= rounded2.x or rounded1.y ~= rounded2.y or rounded1.z ~= rounded2.z then
  87.       return rounded1, rounded2
  88.     else
  89.       return rounded1
  90.     end
  91.   end
  92.   return round(result, 0.01)
  93. end
  94.  
  95. local function narrow(p1, p2, fix)
  96.   local dist1 = math.abs(len(sub(p1, fix)) - fix.d)
  97.   local dist2 = math.abs(len(sub(p2, fix)) - fix.d)
  98.   if math.abs(dist1 - dist2) < 0.01 then
  99.     return p1, p2
  100.   elseif dist1 < dist2 then
  101.     return round(p1, 0.01)
  102.   else
  103.     return round(p2, 0.01)
  104.   end
  105. end
  106.  
  107. function locate()
  108.   modem.open(CHANNEL_GPS)
  109.   modem.broadcast(CHANNEL_GPS, 'PING')
  110.   local tFixes = {}
  111.   local pos1, pos2 = nil, nil
  112.   local timeout = computer.uptime()+2
  113.   while true do
  114.     local e = {computer.pullSignal(1)}
  115.     if e[1] == 'modem_message' and e[6] == 'GPS' then
  116.       local tFix = {x = e[7], y = e[8], z = e[9], d = e[5]}
  117.       if tFix.d == 0 then
  118.         pos1, pos2 = {tFix.x, tFix.y, tFix.z}, nil
  119.       else
  120.         table.insert(tFixes, tFix)
  121.         if #tFixes >= 3 then
  122.           if not pos1 then
  123.             pos1, pos2 = trilaterate(tFixes[1], tFixes[2], tFixes[#tFixes])
  124.           else
  125.             pos1, pos2 = narrow(pos1, pos2, tFixes[#tFixes])
  126.           end
  127.         end
  128.       end
  129.       if pos1 and not pos2 then
  130.         break
  131.       end
  132.     end
  133.     if computer.uptime() >= timeout then
  134.       break
  135.     end
  136.   end
  137.   if pos1 and pos2 then
  138.     return nil
  139.   elseif pos1 then
  140.     X, Y, Z = pos1.x, pos1.y, pos1.z
  141.     return true
  142.   else
  143.     return nil
  144.   end
  145. end
  146.  
  147. if not X and not locate() then
  148.   computer.shutdown()
  149. end
  150.  
  151. modem.broadcast(CHANNEL_GPS, 'GPS', X, Y, Z)
  152. computer.shutdown()]]
  153. if coords then
  154.   bios = coords..'\n'..bios
  155. end
  156. eeprom.set(bios)
  157. eeprom.setLabel(table.concat(ARGS, ', '))
  158. print('GPS firmware installed')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement