HydrantHunter

GPS Deploy 1.2

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