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

I'm new here. Have my position tracking script I just started

Started by Izodn, 03 April 2013 - 04:07 PM
Izodn #1
Posted 03 April 2013 - 06:07 PM
I'm giving it out, because I couldn't find one. I just started this today, but I don't think there are very many issues with it.

This little script starts off by asking the turtle's current location, and stores it as .txt files.
To have movements reflected in this script you would use "forward()", "turn("south")", "turn("north")", "turn("east")", "turn("west")", "up()", and finally "down()"

Note: This script's movements are "descructive" (The turtle will destroy nearly everything to get from point A to point B)/>/>/>.

I'm updating the code most procedural AI tasks (ie. tree farming, mining, quarry building, etc), but this is only a start.
Lua is a new language to me, so if you've got tips, I'd love to hear.

details:
getPos() = get the position of turtle as table

setPos(table) = set position after movement the inputted numbers must be a table

forward() = move turtle forward (Note: it's destructive) and track position

turn("north") = turn, reflect this turn in forward and facing.txt
turn("south") = turn, reflect this turn in forward and facing.txt
turn("west") = turn, reflect this turn in forward and facing.txt
turn("east") = turn, reflect this turn in forward and facing.txt

the homeX, homeY, homeX, xPos, yPos, zPos, and facing are all stored in the root of the turtle's folder as .txt files.

I've also just added the ability to "go home"

To test this, save this file as "directions" and run it 5-or-so times. Now run "directions goHome" to watch the turtle make it back.

Spoiler

--[[  
	getFacing() SETTINGS:
	NORTH = 0
	EAST = 1
	SOUTH = 2
	WEST = 3
--]]
--[[ START POS FUNCTIONS --]]
local args = {...}
local curPos = {}
local dir = "positionTracking/"
if not shell.run("mkdir positionTracking") then
end
function checkPos()
	file  = io.open(dir.."curPos.txt","r")
	if file == nil then
		return false
	end
	pos = file:read()
	posTable = textutils.unserialize(pos)
	if not posTable then
		print("The coords file is a bit weird. Can't load from it.")
		file:close()
		return false
	end
	file:close()
	return true
end
function setPos(pos)
	file = io.open(dir.."curPos.txt", "w")
	pos = textutils.serialize(pos)
	file:write(pos)
	file:close()
end
function getPos()
	file  = io.open(dir.."curPos.txt", "r")
	pos = file.read("*all")
	posTable = textutils.unserialize(pos)
	if not posTable then
		print("The coords file is a bit weird. Can't load from it.")
	end
	posTable[1] = tonumber(posTable[1])
	posTable[2] = tonumber(posTable[2])
	posTable[3] = tonumber(posTable[3])
	file:close()
	return(posTable)
end
function clearPos()
	file = io.open(dir.."curPos.txt","w") 	
	file:write("")
	file:close()
end
--[[ STOP POS FUNCTIONS --]]
--[[ START HOME FUNCTIONS --]]
function checkHome()	
	file  = io.open(dir.."homePos.txt","r")
	if file == nil then
		return false
	end
	pos = file:read()
	posTable = textutils.unserialize(pos)
	if not posTable then
		print("The coords file is a bit weird. Can't load from it.")
		file:close()
		return false
	end
	file:close()
	return true
end
function setHome(pos)
	file = io.open(dir.."homePos.txt", "w")
	pos = textutils.serialize(pos)
	file:write(pos)
	file:close()
end
function getHome()
	file  = io.open(dir.."homePos.txt", "r")
	pos = file.read("*all")
	posTable = textutils.unserialize(pos)
	if not posTable then
		print("The coords file is a bit weird. Can't load from it.")
	end
	posTable[1] = tonumber(posTable[1])
	posTable[2] = tonumber(posTable[2])
	posTable[3] = tonumber(posTable[3])
	file:close()
	return(posTable)
end
function clearHome()
	file = io.open(dir.."homePos.txt","w") 	
	file:write("")
	file:close()
end
--[[ STOP HOME FUNCTIONS --]]
--[[ START FACING FUNCTIONS --]]
function checkFacing()
	file = io.open(dir.."facing.txt","r")
	if not file then
		return false
	end
	file:close()
	return true
end
function setFacing(facing)
	file = io.open(dir.."facing.txt","w") 	
	file:write(facing)
	file:close()
end
function getFacing()
	if not checkFacing() then
		return false
	end
	file = io.open(dir.."facing.txt", "r")
	facing = file:read()
	file:close()
	facing = tonumber(facing)
	return(facing)
end
function clearFacing()
	file = io.open(dir.."facing.txt","w") 	
	file:write("")
	file:close()
end
--[[ STOP FACING FUNCTIONS --]]
function turn(direction)
	if direction == "north" then
		toFace = 0
	elseif direction == "east" then
		toFace = 1
	elseif direction == "south" then
		toFace = 2
	elseif direction == "west" then
		toFace = 3
	end
	facing = tonumber(getFacing())
	while facing ~= toFace do
		turtle.turnRight()
		facing = facing+1
		if facing == 4 then
			facing = 0
		end
	end
	setFacing(toFace)
end
function forward()
	facing = getFacing()
	pos = getPos()
	x = pos[1]
	z = pos[2]
	y = pos[3]
	if facing == 0 then
		z=z-1
	elseif facing == 1 then
		x=x+1
	elseif facing == 3 then
		x=x-1
	elseif facing == 2 then
		z=z+1
	end
	pos = {x, z, y}
	setPos(pos)
	while not turtle.forward() do
		turtle.dig()
	end
end
function down()
	pos = getPos()
	x = pos[1]
	z = pos[2]
	y = pos[3]
	y = y-1
	pos = {x, z, y}
	setPos(pos)
	while not turtle.down() do
		turtle.digDown()
	end
end
function up()
	pos = getPos()
	x = pos[1]
	z = pos[2]
	y = pos[3]
	y = y+1
	pos = {x, z, y}
	setPos(pos)
	while not turtle.up() do
		turtle.digUp()
	end
end
function goHome()
	if not checkHome() then
		print("Problem getting Home")
		return false
	end
	if not checkPos() then
		print("Problem getting Position")
		return false
	end
	print("Retrived cords, moving now.")
	home = getHome()
	homeX = home[1]
	homeZ = home[2]
	homeY = home[3]
	homeR = home[4]
	pos = getPos()
	posX = pos[1]
	posZ = pos[2]
	posY = pos[3]
	facing = getFacing()
	while posY < homeY do
		up()
		pos = getPos()
		posY = pos[3]
	end
	while posY > homeY do
		down()
		pos = getPos()
		posY = pos[3]
	end
	while posX < homeX do
		turn("east")
		forward()
		pos = getPos()
		posX = pos[1]
	end
	while posX > homeX do
		turn("west")
		forward()
		pos = getPos()
		posX = pos[1]
	end
	while posZ < homeZ do
		turn("south")
		forward()
		pos = getPos()
		posZ = pos[2]
	end
	while posZ > homeZ do
		turn("north")
		forward()
		pos = getPos()
		posZ = pos[2]
	end
	if homeR == 0 then
		turn("north")
	elseif homeR == 1 then
		turn("east")
	elseif homeR == 2 then
		turn("south")
	elseif homeR == 3 then
		turn("west")
	end
	print("I am at home")
end
function main()
	if not getFacing() or getFacing() == "" then
		print("What direction am I facing?")
		print("ie. north, east, south, west")
		write("")
		facing = read()
		if facing == "north" then
			toFace = 0
		elseif facing == "east" then
			toFace = 1
		elseif facing == "south" then
			toFace = 2
		elseif facing == "west" then
			toFace = 3
		end
		setFacing(toFace)
	end
	if not checkHome() then
		print("What is my X position?")
		write("")
		curXPos = tonumber(read())
		print("What is my Z position?")
		write("")
		curZPos = tonumber(read())
		print("What is my Y position?")
		write("")
		curYPos = tonumber(read())
		face = tonumber(getFacing())
		home = {curXPos, curZPos, curYPos, face}
		setHome(home)
	end
	if not checkPos() then
		home = getHome()
		xPos = home[1]
		zPos = home[2]
		yPos = home[3]
		pos = {xPos, zPos, yPos}
		setPos(pos)
	end
	--[[ Begin optional testing code --]]
	forward()
	forward()
	forward()
	forward()
	down()
	down()
	turn("east")
	forward()
	forward()
	up()
	turn("south")
	pos = getPos()
	posX = pos[1]
	posZ = pos[2]
	posY = pos[3]
	home = getHome()
	homeX = home[1]
	homeZ = home[2]
	homeY = home[3]
	print("My Position:")
	print("X="..posX..", Z="..posZ..", Y="..posY.."")
	print("My Home:")
	print("X="..homeX..", Z="..homeZ..", Y="..homeY.."")
	--[[ End optional testing code --]]
end
if args[1] and args[1] == "goHome" then
	goHome()
else
	main()
end
http://pastebin.com/2DJPAtYp

you can get this code onto your bot via "pastebin get 2DJPAtYp (name your file)" inside the turtle's/computer's console.

Edit: Friendly people let me know about code and spoiler tags.
Edit2: I've rewritten a good portion. Thanks to Bubba, I've added in tables to simplify, and make less resource intensive.

Hopefully this is turning out to be something :P/>/>
theoriginalbit #2
Posted 03 April 2013 - 06:11 PM
Please put your code inside [code][/code] tags and [spoiler][/spoiler] tags or just post it as a link to pastebin (which i noticed you have down the bottom, but make a clickable one too) instead of posting all the code in the thread. Also a bit of a description of what exactly it does and how to use it would go a long way towards people using this :)/>
Bubba #3
Posted 03 April 2013 - 06:11 PM
You damn ninja's.

SpoilerSuggestion: Use code tags like so:
[.code]
your code here
[/.code]

But remove the periods. Here's an example of how much better it looks:

local test = "1234"
print(test)

for i,v in pairs({1,2,3,4}) do
   print("Index: "..i.."   Value: "..v)
end
Izodn #4
Posted 03 April 2013 - 06:35 PM
Thanks! I've edited the post to be better.
Bubba #5
Posted 03 April 2013 - 06:47 PM
Much better. Thanks for that! :)/>

Your code looks pretty good, but I see that you store the x,y,z coordinates in different files, one for each variable. It would be much easier to store things in a table, although that would require rewriting a few sections.
Example:

local coords = {
x=0, y=0, z=0
}

local function store_coords()
  local f = fs.open("coords.txt", "w")
  f.write(textutils.serialize(coords)) --textutils.serialize will convert a table into string form so you can save it to the file. textutils.unserialize will revert it to a table
  f.close()
end

local function checkCoords() --Much easier than having to load up each file
  if not fs.exists("coords.txt") then
	return false
  end
  local f  = fs.open("coords.txt", "r")
  local content = f.readAll()
  local table_content = content.unserialize(content)
  if table_content then --Just make sure that it's a valid stored table before we overwrite anything
	coords = table_content
  else
	print("The coords file is a bit weird. Can't load from it.")
  end
end

checkCoords()

-- and so on

The same can go for setting a home. I'm not sure if you're familiar with how tables work, but they could simplify a good number of things for you.
superaxander #6
Posted 03 April 2013 - 07:55 PM
This is you're first program O.o
theoriginalbit #7
Posted 03 April 2013 - 07:56 PM
This is you're first program O.o
Not everyone starts with door locks or OSes :P/>
superaxander #8
Posted 03 April 2013 - 08:00 PM
Well I started with a program that showed a tutorial on how to make programs in Lua and VB.NET
Izodn #9
Posted 04 April 2013 - 04:29 AM
This is you're first program O.o
Not my first program. I've rewritten excavate to be "more" as well as a few rednet things. This is just my first revision of this.



Much better. Thanks for that! :)/>

Your code looks pretty good, but I see that you store the x,y,z coordinates in different files, one for each variable. It would be much easier to store things in a table, although that would require rewriting a few sections.
Example:

local coords = {
x=0, y=0, z=0
}

local function store_coords()
  local f = fs.open("coords.txt", "w")
  f.write(textutils.serialize(coords)) --textutils.serialize will convert a table into string form so you can save it to the file. textutils.unserialize will revert it to a table
  f.close()
end

local function checkCoords() --Much easier than having to load up each file
  if not fs.exists("coords.txt") then
	return false
  end
  local f  = fs.open("coords.txt", "r")
  local content = f.readAll()
  local table_content = content.unserialize(content)
  if table_content then --Just make sure that it's a valid stored table before we overwrite anything
	coords = table_content
  else
	print("The coords file is a bit weird. Can't load from it.")
  end
end

checkCoords()

-- and so on

The same can go for setting a home. I'm not sure if you're familiar with how tables work, but they could simplify a good number of things for you.

Thanks for that! I'll probably start work on that today, I'll see what I can upload later tonight.
Izodn #10
Posted 04 April 2013 - 07:54 AM
I've added some changed to the code, and thanks to Bubba, I've decided to use tables and one file per x, y, z to simplify things. I'm having a lot of fun programming this, so I uploaded it sooner :)/>
Bubba #11
Posted 04 April 2013 - 09:28 AM
It looks like you forgot to assign the unserialized table to curPos.

function checkPos()
		file  = io.open(dir.."curPos.txt","r")
		if file == nil then
				return false
		end
		pos = file:read()
		posTable = textutils.unserialize(pos) --[[textutils.serialize will convert a table into string form so you can save it to the file. textutils.unserialize will revert it to a table--]]
		if not posTable then --[[Just make sure that it's a valid stored table before we overwrite anything--]]
				print("The coords file is a bit weird. Can't load from it.")
				file:close()
				return false
		end
		file:close()
		-- You should have something along the lines of curPos = posTable here
		return true
end

Another suggestion I have is to insert these functions into the turtle table so that you can call them like "turtle.goHome()". Here's an example of how you might go about that:

local old_up = turtle.up --No parentheses. We're just linking a local function (old_up) to the old turtle.up. Then we'll override the turtle.up function

turtle.up = function()
   return old_up() --Just an example
   --I believe (although I'm not sure) that you can use turtle.native.up as well without having to save the turtle.up function
end

turtle.other_function()
   print("This is valid too. We don't have to override other functions")
end

All in all though, this is a pretty damn good job. Better than my first navigation API :)/>
Izodn #12
Posted 04 April 2013 - 11:31 AM
It looks like you forgot to assign the unserialized table to curPos.

function checkPos()
		file  = io.open(dir.."curPos.txt","r")
		if file == nil then
				return false
		end
		pos = file:read()
		posTable = textutils.unserialize(pos) --[[textutils.serialize will convert a table into string form so you can save it to the file. textutils.unserialize will revert it to a table--]]
		if not posTable then --[[Just make sure that it's a valid stored table before we overwrite anything--]]
				print("The coords file is a bit weird. Can't load from it.")
				file:close()
				return false
		end
		file:close()
		-- You should have something along the lines of curPos = posTable here
		return true
end

Another suggestion I have is to insert these functions into the turtle table so that you can call them like "turtle.goHome()". Here's an example of how you might go about that:

local old_up = turtle.up --No parentheses. We're just linking a local function (old_up) to the old turtle.up. Then we'll override the turtle.up function

turtle.up = function()
   return old_up() --Just an example
   --I believe (although I'm not sure) that you can use turtle.native.up as well without having to save the turtle.up function
end

turtle.other_function()
   print("This is valid too. We don't have to override other functions")
end

All in all though, this is a pretty damn good job. Better than my first navigation API :)/>

Thanks a lot for all of your suggestions! I will have to think more about how I would do the turtle table's functions. As for your first quote, I don't quite understand what you mean.
The checkPos() function is to just see if pos exists, return true if so, false if else.
Bubba #13
Posted 04 April 2013 - 12:10 PM
Thanks a lot for all of your suggestions! I will have to think more about how I would do the turtle table's functions. As for your first quote, I don't quite understand what you mean.
The checkPos() function is to just see if pos exists, return true if so, false if else.

Ah… Well why not combine that all into one function? Seems like it'd be easier.
FuuuAInfiniteLoop(F.A.I.L) #14
Posted 05 April 2013 - 02:25 PM
you should add tables to store and save everything, its much more easier:


save = {}
save.x = xpos
save.y = ypos
save.z = zpos
save.home = {}
save.home["x"] = xpos
save.home["y"] = ypos
save.home["z"] = zpos
--save
file = fs.open("save", "w")
file.write(textutils.serialize(save))
file.close
--load
file = fs.open("save", "r")
save = textutils.,unserialize(file.readLine())
file.close()
--getvars
xpos = save.x
homey = save.home["y"]
--and so on