Advertisement
PHOBOSS

PAWN_FIRMWARE.lua

Apr 15th, 2022 (edited)
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.04 KB | None | 0 0
  1. local component = require 'component'
  2. local modem = component.modem
  3.  
  4. local PAWN = {}
  5.  
  6.  
  7. local FIRMWARE = {
  8. [[
  9. d= component.proxy(component.list('drone')())
  10. m= component.proxy(component.list('modem')())
  11. Channel = 2413
  12. ResponseChannel = 2403
  13. gpsChannel = 2
  14.  
  15. m.open(Channel)
  16.  
  17.  
  18. drone_inv = "inv_s"
  19. isDroneQueen = false
  20. isFree = true
  21.  
  22. gpsSats={}
  23. cmdTRGPos={}
  24.  
  25. --lightColor = 0xFFFFFF
  26. lightColor = 16777215
  27. ]]
  28. ,
  29. [[
  30. function sleep(timeout)
  31. checkArg(1, timeout, 'number', 'nil')
  32. local deadline = computer.uptime() + (timeout or 0)
  33. repeat
  34. computer.pullSignal(deadline - computer.uptime())
  35. until computer.uptime() >= deadline
  36. end
  37. ]]
  38. ,
  39. [[
  40. floor, sqrt, abs = math.floor, math.sqrt, math.abs
  41.  
  42. function round(v, m) return {x = floor((v.x+(m*0.5))/m)*m, y = floor((v.y+(m*0.5))/m)*m, z = floor((v.z+(m*0.5))/m)*m} end
  43. function cross(v, b) 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} end
  44. function len(v) return sqrt(v.x^2+v.y^2+v.z^2) end
  45. function dot(v, b) return v.x*b.x+v.y*b.y+v.z*b.z end
  46. function add(v, b) return {x=v.x+b.x, y=v.y+b.y, z=v.z+b.z} end
  47. function sub(v, b) return {x=v.x-b.x, y=v.y-b.y, z=v.z-b.z} end
  48. function mul(v, m) return {x=v.x*m, y=v.y*m, z=v.z*m} end
  49. function norm(v) return mul(v, 1/len(v)) end
  50.  
  51. function arr_length(a)
  52. local c = 0
  53. for k,_ in pairs(a) do c=c+1 end
  54. return c
  55. end
  56. function trunc(v) local t = math.modf(v) return t end
  57. function vec_trunc(A)
  58. if A then
  59. return {x=trunc(A.x),y=trunc(A.y),z=trunc(A.z)}
  60. end
  61. return nil
  62. end
  63. ]]
  64. ,
  65.  
  66. [[
  67. function add2GPSTable(r_addr,x,y,z,dist)
  68. if arr_length(gpsSats) < 7 then gpsSats[r_addr] = {x=x,y=y,z=z,d=dist} end
  69. end
  70. ]]
  71. ,
  72. [[
  73. function replyInv(add)
  74. m.send(add,ResponseChannel,"stats",isFree,isDroneQueen)--Queens send "true"
  75. end
  76. ]]
  77. ,
  78. [[
  79. acts = {
  80. [drone_inv] = function(r_add) d.setLightColor(0x00FFBB) replyInv(r_add) end,
  81. ["commit"] = function() d.setLightColor(0x5E00FF) isFree = false end,
  82. ["uncommit"] = function() isFree = true end,
  83.  
  84. ["gps"] = function(r_addr,x,y,z,dist) add2GPSTable(r_addr,x,y,z,dist) end,
  85. --["trg"] = function(_,x,y,z,dist) cmdTRGPos={c={x,y,z},d=dist} end,
  86. ["formup"] = function(_,x,y,z,_,trgC) d.setStatusText(gpsMoveToTarget({x=x,y=y,z=z},trgC)) end,
  87. ["orbit"] = function(_,x,y,z,_,trgC) d.setStatusText(gpsOrbitTRG({x=x,y=y,z=z},trgC)) end,
  88. ["color"] = function(_,x) lightColor = x end,
  89. ["wru"] = function(r_addr) local whereRU = gpsLocateMe() m.send(r_addr,ResponseChannel,"here",whereRU.x,whereRU.y,whereRU.z) end,
  90. ["HUSH"] = function() computer.shutdown() end
  91. }
  92. ]]
  93. ,
  94. [[
  95. actsWhileMoving = {
  96. [drone_inv] = function(r_add) replyInv(r_add) end,
  97. ["commit"] = function() d.setLightColor(0x0077FF) isFree = false end,
  98. ["uncommit"] = function() isFree = true end,
  99. ["gps"] = function(r_addr,x,y,z,dist) add2GPSTable(r_addr,x,y,z,dist) end,
  100. --["trg"] = function(_,x,y,z,dist) cmdTRGPos={c={x=x,y=y,z=z},d=dist} d.setStatusText("trg2:"..tostring(cmdTRGPos.c.x)) end,
  101. ["color"] = function(_,x) lightColor = x end,
  102. ["wru"] = function(r_addr) local whereRU = gpsLocateMe() m.send(r_addr,ResponseChannel,"here",whereRU.x,whereRU.y,whereRU.z) end,
  103. ["HUSH"] = function() d.setLightColor(0xFF0000) sleep(1) computer.shutdown() end
  104. }
  105. ]]
  106. ,
  107. [[
  108. function trilaterate(A, B, C)
  109. local a2b = {x=B.x-A.x, y=B.y-A.y, z=B.z-A.z}
  110. local a2c = {x=C.x-A.x, y=C.y-A.y, z=C.z-A.z}
  111. if abs(dot(norm(a2b), norm(a2c))) > 0.999 then return nil end
  112. local d, ex = len(a2b), norm(a2b)
  113. local i = dot(ex, a2c)
  114. local exMi = mul(ex, i)
  115. local ey = norm(sub(a2c, mul(ex, i)))
  116. local j, ez = dot(ey, a2c), cross(ex, ey)
  117. local r1, r2, r3 = A.d, B.d, C.d
  118. local x = (r1^2 - r2^2 + d^2) / (2*d)
  119. local y = (r1^2 - r3^2 - x^2 + (x-i)^2 + j^2) / (2*j)
  120. local result = add(A, add(mul(ex, x), mul(ey, y)))
  121. local zSquared = r1^2 - x^2 - y^2
  122. if zSquared > 0 then
  123. local z = sqrt( zSquared )
  124. local result1 = add(result, mul(ez, z))
  125. local result2 = sub(result, mul(ez, z))
  126. local rnd1, rnd2 = result1,result2
  127. if rnd1.x ~= rnd2.x or rnd1.y ~= rnd2.y or rnd1.z ~= rnd2.z then
  128. return rnd1, rnd2
  129. else
  130. return rnd1
  131. end
  132. end
  133. return result
  134. end
  135. ]]
  136. ,
  137. [[
  138. function narrow(p1, p2, fix)
  139. local d1 = abs(len(sub(p1, fix))-fix.d)
  140. local d2 = abs(len(sub(p2, fix))-fix.d)
  141. if abs(d1-d2) < 0.01 then
  142. return p1, p2
  143. elseif d1 < d2 then
  144. return p1,nil
  145. else
  146. return p2,nil
  147. end
  148. end
  149. ]]
  150. ,
  151. [[
  152. function getGPSlocation()
  153. local fixes = {}
  154. local pos1, pos2 = nil, nil
  155. for addr,fix in pairs(gpsSats) do
  156. if fix.d == 0 then
  157. pos1, pos2 = {x=fix.x, y=fix.y, z=fix.z}, nil
  158. else
  159. table.insert(fixes, fix)
  160. end
  161. end
  162. if #fixes >= 3 then
  163. if not pos1 then
  164. pos1, pos2 = trilaterate(fixes[1], fixes[2], fixes[3])
  165. end
  166. if pos1 and pos2 then
  167. for f=4,#fixes do
  168. pos1, pos2 = narrow(pos1, pos2, fixes[f])
  169. if pos1 and not pos2 then break end
  170. end
  171. end
  172. end
  173.  
  174. if pos1 and pos2 then
  175. --d.setStatusText("ps12")
  176. return nil
  177. elseif pos1 then
  178. local c = round(pos1,1)
  179. return {x=c.x,y=c.y,z=c.z}
  180. else
  181. --d.setStatusText("else")
  182. return nil
  183. end
  184. end
  185. ]]
  186. ,
  187. [[
  188. refreshGPSInterval = 0
  189. function refreshGPSTable()
  190. if refreshGPSInterval >= 17 then gpsSats={} refreshGPSInterval = 0 end
  191. refreshGPSInterval = refreshGPSInterval + 1
  192. end
  193.  
  194. function getTRGPos()
  195. return cmdTRGPos
  196. end
  197. ]]
  198. ,
  199. [[
  200. function waitForGPS(gpsCh)
  201. gpsSats={}
  202. m.open(gpsCh)
  203. local ctrlTRGP = nil
  204. repeat
  205. if arr_length(gpsSats)>=3 then
  206. ctrlTRGP = getGPSlocation()
  207. end
  208.  
  209. if ctrlTRGP then
  210. ctrlTRGP = vec_trunc(ctrlTRGP)
  211. m.close(gpsChannel)
  212. return ctrlTRGP
  213.  
  214. else d.setLightColor(0xFF0000) end --d.setStatusText("No GPS:") end
  215.  
  216. _,_,r_addr,_,dist,msg,x,y,z,trgCh = computer.pullSignal(0.5)
  217.  
  218. if actsWhileMoving[msg] then
  219. actsWhileMoving[msg](r_addr,x,y,z,dist)
  220. end
  221. refreshGPSTable()
  222.  
  223. until msg == "stop"
  224.  
  225. m.close(gpsCh)
  226. return ctrlTRGP
  227. end
  228. ]]
  229. ,
  230. [[
  231. function gpsMoveToTarget(offset,trgChannel)
  232. d.setLightColor(0xFFFFFF)
  233. m.open(trgChannel)
  234. local ctrlTRGPos = nil
  235.  
  236. ctrlTRGPos = waitForGPS(gpsChannel)
  237.  
  238. if ctrlTRGPos then
  239. d.setLightColor(0xFFFFFF)
  240. local mv = {x=0,y=0,z=0},msg,r_add,dist,x,y,z
  241. local trgUpdate = {}
  242. --local check = 0
  243. repeat
  244. _,_,r_addr,_,dist,msg,x,y,z,_,_ = computer.pullSignal(0.5)
  245. if actsWhileMoving[msg] then
  246. actsWhileMoving[msg](r_addr,x,y,z,dist)
  247. end
  248. if msg == "trg" then
  249. trgUpdate = {c={x=x,y=y,z=z},d=dist}
  250. end
  251. local trgPos = trgUpdate
  252.  
  253. if trgPos.d and trgPos.d < 50 then
  254. trgPos.c = vec_trunc(trgPos.c)
  255. local trgPosOffset = add(trgPos.c, offset)
  256. mv = sub(trgPosOffset,ctrlTRGPos)
  257. d.move(mv.x,mv.y,mv.z)
  258. ctrlTRGPos = trgPosOffset
  259. --d.setLightColor(0x00FF00)
  260. d.setLightColor(lightColor)
  261. --d.setStatusText(d.name())
  262. --d.setStatusText(tostring(lightColor))
  263. else
  264. d.setLightColor(0xFF0000)
  265. d.setStatusText("No TRG:\n"..tostring(trgChannel))
  266. --d.setStatusText("No TRG:\n"..tostring(check))
  267. d.move(-mv.x,-mv.y,-mv.z)
  268. end
  269. --check = check+1
  270. until msg == "stop"
  271. end
  272. m.close(trgChannel)
  273. return d.name()
  274. end
  275. ]]
  276. ,
  277. [[
  278. function rotatePointOnXAxis(radians,point)
  279. --d.setStatusText("pointx: "..tostring(point.x))
  280. local s = math.sin(radians);
  281. local c = math.cos(radians);
  282.  
  283. local ynew = point.y * c - point.z * s;
  284. local znew = point.y * s + point.z * c;
  285. return {x=point.x,y=ynew,z=znew}
  286. end
  287.  
  288. function rotatePointOnYAxis(radians,point)
  289. --d.setStatusText("pointx: "..tostring(point.x))
  290. local s = math.sin(radians);
  291. local c = math.cos(radians);
  292.  
  293. local xnew = point.x * c - point.z * s;
  294. local znew = point.x * s + point.z * c;
  295. return {x=xnew,y=point.y,z=znew}
  296. end
  297.  
  298. function rotatePointOnZAxis(radians,point)
  299. --d.setStatusText("pointx: "..tostring(point.x))
  300. local s = math.sin(radians);
  301. local c = math.cos(radians);
  302.  
  303. local xnew = point.x * c - point.y * s;
  304. local ynew = point.x * s + point.y * c;
  305. return {x=xnew,y=ynew,z=point.z}
  306. end
  307.  
  308. rotate = {
  309. ["X"] = function(i,basePoint) return rotatePointOnXAxis(i,basePoint) end,
  310. ["Y"] = function(i,basePoint) return rotatePointOnYAxis(i,basePoint) end,
  311. ["Z"] = function(i,basePoint) return rotatePointOnZAxis(i,basePoint) end
  312. }
  313.  
  314. rotate2 = {
  315. ["X"] = function(radians,point)
  316. local s = math.sin(radians);
  317. local c = math.cos(radians);
  318.  
  319. local ynew = point.y * c - point.z * s;
  320. local znew = point.y * s + point.z * c;
  321. return {x=point.x,y=ynew,z=znew}
  322. end,
  323. ["Y"] = function(radians,point)
  324. local s = math.sin(radians);
  325. local c = math.cos(radians);
  326.  
  327. local xnew = point.x * c - point.z * s;
  328. local znew = point.x * s + point.z * c;
  329. return {x=xnew,y=point.y,z=znew}
  330. end,
  331. ["Z"] = function(radians,point)
  332. local s = math.sin(radians);
  333. local c = math.cos(radians);
  334.  
  335. local xnew = point.x * c - point.y * s;
  336. local ynew = point.x * s + point.y * c;
  337. return {x=xnew,y=ynew,z=point.z}
  338. end
  339. }
  340. ]]
  341. ,
  342. [[
  343. function rotatePoint(rad,point)
  344. --d.setStatusText("pointx: "..tostring(point.x))
  345. local s = math.sin(rad);
  346. local c = math.cos(rad);
  347.  
  348. local xnew = point.x * c - point.z * s;
  349. local znew = point.x * s + point.z * c;
  350. return {x=xnew,y=point.y,z=znew}
  351. end
  352. ]]
  353. ,
  354. [[
  355. --rotationInterval = math.pi/4
  356. --rotationInterval = math.pi/8
  357. --rotationInterval = math.pi/2
  358. twPI = 2*math.pi
  359. function gpsOrbitTRG(offset,trgChannel)
  360. d.setLightColor(0xFFFFFF)
  361. m.open(trgChannel)
  362. local ctrlTRGPos = nil
  363.  
  364. ctrlTRGPos = waitForGPS(gpsChannel)
  365.  
  366. if ctrlTRGPos then
  367. d.setLightColor(0xFFFFFF)
  368. local mv = {x=0,y=0,z=0},msg,r_add,dist,x,y,z
  369. local trgUpdate = {}
  370. local currentAngle = 0 -- in radians
  371. local rotationInterval = 0
  372. local tiltAxis = "Z"
  373. local tiltAngle = 0
  374. repeat
  375. _,_,r_addr,_,dist,msg,x,y,z,axis,rotInt,tilt = computer.pullSignal(0.5)
  376. if actsWhileMoving[msg] then
  377. actsWhileMoving[msg](r_addr,x,y,z,dist)
  378. end
  379. if msg == "trg" then
  380. trgUpdate = {c={x=x,y=y,z=z},d=dist}
  381. rotationInterval = rotInt
  382. tiltAxis = axis
  383. tiltAngle = tilt
  384. end
  385. local trgPos = trgUpdate
  386.  
  387. if trgPos.d and trgPos.d < 50 then
  388. trgPos.c = vec_trunc(trgPos.c)
  389.  
  390. --local rotatedOffset = rotatePoint(currentAngle%twPI,offset)
  391.  
  392. local rotatedOffset = rotate2["Y"](currentAngle%twPI,offset)
  393. --rotatedOffset = rotate["Z"](math.pi/4,rotatedOffset)-- tilted rotation??
  394. rotatedOffset = rotate[tiltAxis](tiltAngle,rotatedOffset)-- tilted rotation??
  395.  
  396. currentAngle = currentAngle + rotationInterval
  397.  
  398. local trgPosOffset = add(trgPos.c, rotatedOffset)
  399.  
  400. mv = sub(trgPosOffset,ctrlTRGPos)
  401. d.move(mv.x,mv.y,mv.z)
  402. ctrlTRGPos = trgPosOffset
  403. --d.setLightColor(0x00FF00)
  404. d.setLightColor(lightColor)
  405. --d.setStatusText(d.name())
  406. --d.setStatusText(tostring(lightColor))
  407. else
  408. d.setLightColor(0xFF0000)
  409. --d.setStatusText("No TRG:\n"..tostring(trgChannel))
  410. d.move(-mv.x,-mv.y,-mv.z)
  411. end
  412.  
  413. until msg == "stop"
  414. end
  415. m.close(trgChannel)
  416. return d.name()
  417. end
  418. ]]
  419. ,
  420. [[
  421. function gpsLocateMe()
  422. gpsSats={}
  423. m.open(gpsChannel)
  424. local ctrlTRGPos = nil
  425. repeat
  426. if arr_length(gpsSats)>=3 then
  427. ctrlTRGPos = getGPSlocation()
  428. end
  429.  
  430. if ctrlTRGPos then ctrlTRGPos = vec_trunc(ctrlTRGPos)
  431. else d.setLightColor(0xFF0000) end --d.setStatusText("No GPS:") end
  432.  
  433. _,_,r_addr,_,dist,msg,x,y,z,trgCh,_ = computer.pullSignal(0.5)
  434.  
  435. if actsWhileMoving[msg] then
  436. actsWhileMoving[msg](r_addr,x,y,z,dist)
  437. end
  438. refreshGPSTable()
  439. until msg == "stop" or ctrlTRGPos
  440. return ctrlTRGPos
  441. end
  442. ]]
  443. ,
  444. [[
  445. d.setAcceleration(100)
  446. d.setLightColor(0x007B62)
  447. while true do
  448. _,_,r_addr,_,dist,msg,x,y,z,trgCh,_ = computer.pullSignal(0.5)
  449. --if d.name():match("^S%d+$") then
  450. if acts[msg] then
  451. acts[msg](r_addr,x,y,z,dist,trgCh)
  452. end
  453. --end
  454. --d.setLightColor(0xFFAF00)
  455. --d.setLightColor(0x77FF77)
  456. end
  457. ]]
  458. }
  459.  
  460. PAWN.master = "" --control tablet modem address, set before broadcasting firmware
  461.  
  462. function PAWN.broadcastFirmWare(port)
  463. modem.broadcast(port,
  464. [[
  465. master = ]]..PAWN.master..[[
  466. ]]
  467. )
  468. for _,part in ipairs(FIRMWARE) do
  469. modem.broadcast(port,part)
  470. end
  471. end
  472.  
  473. return PAWN
  474.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement