meigrafd

GPS Deploy 1.2

Jun 11th, 2017
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 19.05 KB | None | 0 0
  1. -- GPS Deploy 1.2 - update by Dog aka HydrantHunter
  2. -- http://www.computercraft.info/forums2/index.php?/topic/18830-dogs-progs-for-stargates-biolocks-and-more/
  3. -- pastebin: VXAyXqBv
  4. --
  5. -- This script is originally from BigSHinyToys from ComputerCraft.info
  6. -- Original link can be found here:
  7. -- http://www.computercraft.info/forums2/index.php?/topic/3088-how-to-guide-gps-global-position-system/page__p__28333#entry28333
  8. --
  9. -- Modifications included (line numbers no longer valid):
  10. --
  11. -- GPS Deploy by neonerZ v1.1
  12. -- http://youtube.com/neonerz
  13. -- http://www.computercraft.info/forums2/index.php?/topic/9528-gps-deploy-11-updated-04012014/
  14. --
  15. -- happydude11209: Line 209 - added logic to check if the server is set to no fuel mode
  16. -- http://www.computercraft.info/forums2/index.php?/topic/9528-gps-deploy-10/page__view__findpost__p__123411
  17. --
  18. -- kittykiller: Line 110 - Bug in the locate code if you were using an existing GPS system to deploy a new one
  19. -- http://www.computercraft.info/forums2/index.php?/topic/9528-gps-deploy-10/page__view__findpost__p__80323
  20. --
  21. -- Mad_Professor: Line 296 - Bug calling computers, monitors. Making people think they needed to load 4 monitors
  22. -- http://www.computercraft.info/forums2/index.php?/topic/9528-gps-deploy-10/page__view__findpost__p__150291
  23. --
  24. -- Dog: Too many fixes and changes to list - based on v1.1:
  25. --   Localized variables, reformatted table construction, eliminated duplicate and unnecessary sanity checks,
  26. --   reduced use of tonumber() and turtle calls, added automatic modem finding and an error for non-wireless
  27. --   turtles when using 'locate', automatic GPS host computer labeling (respects currently labeled computers),
  28. --   custom host support re-enabled, emergency return-to-start when unable to complete the job,
  29. --   re-ordered the program to make it more linear, converted many variables to camelCase, and more.
  30. --   Reasonably well tested with 100% accuracy in all tests.
  31. --
  32. -- In order to use this script you need to setup
  33. -- either a mining turtle, or a standard turtle
  34. -- Mining Turtle:
  35. --          Slot 1 - Fuel
  36. --          Slot 2 - 1 floppy disk
  37. --          Slot 3 - 1 disk drive
  38. --          Slot 4 - 4 wireless modems
  39. --          Slot 5 - 4 computers (labeled, unlabeled, or mixed) across
  40. --                      slots 5, 6, 7, 8 (unlabeled computers may be stacked)
  41. -- Non-Mining Turtle:
  42. --          Slot 1 - Fuel
  43. --          Slot 2 - 1 floppy disk
  44. --          Slot 3 - 4 disk drives
  45. --          Slot 4 - 4 wireless modems
  46. --          Slot 5 - 4 computers (labeled, unlabeled, or mixed) across
  47. --                      slots 5, 6, 7, 8 (unlabeled computers may be stacked)
  48. --
  49. -- (mining turtles will be able to reuse the same
  50. --  disk drive, where-as a standard turtle will leave
  51. --  them and deploy a separate disk drive for each
  52. --  GPS host)
  53. --
  54. -- Default Usage: Place the turtle where you want it
  55. --    deployed facing the SOUTH or 0 direction.
  56. --    Fill the turtle with the required materials
  57. --    above. Then use the command
  58. --
  59. --    gps-deploy x y z
  60. --
  61. --    Where x, y, z is the *absolute* positions of the deployment
  62. --    turtle. By default the turtle will deploy the
  63. --    the GPS array at around y = 254. Add a fourth
  64. --    value to specify the height offset.
  65. --    IMPORTANT: It's crucial you use your absolute coordinates,
  66. --     (the ones inside the parentheses next to your relative coordinates)
  67. --     For Example: If F3 shows X = -6.43534 (-7) or Z = -15.542 (-16)
  68. --     you'd use -7 and -16 respectively. If you use -6 and -15 all coordinates
  69. --     that go past 0 in the opposite direction will be off by 1.)
  70. --
  71. --    Example: gps-deploy 1 1 1 20
  72. --
  73. --    Would assume the turtle's start position is
  74. --    x = 1, y = 1, z = 1 and will deploy the satellite
  75. --    array at y = 21
  76. --
  77. --neonerZ added features
  78. --  Smart Refilling: Fuel should go in slot 1.
  79. --    If not enough fuel is available script
  80. --    will prompt user for more fuel and wait 30.
  81. --    Script will estimate how much fuel is needed
  82. --    and try to take only that much (in coal)
  83. --  Item Detection: Script will check slots 2-5
  84. --    for the correct quantity of items. It does
  85. --    *not* check if items are valid
  86. --  GPS Host Coordinates: The script now requires
  87. --    you to enter in the coordinates of the
  88. --    turtle before launching. This will set
  89. --    the GPS host computers to the correct
  90. --    coordinates.
  91. --  Satelite Array Location: The script allows
  92. --    the user to set an offset for the placement
  93. --    of the four satellites
  94.  
  95. -- check if the script is running on a turtle
  96. -- (original code - modified by Dog)
  97. if not turtle then error("Error: Not a turtle.", 0) end
  98.  
  99. -- How high up should the satellite be deployed?
  100. -- This is not absolute height, but relative height.
  101. -- This is the default value if you don't pass a
  102. -- value to the script. There is a check down below
  103. -- to make sure the absolute height isn't > 254
  104. local height, currentHeight, MAXHEIGHT = 254, 0, 254
  105. local tArgs, xCoord, yCoord, zCoord, modemSide = { ... }
  106.  
  107. term.setBackgroundColor(colors.black)
  108. term.clear()
  109.  
  110. -- determine if the turtle has a wireless modem (for 'locate' and coord verification at the end)
  111. for _, side in pairs({ "left", "right" }) do
  112.   if peripheral.isPresent(side) and peripheral.getType(side) == "modem" and peripheral.call(side, "isWireless") then
  113.     modemSide = side
  114.     break
  115.   end
  116. end
  117.  
  118. -- Check to see if the necessary values were
  119. -- passed to the script
  120. -- confirm absolute height isn't set above 254
  121. if tArgs[1] == "locate" then
  122.   if not modemSide then error("Error: Wireless turtle required.\n", 0) end
  123.   print("Locating GPS signal...\n")
  124.   rednet.open(modemSide)
  125.   xCoord, yCoord, zCoord = gps.locate(3)
  126.   rednet.close(modemSide)
  127.   if not xCoord then error("No GPS signal detected, please re-run manually.\n", 0) end
  128.   if tArgs[2] and tonumber(tArgs[2]) then
  129.     height = math.min(MAXHEIGHT - yCoord, tonumber(tArgs[2]))
  130.   else
  131.     height = MAXHEIGHT - yCoord
  132.   end
  133. else
  134.   if (#tArgs < 3 or #tArgs > 4) or (not tonumber(tArgs[1]) or not tonumber(tArgs[2]) or not tonumber(tArgs[3])) then
  135.     local prog = shell.getRunningProgram()
  136.     print("Usage:\n")
  137.     print(prog .. " <x> <y> <z> [height]")
  138.     print(" - or -")
  139.     print(prog .. " locate [height]\n")
  140.     print("Height is relative to your position.")
  141.     print("Example: " .. prog .. " 1 1 1 20")
  142.     print("would deploy the satellite to y = 21.\n")
  143.     print("If you have working GPS use 'locate'")
  144.     print("to automatically set the start coords.")
  145.     return
  146.   else
  147.     xCoord = tonumber(tArgs[1])
  148.     yCoord = tonumber(tArgs[2])
  149.     zCoord = tonumber(tArgs[3])
  150.     if tArgs[4] and tonumber(tArgs[4]) then
  151.       height = math.min(MAXHEIGHT - yCoord, tonumber(tArgs[4]))
  152.     else
  153.       height = MAXHEIGHT - yCoord
  154.     end
  155.   end
  156. end
  157.  
  158. -- Check if we have enough fuel
  159. -- we estimate the fuel usage ((height * 2) + 70) needed to
  160. -- complete the deployment and then see if we have enough
  161. -- fuel loaded. If we don't, it checks the first slot for
  162. -- available fuel and tries to fill up on it. If it doesn't
  163. -- have enough fuel in there, it prompts the user for more
  164. -- fuel. It allows 30 seconds for the user to add  fuel
  165. -- (trying to refuel and verify fuel level every second)
  166. -- and if it doesn't get it's fill within 30 seconds
  167. -- it exits with a message to the user
  168. -- neonerZ (updated by Dog)
  169. local fuelHave = turtle.getFuelLevel()
  170. if type(fuelHave) == "string" then
  171.   print("")
  172.   print("-= No-fuel mode =-\n")
  173. else
  174.   local fuelRequired, fuel, coal, totalCoal = (height * 2) + 70
  175.   if fuelHave < fuelRequired then
  176.     turtle.select(1)
  177.     repeat
  178.       totalCoal = (fuelRequired - fuelHave) / 80
  179.       coal = math.min(64, math.ceil(totalCoal))
  180.       if not turtle.refuel(coal) then
  181.         fuelHave = turtle.getFuelLevel()
  182.         fuel = fuelRequired - fuelHave
  183.         totalCoal = fuel / 80
  184.         coal = math.min(64, math.ceil(totalCoal))
  185.         term.clear()
  186.         term.setCursorPos(1, 1)
  187.         print("Insufficient fuel in slot 1.")
  188.         for i = 30, 1, -1 do
  189.           term.setCursorPos(1, 3)
  190.           print("Please insert " .. tostring(fuel) .. " fuel or " .. tostring(totalCoal) .. " coal to continue.          ")
  191.           term.setCursorPos(1, 5)
  192.           print("Waiting " .. tostring(i) .. " seconds for fuel or exiting. ")
  193.           sleep(1)
  194.           turtle.refuel(coal)
  195.           fuelHave = turtle.getFuelLevel()
  196.           if fuelHave >= fuelRequired then break end
  197.           totalCoal = (fuelRequired - fuelHave) / 80
  198.           coal = math.min(64, math.ceil(totalCoal))
  199.           fuel = fuelRequired - fuelHave
  200.           if i == 1 then
  201.             print("")
  202.             print("Not enough fuel provided.\n")
  203.             print("Please provide " .. tostring(fuel) .. " fuel or " .. tostring(totalCoal) .. " coal and try again.\n")
  204.             return
  205.           end
  206.         end
  207.       else
  208.         fuelHave = turtle.getFuelLevel()
  209.       end
  210.     until fuelHave >= fuelRequired
  211.   end
  212.   print("")
  213.   print("-= Turtle Fueled =-\n")
  214. end
  215.  
  216. -- check if the required quantity of items
  217. -- are in the appropriate spots. I'm sure
  218. -- there's a more elegant way of doing this.
  219. -- I don't believe there's a way to check if
  220. -- the items are correct without using compare
  221. -- inventory checking re-written and slotNum selection adjusted by Dog
  222. local err = false
  223. local itemTable = {
  224.   [2] = { 1, "Please place 1 floppy disk in slot two." };
  225.   [3] = { 1, "Please place 1 disk drive in slot three (mining turtle), or place 4 disk drives in slot three (standard turtle)." };
  226.   [4] = { 4, "Please place 4 modems in slot four." };
  227.   [5] = { 4, "Please place 4 computers across slots 5, 6, 7, 8. They may be labled, unlabled, or a mix of both.  Unlabeled computers may be stacked." };
  228. }
  229.  
  230. for i = 2, 5 do
  231.   if turtle.getItemCount(i) < itemTable[i][1] then
  232.     if i == 5 then
  233.       if (turtle.getItemCount(5) + turtle.getItemCount(6) + turtle.getItemCount(7) + turtle.getItemCount(8)) < 4 then
  234.         print(itemTable[5][2])
  235.         print("")
  236.         err = true
  237.       end
  238.     else
  239.       print(itemTable[i][2])
  240.       print("")
  241.       err = true
  242.     end
  243.   end
  244. end
  245.  
  246. if err then
  247.   print("Please fix the above issue(s) and restart.\n")
  248.   return
  249. end
  250.  
  251. --# Custom host program support - re-enabled by Dog
  252. local base
  253. if fs.exists("custom") then
  254.   term.clear()
  255.   term.setCursorPos(1, 1)
  256.   print("Custom program detected!")
  257.   print("Please enter base station number.\n")
  258.   repeat
  259.     write(" > ")
  260.     base = tonumber(read())
  261.     if not base then
  262.       print("Error: Not a number.")
  263.       print("Try again...\n")
  264.     end
  265.   until type(base) == "number"
  266. end
  267.  
  268. -- move functions
  269. local facing, currentX, currentZ = 1, xCoord, zCoord
  270. local cardinals, xOffset, zOffset = { "South", "West", "North", "East" }, { 0, -1, 0, 1 }, { 1, 0, -1, 0 }
  271.  
  272. local function emergencyStop()
  273.   local failCount = 0
  274.   print("ABORT! Unable to complete action.")
  275.   print("Attempting to return to origin point.")
  276.   if currentX > xCoord then     --# If east of the target then...
  277.     if facing ~= 2 then         --# if not facing west then...
  278.       repeat                    --# turn until facing west
  279.         turtle.turnRight()
  280.         facing = (facing % 4) + 1
  281.       until facing == 2
  282.     end
  283.   elseif currentX < xCoord then --# If west of the target then...
  284.     if facing ~= 4 then         --# if not facing east then...
  285.       repeat                    --# turn until facing east
  286.         turtle.turnRight()
  287.         facing = (facing % 4) + 1
  288.       until facing == 4
  289.     end
  290.   end
  291.   if currentX ~= xCoord then
  292.     repeat                      --# Move forward until currentX == xCoord
  293.       while not turtle.forward() do
  294.         turtle.dig()
  295.         failCount = failCount + 1
  296.         if failCount == 10 then error("Aborting return trip - too many obstacles.", 0) end
  297.       end
  298.       currentX = currentX + xOffset[facing]
  299.     until currentX == xCoord
  300.   end
  301.   if currentZ > zCoord then     --# If south of the target then...
  302.     if facing ~= 3 then         --# if not facing north then...
  303.       repeat                    --# turn until facing north
  304.         turtle.turnRight()
  305.         facing = (facing % 4) + 1
  306.       until facing == 3
  307.     end
  308.   elseif currentZ < zCoord then --# If north of the target then...
  309.     if facing ~= 1 then         --# if not facing south then...
  310.       repeat                    --# turn until facing south
  311.         turtle.turnRight()
  312.         facing = (facing % 4) + 1
  313.       until facing == 1
  314.     end
  315.   end
  316.   if currentZ ~= zCoord then
  317.     failCount = 0
  318.     repeat                      --# Move forward until currentZ == zCoord
  319.       while not turtle.forward() do
  320.         turtle.dig()
  321.         failCount = failCount + 1
  322.         if failCount == 10 then error("Aborting return trip - too many obstacles.", 0) end
  323.       end
  324.       currentZ = currentZ + zOffset[facing]
  325.     until currentZ == zCoord
  326.   end
  327.   if facing ~= 1 then           --# If not facing south then...
  328.     repeat                      --# turn until facing south
  329.       turtle.turnRight()
  330.       facing = (facing % 4) + 1
  331.     until facing == 1
  332.   end
  333.   failCount = 0
  334.   for i = 1, currentHeight do   --# Now above origin point, go down until reaching the origin point
  335.     while not turtle.down() do
  336.       turtle.digDown()
  337.       failCount = failCount + 1
  338.       if failCount == 10 then error("Aborting return trip - too many obstacles.", 0) end
  339.     end
  340.   end
  341.   if modemSide then
  342.     local gpsX, gpsY, gpsZ = gps.locate(3)
  343.     if gpsX then
  344.       print((gpsX == xCoord and gpsY == yCoord and gpsZ == zCoord) and "Coordinates verified." or "Coordinates don't match.")
  345.     else
  346.       print("GPS array unreachable.")
  347.     end
  348.   end
  349.   error("Return trip complete.\n", 0)
  350. end
  351.  
  352. -- (original code - reformatted and modified by Dog)
  353. local failCount --# use a forward declaration so the variable doesn't have to be initialized every time a mov function is called
  354. local mov = {
  355.   forward = function()
  356.     failCount = 0
  357.     while not turtle.forward() do
  358.       sleep(1)
  359.       failCount = failCount + 1
  360.       if failCount == 5 then emergencyStop() end
  361.     end
  362.     currentX = currentX + xOffset[facing]
  363.     currentZ = currentZ + zOffset[facing]
  364.   end;
  365.   back = function()
  366.     failCount = 0
  367.     while not turtle.back() do
  368.       sleep(1)
  369.       failCount = failCount + 1
  370.       if failCount == 5 then emergencyStop() end
  371.     end
  372.     currentX = currentX - xOffset[facing]
  373.     currentZ = currentZ - zOffset[facing]
  374.   end;
  375.   up = function()
  376.     failCount = 0
  377.     while not turtle.up() do
  378.       sleep(1)
  379.       failCount = failCount + 1
  380.       if failCount == 5 then emergencyStop() end
  381.     end
  382.     currentHeight = currentHeight + 1
  383.   end;
  384.   down = function()
  385.     failCount = 0
  386.     while not turtle.down() do
  387.       sleep(1)
  388.       failCount = failCount + 1
  389.       if failCount == 5 then emergencyStop() end
  390.     end
  391.     currentHeight = currentHeight - 1
  392.   end;
  393.   left = function()
  394.     turtle.turnLeft()
  395.     facing = ((facing - 2) % 4) + 1
  396.   end;
  397.   right = function()
  398.     turtle.turnRight()
  399.     facing = (facing % 4) + 1
  400.   end;
  401.   place = function()
  402.     failCount = 0
  403.     while not turtle.place() do
  404.       sleep(1)
  405.       failCount = failCount + 1
  406.       if failCount == 5 then emergencyStop() end
  407.     end
  408.   end;
  409. }
  410.  
  411. print("")
  412. print("X: " .. tostring(xCoord) .. " Y: " .. tostring(yCoord) .. " Z: " .. tostring(zCoord) .. " Height: " .. tostring(height + yCoord) .. " (+" .. tostring(height) ..")\n")
  413. print("-= Launching =-\n")
  414. -- start the climb up to the correct yCoord
  415. for i = 1, height do
  416.   mov.up()
  417. end
  418.  
  419. -- once at the correct height, deploy GPS array
  420. -- this is a mixture of my own code and the
  421. -- original code
  422. -- calculate the coordinates of the 4 satellite computers
  423. local toYcordNS = math.min(MAXHEIGHT, yCoord + height)
  424. local toYcordWE = toYcordNS - 3
  425. local file, direction
  426. local coords = {
  427.   { x = xCoord, z = zCoord + 3, y = toYcordNS };
  428.   { x = xCoord - 3, z = zCoord, y = toYcordWE };
  429.   { x = xCoord, z = zCoord - 3, y = toYcordNS };
  430.   { x = xCoord + 3, z = zCoord, y = toYcordWE };
  431. }
  432.  
  433. for a = 1, 4 do
  434.   direction = cardinals[a]
  435.   mov.forward()
  436.   mov.forward()
  437.   if turtle.getItemCount(5) > 0 then --# Select & place computer
  438.     turtle.select(5)
  439.   elseif turtle.getItemCount(6) > 0 then
  440.     turtle.select(6)
  441.   elseif turtle.getItemCount(7) > 0 then
  442.     turtle.select(7)
  443.   else
  444.     turtle.select(8)
  445.   end
  446.   print("Placing " .. direction .. ".")
  447.   mov.place()
  448.   mov.back()
  449.   turtle.select(4) --# Select & place modem
  450.   mov.place()
  451.   mov.down()
  452.   mov.forward()
  453.   turtle.select(3) --# Select & place disk drive
  454.   mov.place()
  455.   turtle.select(2) --# Select & insert floppy disk
  456.   turtle.drop()
  457.   -- make a custom disk that starts up the gps host application
  458.   -- with the correct coordinates and copy it over. also
  459.   -- makes it a startup script so the program will
  460.   -- start back up properly after chunk reloading
  461.   print("Configuring " .. direction .. ".")
  462.   if fs.exists("custom") then
  463.     fs.copy("custom","disk/custom")
  464.   end
  465.   file = fs.open("disk/startup", "w")
  466.   file.write([[
  467. if not os.getComputerLabel() then os.setComputerLabel("GPS Host ]] .. direction .. [[ (" .. tostring(os.getComputerID()) .. ")") end
  468. if fs.exists("startup") and fs.exists("startup-old") then fs.delete("startup-old") end
  469. if fs.exists("startup") then fs.move("startup", "startup-old") end
  470. fs.copy("disk/install", "startup")
  471. fs.delete("disk/startup")
  472. if fs.exists("disk/custom") then
  473.   fs.copy("disk/custom", "custom")
  474.   fs.delete("disk/custom")
  475. end
  476. print("Sleeping for 5 seconds.")
  477. sleep(5)
  478. os.reboot()
  479. ]])
  480.   file.close()
  481.   file = fs.open("disk/install","w")
  482.   file.write([[
  483. if fs.exists("custom") then
  484.   shell.run("custom", "host", ]] .. coords[a]["x"] .. ", " .. coords[a]["y"] .. ", " .. coords[a]["z"] .. ", " .. (base or "nil") .. [[)
  485. else
  486.   shell.run("gps", "host", ]] .. coords[a]["x"] .. ", " .. coords[a]["y"] .. ", " .. coords[a]["z"] .. [[)
  487. end
  488. ]])
  489.   file.close()
  490.   mov.left()
  491.   mov.forward()
  492.   mov.up()
  493.   mov.right()
  494.   mov.forward()
  495.   mov.right()
  496.   print("Activating " .. direction .. ".")
  497.   peripheral.call("front", "turnOn")
  498.   mov.down()
  499.   print("Retrieving floppy & drive from " .. direction .. ".")
  500.   turtle.select(2) --# Select slot & retreive floppy disk
  501.   turtle.suck()
  502.   turtle.select(3) --# Select slot & retreive floppy drive
  503.   turtle.dig()
  504.   mov.up()
  505.   -- reboot would be here  (Dog: reboot?!?)
  506.   mov.right()
  507.   --back 3 (Dog: back 3?)
  508.   mov.forward()
  509.   mov.forward()
  510.   mov.forward()
  511.   mov.left()
  512.   mov.forward()
  513.   if a == 2 then
  514.     mov.up()
  515.     mov.up()
  516.     mov.up()
  517.   elseif a % 2 ~= 0 then
  518.     mov.down()
  519.     mov.down()
  520.     mov.down()
  521.   end
  522. end
  523.  
  524. -- Return to starting point
  525. print("Returning home.\n")
  526. for i = 1, currentHeight do
  527.   mov.down()
  528. end
  529. if modemSide then
  530.   rednet.open(modemSide)
  531.   local gpsX, gpsY, gpsZ = gps.locate(3)
  532.   rednet.close(modemSide)
  533.   if gpsX then
  534.     print((gpsX == xCoord and gpsY == yCoord and gpsZ == zCoord) and "Success! Coordinates verified.\n" or "Failure. Coordinates don't match.\n")
  535.   else
  536.     print("GPS array unreachable.  Unable to verify installation.\n")
  537.   end
  538. else
  539.   print("Finished.\n")
  540. end
Add Comment
Please, Sign In to add comment