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

Using Parallel

Started by Balthamel, 06 June 2015 - 08:34 PM
Balthamel #1
Posted 06 June 2015 - 10:34 PM
Hi I've been trying to use parallel.waitForAny to make a mining turtle that can return to base on recieiving a wireless rednet signal. I had some issues with it hanging so wanted to see how it behaved. I created this bit of code to test it from snippets of the main code.

local Recall = 1
local function main()
os.sleep(10)
print("test1")
end
local function listen()
os.sleep(5)
	    print("test2")
end
--this will listen for recall while running all the main code.
while Recall == 0 do
parallel.waitForAny(main(), listen())

end
What I expected, to be spammed with printed test2.
What happens, test1 is printed after a few seconds shortly followed by test2 then the program hangs and will not end even with CTRL-T. Am i doing it wrong?
Lyqyd #2
Posted 06 June 2015 - 10:45 PM
Yes, you're doing it wrong. You should be passing the functions to the parallel call, not calling them and passing the results to the parallel call. You should also probably have the while loops in the functions you're calling in parallel rather than having the parallel call in a while loop, so you can just create the coroutines once and continue to use them.
Balthamel #3
Posted 06 June 2015 - 10:51 PM
The parallel call in a while loop is required due to the structure of the original code. Would you type out what should go in the parallel.waitForAny brackets for me please? I've looked at a lot of examples and I can't see how mine differs.
Balthamel #4
Posted 06 June 2015 - 10:53 PM
Oh, nvm, i can't believe I missed that for so long. not main() just main. My bad.
HPWebcamAble #5
Posted 06 June 2015 - 10:59 PM
To expand on what Lyqyd said, you need to pass the FUNCTION to 'parallel.waitForAny', by using the (), you are passing the RESULT


The fix is simple:

parallel.waitForAny( main , listen )

Also, like lyqyd said, the two functions should have while loops, instead of repeatedly calling 'parallel.waitForAny'
Lyqyd #6
Posted 06 June 2015 - 11:38 PM
The parallel call in a while loop is required due to the structure of the original code.

I strongly suspect that it isn't. I'd imagine that if you were to post the actual code, we could help you refactor it to move the loops into the coroutines.
Balthamel #7
Posted 07 June 2015 - 05:45 AM
If you want to have a look. I know it's a mess.

--This is a Mining Program
--Set Variables
local TurtleCanMine = 1
XMovement = 0 --store movement on the X Axis-Global so that it can return to home
ZMovement = 0 --store movement on the Z Axis
YDrop = 0 --store how low the turtle is
local XMax = 0 --how far has it moved
local ZMax = 0
local YLast = 0 --Last known Y height
local moveconfirm
local Recall = 0 --holds value for if recall command has been sent
local modem = peripheral.wrap("right") --wraps the modem located on right
modem.open(1972)--Open channel 1972 so that we can listen on it
--TO DO
--WRITE A SECTION THAT MAPS HOME LOCATION AND ORIENTATION TO FILE
--set the last mined location variables from file
local file = io.open("last","r")--get the home location
local XMax = tonumber(file.read("*line"))
local ZMax = tonumber(file.read("*line"))
local YLast = tonumber(file.read("*line"))
file:close()

local function Forward() --this function move the turtle forward one block allowing for blockages. and updates XMovement for each successful move
while not turtle.forward() do
  if turtle.detect() then --It cannot move because of a block
   if not turtle.dig() then --It cannot dig the block, assume bedrock, warded etc.
    peripheral.call("right", "transmit", 1972, 1972, "Block impact Forward")
    TurtleCanMine = 0
   end
  elseif turtle.attack() then --it cannot move because of a mob
   while turtle.attack() do end
   end
end
end
local function Down() --this function move the turtle Down one block allowing for blockages. and updates XMovement for each successful move
while not turtle.down() do
  if turtle.detectDown() then --It cannot move because of a block
   if not turtle.digDown() then --It cannot dig the block, assume bedrock, warded etc.
    peripheral.call("right", "transmit", 1972, 1972, "Block impact Down")
    return(2)
   end
  elseif turtle.attackDown() then --it cannot move because of a mob
   while turtle.attackDown() do end
   end
end
YDrop = YDrop + 1
end
local function Up() --this function move the turtle Down one block allowing for blockages. and updates XMovement for each successful move
while not turtle.up() do
  if turtle.detectUp() then --It cannot move because of a block
   if not turtle.digUp() then --It cannot dig the block, assume bedrock, warded etc.
    peripheral.call("right", "transmit", 1972, 1972, "Block impact Up")
    Return(2)
   end
  elseif turtle.attackUp() then --it cannot move because of a mob
   while turtle.attackUp() do end
   end
end
YDrop = YDrop - 1
end
local function preFlightChecks()
  ------
  --Ensure Turtle is Fuelled
  peripheral.call("right", "transmit", 1972, 1972, "Fuelling")
  while turtle.getFuelLevel()<20000 do
   turtle.select(1)--go to slot 1
   turtle.suckUp()--collect fuel from the chest ABOVE the turtle start position
   while (turtle.getFuelLevel()<20000 and turtle.getItemCount()~=0) do --refuel one item repeatedly until maxed or no more fuel is available
    turtle.refuel(1)
   end
  end
  --offload excess fuel back into fuel chest
  turtle.dropUp()
end
local function returnAndUnload()

XMax = XMovement --set last known locations
ZMax = ZMovement --for all the
YLast = YDrop    --variables
--save these variables to file so can resume last location mining even after restart.
fs.delete("last")--remove the previous saved data
local file = io.open("last","a")--open a new save file
file:write(XMax)
file:write("\n")
file:write(ZMax)
file:write("\n")
file:write(YLast)
file:close()


--Return to drop off
peripheral.call("right", "transmit", 1972, 1972, "Drop off")
while YDrop > 0 do --return to Y0
  Up()
end
turtle.turnRight()
while ZMovement > 0 do --return to Z0
  Forward()
  ZMovement = ZMovement - 1
end
turtle.turnRight()
while XMovement >0 do --return to Y0
  Forward()
  XMovement = XMovement - 1
end


--Unload all the Mined resources
peripheral.call("right", "transmit", 1972, 1972, "Unload")
for i=1,16 do
  turtle.select(i) --select slot i
  if not turtle.drop() then --place slot i in chest
   peripheral.call("right", "transmit", 1972, 1972, "Output is Full") --if chest is full report full
   TurtleCanMine = 0	   --and then trigger end script
  end
end
turtle.turnLeft()--reset to face out again
turtle.turnLeft()--^^
turtle.select(1)
 
end
--This is the primary active section of the script.
local function main ()
while TurtleCanMine do
  ------
 
  --Return to LAST mining location
  peripheral.call("right", "transmit", 1972, 1972, "Return To Mine")
  while XMovement<XMax do --move the turtle to the last mining on X axis
   Forward()
   XMovement = XMovement + 1
  end
  turtle.turnLeft() --rotate the turtle to move on Z axis
  while ZMovement<ZMax do --move the turtle to last mining on Z axis
   Forward()
   ZMovement = ZMovement + 1
  end
  turtle.turnRight() --Return turtle to primary direction
  while YDrop<YLast do --move the turtle to the last Y position
  Down()
  end
 
  ---------
 
  --Start Mining
  peripheral.call("right", "transmit", 1972, 1972, "Begin Mining")
  while turtle.getItemCount(16)==0 do --while slot 16 is empty, if slot 16 contains an item the turtle may drop items.
  
   if Down() == 2 then -- first try and mine down, if it has hit bedrock
    while YDrop > 0 do --return to y0
	 Up()
    end
   
    if ZMovement < 30 then --if the sideways movement is still not full mine width move sideways
   
	 turtle.turnLeft()--rotate to moving in Z
	 Forward()
	 ZMovement = ZMovement + 1
	 turtle.turnRight()--rotate back to start position
   
    else --if the sideways movement IS full return to Z0 and move X+1
   
	 turtle.turnRight() --Rotate to moving in -Z
	 while ZMovement>0 do --return to Z0
	 
	  Forward()
	  ZMovement = ZMovement - 1
	 
	 end
	 turtle.turnLeft() --Return to Orientation0
	
	 Forward() --X+1 movement
	 XMovement = XMovement +1
	
    end
   end
  end
  returnAndUnload()
 
end
end
local function listen()
while 1 do
  local event, modemSide, senderChannel, replyChannel, message, senderDistance = os.pullEvent("modem_message")
  if message == "Recall" then
   Recall = 1
   peripheral.call("right", "transmit", 1972, 1972, "Recall Received")
  end
end
peripheral.call("right", "transmit", 1972, 1972, "Recall Received")
end
--this will listen for the recall signal while running all the main code.
while (Recall == 0 and TurtleCanMine) do
preFlightChecks()
parallel.waitForAny(main, listen)
returnAndUnload()
end