This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
erima's profile picture

Help with GPS to return to origin

Started by erima, 19 March 2013 - 03:53 PM
erima #1
Posted 19 March 2013 - 04:53 PM
I have written a program for a turtle to harvest village wheat farms. I need to add some logic based on where the turtle is placed, but placing it in the correct spot and running it works - but adding a sleep() command and looping it introduces problems. Upon a second run it might end it's run in an odd part of the farm area, or it could go off and wander.

At first I thought it was a GPS host issue where I was triangulating the wrong coordinates, and I was right. The gps host computers I set up had a couple of incorrect hard-coded X coordinates. It seems that's not the only issue though, and I'm stumped. They still seem to go off sometimes.

Another thing to mention - I was reading up on wheat growth in vanilla Minecraft and read that rows grow faster when there is not wheat next to it, so I took those village farms and only harvest 1 of the two columns, leaving the other tilled and not used.


-- current location and known gps points
local home = vector.new(gps.locate())
local refill = vector.new(0, 0, 0) -- replace with gps of inventory to get stock
local refuel = vector.new(0, 0, 0) -- replace with gps of inventory to get fuel
local dump = vector.new(0, 0, 0) -- replace with gps of inventory to dump to
-- item slots used to compare against inventory and produce
local fuel = 1
local seedCompare = 2
local wheatCompare = 3
local dirtCompare = 4
-- configuration
local fuelIncrement = 2 -- the amount of item to use to refuel
local rowSize = 7 -- the distance to plant and sow, this is size of village row
local rows = 4 -- the number of rows to plant
local skip = 2 -- the number of rows to skip, water, empty field, etc
-- FUNCTIONS

-- check fuel level
local function fuelCheck()
print("checking fuel levels...")
local fuelLevel = turtle.getFuelLevel()
-- refuel if necessary
if fuelLevel > 10 then
   print("fuel level: "..fuelLevel)
   print("no fuel necessary at this time")
else
  turtle.select(fuel)
  print("...refueling")
  turtle.refuel(fuelIncrement)
  print("fuel level: "..fuelLevel)
end
end
local function selectSeed()
turtle.select(seedCompare)
print("compare to slot: "..seedCompare)
local seeds = seedCompare + 1
repeat
  turtle.compareTo(seeds)
  print("comparing to slot: "..seeds)
  seeds = seeds + 1
until turtle.compareTo(seeds) == true

if turtle.compareTo(seeds) == true then
  print("seeds found in slot: ".. seeds)
  return turtle.select(seeds)
else
  print("no seeds in inventory")
end
end

local function harvest()
turtle.digDown()
end
local function plant()
turtle.placeDown()
end
function harvestRow()
-- combines harvesting, planting, and movement for a whole row

  selectSeed()
  print("selected inventory")


for start = 1, rowSize do
  turtle.forward() -- move to first block
  print("moved forward")
  harvest() -- harvest the block
  print("harvested wheat")
  plant()
  print("planted seed")
end

  turtle.forward() -- otherwise standing over last seed placed
end
function newRowEven()
-- move on to the next row

print("starting a new row")
checkOrientation()

turtle.forward() -- variable "skip" implies it is one row further away

for start=1, skip do
  turtle.forward()
end

-- turtle.turnLeft() -- now facing new row
checkOrientation()
end
function newRowOdd()
-- move on to the next row

print("starting a new row")
checkOrientation()
  turtle.forward() -- variable "skip" implies it is one row further away
for start=1, skip do
  turtle.forward()
end

checkOrientation()
end

-- function checkDistance()
-- local current = vector.new(gps.locate())
-- local travel = home - current
-- print("Traveled distance from origin: ")
-- print(travel)
-- return travel

-- end
function checkOrientation()
-- this should run the xyz comparison and determine the direction. If distance is over zero turn this way, if under 0 turn that way
local current = vector.new(gps.locate())
local travel = current - home
print("Traveled distance from origin: ")
print(travel)

  -- compares coordinates and sets turtle to turn away from origin while harvesting. need logic for when turtle is facing other directions, eg where x < 0

  if travel.x == 0 then
   if travel.z > 0 then
    turtle.turnLeft()
   elseif travel.z == 0 then
    -- do nothing, went nowhere
   end
  elseif travel.x > 0 then
   if travel.z > 0 then
    turtle.turnLeft()
   elseif travel.z == 0 then
    turtle.turnRight()
   end
  end
end
local function returnHome ()
-- get final gps location and compare to origin
local current = vector.new(gps.locate())
local travel = home - current -- haven't considered why I reversed this for the orientation logic, but I did and it works. This was original formula.

print("Traveled distance from origin: ")
print(travel)

-- similar to the check orientation above but built to turn turtle facing the right way to go to origin point

if travel.x > 0 then
  turtle.turnRight()
elseif travel.x < 0 then
  turtle.turnLeft()
elseif travel.x == 0 then
  turtle.turnLeft()
end

-- a set of loop variables to travel the difference
local xt, yt, zt = 0, 0, 0
-- travel logic

if travel.x > 0 then -- went east
  repeat
   turtle.forward()
   xt = xt + 1
  until xt == travel.x
elseif travel.x < 0 then -- went west
  repeat
   turtle.forward()
   xt = xt - 1
  until xt == travel.x
elseif travel.x == 0 then -- no change
  -- do nothing
else
  -- do nothing
end

if travel.y > 0 then -- went up
  repeat
   turtle.up()
   yt = yt + 1
  until yt == travel.y
elseif travel.y < 0 then -- went down
  repeat
   turtle.down()
   yt = yt - 1
  until yt == travel.y
elseif travel.y == 0 then -- no change
  -- do nothing
else
  -- do nothing
end

if travel.z > 0 then -- went south
  repeat
   turtle.forward()
   zt = zt + 1
  until zt == travel.z

elseif travel.z < 0 then -- went north
  repeat
   turtle.back()
   zt = zt - 1
  until zt == travel.z
elseif travel.z == 0 then -- no change
  -- do nothing
else
  -- do nothing
end

-- same idea as above, but making orientation correct for next run

if travel.x > 0 then
  turtle.turnRight()
elseif travel.x < 0 then
  turtle.turnLeft()
elseif travel.x == 0 then
  -- nothing
end

end -- end returnHome
-- PROGRAM
while true do
fuelCheck() -- check fuel level

for r = 1, rows do

  harvestRow()

  r = r + 1

  if r == 2 then -- would like a math check to see if even or odd, to handle better
   newRowEven()
  elseif r == 3 then
   newRowOdd()
  elseif r == 4 then
   newRowEven()
  end

end


returnHome() -- go to origin

print("waiting for wheat to grow")
sleep(2400)
end
Lyqyd #2
Posted 20 March 2013 - 04:00 AM
Split into new topic.
erima #3
Posted 20 March 2013 - 08:52 AM
Just a thought: could it be rain? There's nothing in the program that would check against a bad GPS location due to reduced broadcast distance.
erima #4
Posted 22 March 2013 - 08:13 AM
I've rewritten much of this program and it seems to work reliably. I gutted out the parts that dealt with placing the turtle in a different direction and getting the orientation correct, and hardcoded a few more turtle.forward() commands to make it work. I also can say that rain was not a factor (I have a host set up at max Y level above village well) after watching many cycles of this program run. The wild wandering I attribute to it being *just* out of my chunk loader range and so when it ran upon my return it did a startup from the middle of the field. There was also so bad code that made it fly but that's been cut.

Right now I'm trying to clean up the code and provide helpful error messages. But I do have one thing that has stumped me. When it finishes it's wheat harvesting it should be at a distance of X: 9, Z: 0 (remember it is programmed to harvest wheat from village fields).

In the function returnHome() I print "goin' home" and then do a little for loop to go in the correct direction. The thing is that this consistently prints the message and coordinates at X:6, Z: 0. It should hit the end of that row and then run returnHome() but it seems that it is turning left, going three blocks, and then running it. I tried reducing the number of times it performed the rows but it gets stranded at X:9, Z: 8. I also tried to leave out the final checkOrientation() call by comparing it to the distance. Neither worked for me. Any thoughts?


-- current location and known gps points
local home = vector.new(gps.locate())
-- local refill = vector.new(0, 0, 0) -- replace with gps of inventory to get stock
-- local refuel = vector.new(0, 0, 0) -- replace with gps of inventory to get fuel
-- local dump = vector.new(0, 0, 0) -- replace with gps of inventory to dump to
-- item slots used to compare against inventory and produce
local fuel = 1
local seedCompare = 2
local wheatCompare = 3
local dirtCompare = 4
-- configuration
local fuelIncrement = 2 -- the amount of item to use to refuel
local rowSize = 7 -- the distance to plant and sow, this is size of village row
local rows = 4 -- the number of rows to plant KEEP EVEN
local frequency = 3 -- When to start next row, skipping the blocks between
local totalDistance = (rows - 1) * frequency -- X, Z coordinates are 0 for first row
-- FUNCTIONS

local function fuelCheck() -- check fuel level
print("checking fuel levels...")
local fuelLevel = turtle.getFuelLevel()
-- refuel if necessary
if fuelLevel > 50 then
  print("fuel level: "..fuelLevel)
  print("no fuel necessary at this time")
elseif turtle.getItemCount(fuel) < 2 then
  error("No fuel source")
else
  turtle.select(fuel)
  print("...refueling")
  turtle.refuel(fuelIncrement)
  print("fuel level: "..fuelLevel)
end
end
local function selectSeed()
turtle.select(seedCompare)
-- print("compare to slot: "..seedCompare)
local seeds = seedCompare + 1


while turtle.compareTo(seeds) ~= true do
  turtle.compareTo(seeds)
  -- print("comparing to slot: "..seeds)
  seeds = seeds + 1
 
  if (turtle.compareTo(seeds) == 16) and (turtle.compareTo(seeds) ~= true) then
   error("no seeds in inventory")
  end
end
  print("seeds found in slot: ".. seeds)
  return turtle.select(seeds)

end
local function harvest()
turtle.digDown()
end
local function plant()
turtle.placeDown()
end
 
local function checkOrientation()
-- this should run the xyz comparison and determine the direction. If distance is over zero turn this way, if under 0 turn that way
local current = vector.new(gps.locate())
local travel = current - home
-- compares coordinates and sets turtle to turn away from origin while harvesting. need logic for when turtle is facing other directions, eg where x < 0


  if (travel.x > 0) and (travel.z == 0) then
  
   -- The coordinate should not exceed the number of rows (and frequency)
  
   if travel.x ~= totalDistance then
    turtle.turnRight()	
   else
    turtle.turnLeft()
   end
  elseif (travel.x == 0) and (travel.z > 0) then
   -- the first turn only
   turtle.turnLeft()
  elseif (travel.x > 0) and (travel.z > 0) then
   turtle.turnLeft()
  elseif
   (travel.x == 0) and (travel.z == 0) then
   turtle.turnLeft()
  end
   
end

local function harvestRow()
-- combines harvesting, planting, and movement for a whole row

  selectSeed()
  -- print("selected inventory")
 
 
for start = 1, rowSize do  
  turtle.forward() -- move to first block
  -- print("moved forward")
  harvest() -- harvest the block
  -- print("harvested wheat")
  plant()
  -- print("planted seed")
end

print("harvest and seeding sucessful")

turtle.forward() -- otherwise standing over last seed placed

end


local function newRow()
-- move on to the next row
print("starting a new row")

 
for start=1, frequency do
  turtle.forward()
end
end
local function returnHome ()
local current = vector.new(gps.locate())
local homeDistance = home - current
print("Goin home: ")
print(homeDistance)

i = 0
while i > homeDistance.x do
  turtle.forward()
  i = i - 1
end
turtle.turnLeft()

end -- end returnHome
-- PROGRAM -------------------------------------------
while true do
fuelCheck() -- check fuel level

  r = 1
  while r <= rows do

  harvestRow()
  checkOrientation()
  newRow()
  if r ~= rows then
   checkOrientation()
  end
  r = r + 1
end
  
  returnHome()
   print("waiting for wheat to grow")
   sleep(2400)
end