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

Turtle turning to a certain direction

Started by popdog15, 09 May 2015 - 04:44 AM
popdog15 #1
Posted 09 May 2015 - 06:44 AM
All right. I'm working on a to be storage program that counts items and can pull them out of storage using a network of turtles. So far I have written a framework for the turtle, and after that I will be writing a server and client. My turtle code is currently: Code

My problem lies at line 257 and later upon calling it at 277. I'm telling the turtle to get an item to the east when it's facing north, and in theory, it should just turn left 3 times and then stop, but it doesn't. It just keeps on turning no matter what. No idea why. Maybe the current 'pos' is not accurate? I don't know.



Previous issue that is resolved.
SpoilerI'm working on a (to be) ticker program to count off my resources, store them, etc. I'm going to have the turtles pull items out of nearby barrels so I don't have to worry about fuel and then transport them through an enderchest. Now what I'm working on right now is a very basic framework for the turtle to: 1. Remember it's position and orientation even with server restarts. 2. Have an easy method of controlling the turtle while still remembering it's position. Right now I'm working on the turning of the turtle, and after that is when I will be working on the server and other client portion of this project. I believe my problem lies in the fs.flush function but I can't seem to find proper documentation to figure out whether or not I'm using the proper syntax, but there are no errors with the program. It outputs "It exists, friend." as in the 'pos' file does, but it does not turn like I would expect it to with the test calls of the changeTurtle function at the end. No "written" is output, no turning occurs. No idea what's going on. Ideas would be appreciated, as well as if you have any ideas on how to optimize the code - I know in the turning function that could be worked out differently and more efficiently but I'm tired and my brain couldn't think of anything but to copy/paste and change the minor details.

Spoiler

-- This is the turtle client code.


-- Just some prerequisite stuff.
rednet.open("left")
-- Reading, or if needed, creating the position file.
function getPosition()
if fs.exists("pos") == true then
  print("It exists, friend.")
  pos = fs.open("pos","r")
  -- Putting the turtle on the games grid
  x = pos.readLine()
  y = pos.readLine()
  z = pos.readLine()
  -- values are as following: 1, west. 2, north. 3, east. 4, south
  f = pos.readLine()
  pos.close()
else
  -- Getting the input Coords.
  pos = fs.open("pos", "w")
  print("Insert the current X, Y, Z, and F (Direction facing value.) respectively.")
  write("X: ")
  local inpX = read()
  write("Y: ")
  local inpY = read()
  write("Z: ")
  local inpZ = read()
  write("F: ")
  local inpF = read()

  -- Writing the input coords.
  pos.writeLine(inpX)
  pos.writeLine(inpY)
  pos.writeLine(inpZ)
  pos.writeLine(inpF)
  pos.close()
end
end
function changeTurtle(func, var)
-- Both changing the position and writing the new one to the 'pos' file.

-- exclusively for turning the turtle
local function turtleTurn(turnD)
  -- turnD is either 'l' or 'r', simply for left or right.
  if f == "1" and turnD == "r" then
   getPosition()
   turtle.turnRight()
   f = 2
   pos = fs.open("pos","a")
   pos.flush()
   pos.writeLine(x)
   pos.writeLine(y)
   pos.writeLine(z)
   pos.writeLine(newF)
   pos.close()
   print("Written.")
  elseif f == "1" and turnD == "l" then
   getPosition()
   turtle.turnLeft()
   f = 4
   pos = fs.open("pos","a")
   pos.flush()
   pos.writeLine(x)
   pos.writeLine(y)
   pos.writeLine(z)
   pos.writeLine(newF)
   pos.close()
   print("Written.")
  elseif f == "4" and turnD == "r" then
   getPosition()
   turtle.turnRight()
   f = 1
   pos = fs.open("pos","a")
   pos.flush()
   pos.writeLine(x)
   pos.writeLine(y)
   pos.writeLine(z)
   pos.writeLine(newF)
   pos.close()
   print("Written.")
  elseif f == "4" and turnD == "l" then
   getPosition()
   turtle.turnLeft()
   f = 3
   pos = fs.open("pos","a")
   pos.flush()
   pos.writeLine(x)
   pos.writeLine(y)
   pos.writeLine(z)
   pos.writeLine(newF)
   pos.close()
   print("Written.")
  elseif f == "3" and turnD == "r" then
   getPosition()
   turtle.turnRight()
   f = 4
   pos = fs.open("pos","a")
   pos.flush()
   pos.writeLine(x)
   pos.writeLine(y)
   pos.writeLine(z)
   pos.writeLine(newF)
   pos.close()
   print("Written.")
  elseif f == "3" and turnD == "l" then
   getPosition()
   turtle.turnLeft()
   f = 2
   pos = fs.open("pos","a")
   pos.flush()
   pos.writeLine(x)
   pos.writeLine(y)
   pos.writeLine(z)
   pos.writeLine(newF)
   pos.close()
   print("Written.")
  elseif f == "2" and turnD == "r" then
   getPosition()
   turtle.turnRight()
   f = 3
   pos = fs.open("pos","a")
   pos.flush()
   pos.writeLine(x)
   pos.writeLine(y)
   pos.writeLine(z)
   pos.writeLine(newF)
   pos.close()
   print("Written.")
  elseif f == "2" and turnD == "l" then
   getPosition()
   turtle.turnLeft()
   f = 1
   pos = fs.open("pos","a")
   pos.flush()
   pos.writeLine(x)
   pos.writeLine(y)
   pos.writeLine(z)
   pos.writeLine(newF)
   pos.close()
   print("Written.")
  end

  if func == "tturn" then
  
   turtleTurn(var)
  end
end
end
getPosition()
--serverCall()
-- test turns
sleep(1)
changeTurtle("tturn", "l")
sleep(1)
changeTurtle("tturn", "r")
sleep(1)
changeTurtle("tturn", "r")
Edited on 10 May 2015 - 05:56 AM
Creator #2
Posted 09 May 2015 - 08:57 AM
You don't need to flush. Closing files is enough.
Bomb Bloke #3
Posted 09 May 2015 - 09:09 AM
Flush simply ensures that any data you've queued to be written to disk, gets written to disk before the script goes any further. Normally data you've requested be written goes into a buffer to be actually written when the VM thinks it's worth kicking the HDD into action (sending one big write request is more efficient than ordering lots of little ones). Closing a file automatically flushes it, but, in cases where you think your script might crash in between your write commands and your close call, you can request it manually. Of course, if you've simply opened the file and haven't made any write calls yet, flushing does nothing (and in cases where you're closing the files directly after ordering writes, it effectively does nothing).

It seems you never define "newF". The fourth line of your "pos" file will quickly become blank, and "f" will thus become an empty string.

Frankly my recommendation is to forget about having your turtles "remember" their states in between boots, and simply code them to figure it out each time they boot up based on a GPS setup. There's no point in flogging your hard drive when you'll never move out of range of a satellite system.

Here's an example of the sort of code most all of my turtle scripts execute on startup:

local pos, facings = {}, {"north","east","south","west"}

-- Ping the GPS servers until I get a valid reading:
do
        local tempx, tempy, tempz
        while tempx == nil or tempy == nil or tempz == nil do
                tempx, tempy, tempz = gps.locate(5)
                sleep(5)
        end

        while not turtle.forward() do while not turtle.turnLeft() do end end
        pos.x,pos.y,pos.z = gps.locate(5)

        if pos.x < tempx then pos.direction = 4
        elseif pos.x > tempx then pos.direction = 2
        elseif pos.z < tempz then pos.direction = 1
        else pos.direction = 3 end
end

print("I'm at "..pos.x..","..pos.y..","..pos.z..", I have "..turtle.getFuelLevel().." fuel and I'm facing "..facings[pos.direction]..".")

I then just have them update the variables in the pos table as they move around.
popdog15 #4
Posted 09 May 2015 - 04:28 PM
Flush simply ensures that any data you've queued to be written to disk, gets written to disk before the script goes any further. Normally data you've requested be written goes into a buffer to be actually written when the VM thinks it's worth kicking the HDD into action (sending one big write request is more efficient than ordering lots of little ones). Closing a file automatically flushes it, but, in cases where you think your script might crash in between your write commands and your close call, you can request it manually. Of course, if you've simply opened the file and haven't made any write calls yet, flushing does nothing (and in cases where you're closing the files directly after ordering writes, it effectively does nothing).

It seems you never define "newF". The fourth line of your "pos" file will quickly become blank, and "f" will thus become an empty string.

Frankly my recommendation is to forget about having your turtles "remember" their states in between boots, and simply code them to figure it out each time they boot up based on a GPS setup. There's no point in flogging your hard drive when you'll never move out of range of a satellite system.

Here's an example of the sort of code most all of my turtle scripts execute on startup:

local pos, facings = {}, {"north","east","south","west"}

-- Ping the GPS servers until I get a valid reading:
do
		local tempx, tempy, tempz
		while tempx == nil or tempy == nil or tempz == nil do
				tempx, tempy, tempz = gps.locate(5)
				sleep(5)
		end

		while not turtle.forward() do while not turtle.turnLeft() do end end
		pos.x,pos.y,pos.z = gps.locate(5)

		if pos.x < tempx then pos.direction = 4
		elseif pos.x > tempx then pos.direction = 2
		elseif pos.z < tempz then pos.direction = 1
		else pos.direction = 3 end
end

print("I'm at "..pos.x..","..pos.y..","..pos.z..", I have "..turtle.getFuelLevel().." fuel and I'm facing "..facings[pos.direction]..".")

I then just have them update the variables in the pos table as they move around.
Oh. I thought it flush purged the file of it's contents. I changed it around so that it deletes the 'pos' file every time and just re-writes it, and with that, it works now.
Edited on 09 May 2015 - 02:29 PM
valithor #5
Posted 09 May 2015 - 04:48 PM
Flush simply ensures that any data you've queued to be written to disk, gets written to disk before the script goes any further. Normally data you've requested be written goes into a buffer to be actually written when the VM thinks it's worth kicking the HDD into action (sending one big write request is more efficient than ordering lots of little ones). Closing a file automatically flushes it, but, in cases where you think your script might crash in between your write commands and your close call, you can request it manually. Of course, if you've simply opened the file and haven't made any write calls yet, flushing does nothing (and in cases where you're closing the files directly after ordering writes, it effectively does nothing).

It seems you never define "newF". The fourth line of your "pos" file will quickly become blank, and "f" will thus become an empty string.

Frankly my recommendation is to forget about having your turtles "remember" their states in between boots, and simply code them to figure it out each time they boot up based on a GPS setup. There's no point in flogging your hard drive when you'll never move out of range of a satellite system.

Here's an example of the sort of code most all of my turtle scripts execute on startup:

local pos, facings = {}, {"north","east","south","west"}

-- Ping the GPS servers until I get a valid reading:
do
		local tempx, tempy, tempz
		while tempx == nil or tempy == nil or tempz == nil do
				tempx, tempy, tempz = gps.locate(5)
				sleep(5)
		end

		while not turtle.forward() do while not turtle.turnLeft() do end end
		pos.x,pos.y,pos.z = gps.locate(5)

		if pos.x < tempx then pos.direction = 4
		elseif pos.x > tempx then pos.direction = 2
		elseif pos.z < tempz then pos.direction = 1
		else pos.direction = 3 end
end

print("I'm at "..pos.x..","..pos.y..","..pos.z..", I have "..turtle.getFuelLevel().." fuel and I'm facing "..facings[pos.direction]..".")

I then just have them update the variables in the pos table as they move around.
Oh. I thought it flush purged the file of it's contents. I changed it around so that it deletes the 'pos' file every time and just re-writes it, and with that, it works now.

Just so you know by opening a file in write mode using the fs api (fs.open(file,"w")) it will delete the contents automatically. The only reason the contents are not being deleted when you open it is because you are using append mode which adds the information to the end.

So instead of deleting the file you can just do this:

local h = fs.open(file,"w") -- because it is opened in "w" mode it will delete all contents
h.writeLine(stuff)
h.close()

Append mode or "a" mode will just add whatever you want to write to the end of the file.
popdog15 #6
Posted 09 May 2015 - 05:31 PM
Flush simply ensures that any data you've queued to be written to disk, gets written to disk before the script goes any further. Normally data you've requested be written goes into a buffer to be actually written when the VM thinks it's worth kicking the HDD into action (sending one big write request is more efficient than ordering lots of little ones). Closing a file automatically flushes it, but, in cases where you think your script might crash in between your write commands and your close call, you can request it manually. Of course, if you've simply opened the file and haven't made any write calls yet, flushing does nothing (and in cases where you're closing the files directly after ordering writes, it effectively does nothing).

It seems you never define "newF". The fourth line of your "pos" file will quickly become blank, and "f" will thus become an empty string.

Frankly my recommendation is to forget about having your turtles "remember" their states in between boots, and simply code them to figure it out each time they boot up based on a GPS setup. There's no point in flogging your hard drive when you'll never move out of range of a satellite system.

Here's an example of the sort of code most all of my turtle scripts execute on startup:

local pos, facings = {}, {"north","east","south","west"}

-- Ping the GPS servers until I get a valid reading:
do
		local tempx, tempy, tempz
		while tempx == nil or tempy == nil or tempz == nil do
				tempx, tempy, tempz = gps.locate(5)
				sleep(5)
		end

		while not turtle.forward() do while not turtle.turnLeft() do end end
		pos.x,pos.y,pos.z = gps.locate(5)

		if pos.x < tempx then pos.direction = 4
		elseif pos.x > tempx then pos.direction = 2
		elseif pos.z < tempz then pos.direction = 1
		else pos.direction = 3 end
end

print("I'm at "..pos.x..","..pos.y..","..pos.z..", I have "..turtle.getFuelLevel().." fuel and I'm facing "..facings[pos.direction]..".")

I then just have them update the variables in the pos table as they move around.
Oh. I thought it flush purged the file of it's contents. I changed it around so that it deletes the 'pos' file every time and just re-writes it, and with that, it works now.

Just so you know by opening a file in write mode using the fs api (fs.open(file,"w")) it will delete the contents automatically. The only reason the contents are not being deleted when you open it is because you are using append mode which adds the information to the end.

So instead of deleting the file you can just do this:

local h = fs.open(file,"w") -- because it is opened in "w" mode it will delete all contents
h.writeLine(stuff)
h.close()

Append mode or "a" mode will just add whatever you want to write to the end of the file.
Oh. All righty then, thanks.
Edited on 09 May 2015 - 03:31 PM
popdog15 #7
Posted 10 May 2015 - 07:59 AM
Bump as of edit? (If allowed?)
Edited on 10 May 2015 - 05:59 AM
flaghacker #8
Posted 10 May 2015 - 08:32 AM
Bump as of edit? (If allowed?)

Pleaso don't edit your original post, just write a new one. It's going to become a mess like this.
Edited on 10 May 2015 - 06:32 AM
popdog15 #9
Posted 10 May 2015 - 09:11 AM
Bump as of edit? (If allowed?)

Pleaso don't edit your original post, just write a new one. It's going to become a mess like this.
I thought this was better than flooding the "Ask a Pro" board, but all right.
flaghacker #10
Posted 10 May 2015 - 10:01 AM
Bump as of edit? (If allowed?)

Pleaso don't edit your original post, just write a new one. It's going to become a mess like this.
I thought this was better than flooding the "Ask a Pro" board, but all right.

No no, don't flood the Ask a pro board! I meant that you should post a new reply to this topic. Something like
Thanks, my problem is resolved! But now I'm getting this error:
Edited on 10 May 2015 - 08:01 AM
Bomb Bloke #11
Posted 10 May 2015 - 12:04 PM
My problem lies at line 257 and later upon calling it at 277. I'm telling the turtle to get an item to the east when it's facing north, and in theory, it should just turn left 3 times and then stop, but it doesn't. It just keeps on turning no matter what. No idea why. Maybe the current 'pos' is not accurate? I don't know.

So around line 257, we have:

function figureOutTurn(newf)
        while f ~= newf do
        turtle.turnLeft()
        end
end

… a loop that'll repeat so long as f isn't newf. And since it never bothers to change those variables, it's indeed going to keep going for quite a while…

Did you intend to call your changeTurtle() function from there?
popdog15 #12
Posted 10 May 2015 - 04:08 PM
My problem lies at line 257 and later upon calling it at 277. I'm telling the turtle to get an item to the east when it's facing north, and in theory, it should just turn left 3 times and then stop, but it doesn't. It just keeps on turning no matter what. No idea why. Maybe the current 'pos' is not accurate? I don't know.

So around line 257, we have:

function figureOutTurn(newf)
		while f ~= newf do
		turtle.turnLeft()
		end
end

… a loop that'll repeat so long as f isn't newf. And since it never bothers to change those variables, it's indeed going to keep going for quite a while…

Did you intend to call your changeTurtle() function from there?
Oh, yeah, that'd be the problem. I'm silly sometimes, thanks.