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

[1.3] Turtle Wifi Remote Control Software

Started by vvenaya, 25 February 2012 - 10:39 AM
vvenaya #1
Posted 25 February 2012 - 11:39 AM
DESCRIPTION
This software when placed in the startup of a turtle, allows the turtle to be controlled via Rednet wireless. It is smart enough to send complext sequences of commands in one go.


USAGE
once the software is running on the turtle, it can be controlled by sending character sequences to the turtle via rednet.
once the turtle has done the command sequence, it sends bot/done back to the computer the send the commands


SYNTAX
The turtle accepts commands seperated by the / character. Commands can have parameters added, by adding a double-point seperator ( :P/>/> and the parameters following it


COMMANDS

D = Down Optional parameter: number of times to go down (default:1)
U = Up Optional parameter: number of times to go up (default:1)
R = Turn Rignt Optional parameter: number of times to go right (default:1)
L = Turn Left Optional parameter: number of times to go left (default:1)
F = Move Forward Optional parameter: number of times to go forward (default:1)
B = Move Back Optional parameter: number of times to go back (default:1)
PL = place a block Optional parameters: 1 parameter: slot in inventory to use 2nd parameter: up/down/left/right for placing up/down/left/right (ex. PL:1:down)
DG break a block Optional parameters: 1 parameter: slot in inventory to use 2nd parameter: up/down/left/rightfor digging up/down/left/right (ex. DG:2:down = digs the block above and puts the content in slot 2 of the bots inventory)
REP Repeat a number of commands a number of times Syntax: REP:<number of times>:[commandsTobeRepeated]



EXAMPLES


send with : rednet.send(TurtleID,"commands here")

u:3/f/pl/d:3 = Go up 3 times, then go forward, and place a block, then go down 3 times

rep:3:[u/pl] = makes a pillar of 3 blocks

rep:3:[rep:3:[u/pl]/d:3/r/f/l] = makes a 3x3 wall

rep:10:[f/pl:1:up] = places a line of blocks above the turtle, for 10 block forward

CODE



-- ==========================================================
-- TURTLE REMOTE CONTROL PROGRAM
-- ==========================================================


rednet.open('right')

local function nz(val) if val then return val else return '' end end
local function iif(c,y,n) if c then return y else return n end end
local function isIn(c,...) for i,v in ipairs({...}) do if v==c then return true end end return false end

local split = function(str, pattern)
  pattern = pattern or "[^%s]+"
  if pattern:len() == 0 then pattern = "[^%s]+" end
  local parts = {__index = table.insert}
  setmetatable(parts, parts)
  str:gsub(pattern, parts)
  setmetatable(parts, nil)
  parts.__index = nil
  return parts
end

w,h = term.getSize()

local xpos=0
local ypos=0
local zpos=0
local rotation=0

local log={}
local logLines=h-4

local turtleCommands={}

local function addLog(message)
table.insert(log, message)
if #log>logLines then
table.remove(log,1)
end
for n=1,#log do
term.setCursorPos(1,4+n)
term.clearLine()
write(log[n])
end
end


local function updateScreen()
term.setCursorPos(1,3)
write("X: "..xpos.." Y: "..ypos.." Z: "..zpos.." ROT: "..rotation)
end

local function doTurnRight(params)
local times=tonumber(params[1]) or 1
for i=1,times do
rotation = (rotation+1)%4
turtle.turnRight()
end
updateScreen()
end

local function doTurnLeft(params)
local times=tonumber(params[1]) or 1
for i=1,times do
rotation = (rotation-1)%4
turtle.turnLeft()
end
updateScreen()
end

local function doForward(params)
local bUpdated=false
local times=tonumber(params[1]) or 1
for i=1,times do
if turtle.forward() then
xpos = xpos + iif(rotation==0,1,iif(rotation==2,-1,0))
ypos = ypos + iif(rotation==1,1,iif(rotation==3,-1,0))
bUpdated=true
end
end
if bUpdated then updateScreen() end
end

local function doBack(params)
local bUpdated=false
local times=tonumber(params[1]) or 1
for i=1,times do
if turtle.back() then
xpos = xpos - iif(rotation==0,1,iif(rotation==2,-1,0))
ypos = ypos - iif(rotation==1,1,iif(rotation==3,-1,0))
bUpdate=true
end
end
if bUpdated then updateScreen() end
end

local function doUp(params)
local bUpdated=false
local times=tonumber(params[1]) or 1
for i=1,times do
if turtle.up() then
zpos = zpos + 1
bUpdated=true
end
end
if bUpdated then updateScreen() end
end

local function doDown(params)
local bUpdated=false
local times=tonumber(params[1]) or 1
for i=1,times do
if turtle.down() then
zpos = zpos - 1
bUpdated=true
end
end
if bUpdated then updateScreen() end
end

local function doPlace(params)
turtle.select(tonumber(params[1]) or 1)
if #params>1 then
local where=params[2]:lower()
if where=="up" then
turtle.placeUp()
elseif where=="down" then
turtle.placeDown()
elseif where=="left" then
turtle.turnLeft()
turtle.placeDown()
turtle.turnRight()
elseif where=="right" then
turtle.turnRight()
turtle.placeDown()
turtle.turnLeft()
elseif where=="back" then
turtle.turnRight()
turtle.turnRight()
turtle.place()
turtle.turnRight()
turtle.turnRight()
end
else
turtle.place()
end
end

local function doDig(params)
turtle.select(tonumber(params[1]) or 1)
if #params>1 then
local where=params[2]:lower()
if where=="up" then
turtle.digUp()
elseif where=="down" then
turtle.digDown()
elseif where=="left" then
turtle.turnLeft()
turtle.digDown()
turtle.turnRight()
elseif where=="right" then
turtle.turnRight()
turtle.digDown()
turtle.turnLeft()
elseif where=="back" then
turtle.turnRight()
turtle.turnRight()
turtle.dig()
turtle.turnRight()
turtle.turnRight()
end
else
turtle.dig()
end
end

local function parseBracket(source,startPos)
local level=0
for n=startPos,source:len() do
local fChar=source:sub(n,n)
if fChar=="[" then
level = level + 1
elseif fChar=="]" then
level=level - 1
if level==0 then
return true, n, source:sub(startPos+1,n-1)
end
end
end
return false,-1,""
end


local function tableToString(tbl,delimiter)
local result = ""
if not delimiter then delimiter="," end
for n=1,#tbl do
result=result..iif(n>1,delimiter,"")..tbl[n]
end
return result
end

-- Sample syntax: REP:3:[code]/u/	  u/
local function parseCommands(commands)
local cmd=""
local cmdParams={}
local bHandleCommand = false

commands=commands.."/"

local buildCmd=function(cmdElement)
if cmd=="" then
cmd=cmdElement:lower()
else
table.insert(cmdParams,cmdElement)
end
end

while commands~="" do  
local fCharPos=commands:find("[/:%[]")
local fChar = ""

if not fCharPos then
fCharPos=commands:len()+1
fChar=""
else
fChar=commands:sub(fCharPos,fCharPos)
end

if fChar=="" then
buildCmd(commands)
bHandleCommand=true
commands=""
elseif fChar=="[" then
local success, endPos, foundString  = parseBracket(commands,fCharPos)
if success then
buildCmd(foundString)
commands=commands:sub(endPos+1)
else
commands=""
end
elseif fChar==":" then
foundString=commands:sub(1,fCharPos-1)
buildCmd(foundString)
commands=commands:sub(fCharPos+1)
elseif fChar=="/" then
foundString=commands:sub(1,fCharPos-1)
buildCmd(foundString)
commands=commands:sub(fCharPos+1)
bHandleCommand=true
else
addLog(commands)
end

if bHandleCommand then
--addLog("exec:"..cmd.."("..tableToString(cmdParams)..")")
local cmdToExecute=turtleCommands[cmd]
if cmdToExecute then
cmdToExecute(cmdParams)
else
addLog("Invalid command from cpu#"..cpu.." :"..cmd)
end

cmd=""
cmdParams={}
bHandleCommand=false
end
end
end

local doRepeat=function(params)
if #params>1 then
local times=tonumber(params[1]) or 1
for i=1,times do
parseCommands(params[2])
end
else
addLog("Not enough parameters for REP")
end
end

local doFill=function(params)
local times=tonumber(params[1]) or 1
for i=1,times do
rs.setOutput("left",true)
sleep(0.2)
rs.setOutput("left",false)
sleep(0.2)
end
end


turtleCommands={
  right=doTurnRight,r=doTurnRight,
  left=doTurnLeft,l=doTurnLeft,
  up=doUp,u=doUp,
  down=doDown,d=doDown,
  forward=doForward,f=doForward,
  back=doBack,b=doBack,
  place=doPlace,pl=doPlace,
  dig=doDig,dg=doDig,
  rep=doRepeat,
  fill=doFill
  }

  -- Initialize interface, let other computers know i'm alive  

term.clear()
term.setCursorPos(1,1)
print("Rednet Monitor CPU#"..os.getComputerID())
print(string.rep("=",w-1))
term.setCursorPos(1,4)
print("-[log]"..string.rep("-",w-7))
rednet.broadcast("bot/active/"..os.getComputerID())

updateScreen()

-- Start listening to commands

while true do
   sleep(0.1)
   event,cpu,message=os.pullEvent()
   if event=="rednet_message" then
parseCommands(message)
rednet.send(cpu,"bot/done")
   end
end
Vannya #2
Posted 08 March 2012 - 05:34 AM
This program is AMAZING!!

Actually, Im totally new to this mod, and I have been and always gonna be a noob into the things of codding and programming. Its just not my world.

Anyway, There is something that I could point for you: the turtle lacks from the ability to "pick up" items.
I have found, in a post, a function called "getItem()". I dont know if that really gives to the droid that ability, but if it can, then it would be wonderful.

Also, It would be really nice some kind of "oficial program" for controlling the turtle. Actually im doing it with some weird piece of program made by me, and with my trollnian knowledge about the stuff… It just works, but its not perfect at all.

——————————————————-

Apart from that, Im asking myself if, in the same way that the auto-builder from BC can read "schemes", the turtle could do it too. Or, in another way, could be made some kind of program about a grid of… 20x20? Where you could mark with crosses some squares and the turtle could place a block on the fiel ahead over the marked squares.
That could be a really basic but incredible building program!!

P.D.: sorry for my trash english D:
Liraal #3
Posted 08 March 2012 - 06:05 AM
You could simply use loadstring… My remote control is like 3 times shorter :mellow:/>/> Anyway, god job!
Espen #4
Posted 08 March 2012 - 09:24 AM
You could simply use loadstring… My remote control is like 3 times shorter :mellow:/>/> Anyway, god job!
Come on, be respectful. There's no need to make comparisons, this is not a competition.

Also, to everyone who feels addressed by the following:
Skill should always be self-evident and speak for itself. If you feel the need to advertise it, then you're either not as skilled as you think, or you are slave to the need for appreciation. This sounds harsher than it is meant, though. I hope it isn't misunderstood as patronizing, it's meant more as friendly advice.
Liraal #5
Posted 08 March 2012 - 12:06 PM
I suppose i should definitely stop typing at 7AM.
I didn't meant that as a comparison, I simply wanted to say, that using loadstring to load code allows for a greater degree of flexibility than fixed commands. It was an advice (or it was MEANT to be one) but i really appreciate his work. He did many tings better that i did and I must admit I'm a bit envious :mellow:/>/> But since this seems to upset some people, I'll stop mentioning my stuff anywhere else than my threads.

All I ever wanted to say is that using loadsting() allows for making the code more flexible and shorter at once.
Espen #6
Posted 08 March 2012 - 12:50 PM
Hey Liraal, I'm sorry, the whole post wasn't meant to target you, it was meant for everyone who is susceptible to the described behavior.
It was really just the first part of my post that was meant for you and then I used that opportunity as a springboard to convey a general plea.
And it's not to scold anyone for smug behavior, but to try to make them understand that it's futile and doesn't help anyone but their own egos.
In the best case nobody cares, in the worst case someone who was given smug advise is probably less inclined to follow the smug advice, even though it might have been a good one!
Also I didn't mean for you to stop talking about your programs, etc. Omg, that is the last thing I'd want and goes completely against the whole point of this forum.
It's totally ok to share your ideas and give people advice on how to improve their skills and show them how you did it. Please don't stop that on my behalf! :mellow:/>/>

And lastly: I'm not part of the staff and thus have no authority to enforce any rules of conduct whatsoever.
I'm just like everybody else and what I said is my personal opinion and well meaning advice.

Ok, so no hard feelings to anyone and I will stop derailing this thread any further with this.
Cheers ;)/>/>
Wolvan #7
Posted 08 March 2012 - 05:39 PM
He that is really nice. Wanna merge my modification of Dirkus7's Remote Turtle with this modification?
Vannya #8
Posted 08 March 2012 - 06:58 PM
The diference between Wenaya´s and Wolvan´s programs is the point that the first one can be ordered to do some list of tasks and repeat them. Its a kind of droid that you can send, by a laaaarge and premeditated chain of commands, to do some complicated task (actually you need to calculate it very well, and you lose the time that you can use to do it by yourself, but its cute anyway <3).

The second one, instead, is used to be controlled by the user. And thats really nice too!!

Actually, I carry my disks and a drive, a computer, and a turtle. In that way I can choose between one or another. But what would be more awesome is some kind of interface to order the turtle to build some structure, or to mine in some way. Some kind of grid (as the "Sea Battle" table game that kids sometimes play) where you could mark or not some square and send the turtle to "do something" in that square; always the turtle in the middle of the grid.
Wolvan #9
Posted 08 March 2012 - 08:09 PM
The diference between Wenaya´s and Wolvan´s programs is the point that the first one can be ordered to do some list of tasks and repeat them. Its a kind of droid that you can send, by a laaaarge and premeditated chain of commands, to do some complicated task (actually you need to calculate it very well, and you lose the time that you can use to do it by yourself, but its cute anyway <3).

The second one, instead, is used to be controlled by the user. And thats really nice too!!

Actually, I carry my disks and a drive, a computer, and a turtle. In that way I can choose between one or another. But what would be more awesome is some kind of interface to order the turtle to build some structure, or to mine in some way. Some kind of grid (as the "Sea Battle" table game that kids sometimes play) where you could mark or not some square and send the turtle to "do something" in that square; always the turtle in the middle of the grid.
That sounds pretty cool. Again for understanding:
1. Create a grid or mark an area
2. Start a programm on the turtle
3. Let the turtle build for example a house
Vannya #10
Posted 08 March 2012 - 10:04 PM
Thats it!! But… I dont know anything about this, but I guess it would be really hard or even imposible to send the turtle to build something in 3D. I mean… its posible to send it to build something 1 block tall, but I dont know if some kind of interface could store so much information as many blocks of tall.
Liraal #11
Posted 08 March 2012 - 10:09 PM
Well, it most certainly is NOT impossible. I can easily imagine a grid and a column beside it that would emulate the 3rd dimension of the blueprint.
Wolvan #12
Posted 09 March 2012 - 02:27 PM
Thats it!! But… I dont know anything about this, but I guess it would be really hard or even imposible to send the turtle to build something in 3D. I mean… its posible to send it to build something 1 block tall, but I dont know if some kind of interface could store so much information as many blocks of tall.
Not really that difficult I think. Just add a variable that defines the height and then do a repeat loop
It is pretty easy I think just doing a repeat loop
Liraal #13
Posted 09 March 2012 - 02:29 PM
ah, you meant 3d builder? It's already been done by many people. Thought you want a 3d INTERFACE :mellow:/>/> But i have to think about the interface.
ironsmith123 #14
Posted 14 March 2012 - 12:42 AM
Just wonderinmg……..What should i name this file? Also where should i put this program at so it is available?
ToySoldier1992 #15
Posted 21 May 2012 - 10:04 PM
Just wonderinmg……..What should i name this file? Also where should i put this program at so it is available?

Name it startup, rightclick on the turtle and it will load. Otherwise, just give it any name (like /helloworld), rightclick on the turtle and then type "helloworld", it will also load.

For the rest: Absolutely an awesome code. I'm using it for underground mining:

rednet.send(16,"dg/f/r/rep:3:[rep:9:[dg/f]/l:2/dg::up/u]/rep:9:[dg/f]/l:3/d:4")

It's so much faster than me, haha.

For some ideas before here: It's certainly not impossible to let it build a structure for you. Give it all the materials in the right inventory spots, place it somewhere at x/y/z 0/0/0 of the place where you want to build, run a pre-created program (By whoever designed the structure you wish to build) and voila. I think it will give people who design structures and things for minecraft a whole new oppertunity. People don't have to build it themselves any more, create a turtle, gather the materials, run the code and watch the turtle build the house for you. How awesome is that?