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

Loop is broken?

Started by Furest_, 21 August 2014 - 03:58 PM
Furest_ #1
Posted 21 August 2014 - 05:58 PM
Hello,
I'm trying to make a program able to detect if I am in an area so a door opens.
The door is a carriage translocator from JAKJ redstone in motion. It works with a redstone signal.
I've derped around to find a correct way to exploit the OpenCCSensors' sensor (with the proximity sensor card).

Here's my code:

print("start")
whitelist = {"furest","arthuremen1"}
print("whitelist done")
os.loadAPI("ocs/apis/sensor")
sensor = peripheral.wrap("left")

-- vérifie si le joueur détecté est whitelist
function checkexist(nickname)
  for key, nom in pairs(whitelist) do
	if nom == nickname then
	  return true
	end
  end
return false
end

--Ouvre la porte
function Ouvre()
rs.setOutput("bottom", true)
sleep(0.2)
rs.setOutput("bottom", false)
end

--Ferme la porte
function Ferme()
rs.setOutput("right", true)
sleep(0.2)
rs.setOutput("right", false)
end


--Distance du centre de détection
local offset = {
X = 0,
Y = 8,
Z = 0
}
local rayon = 3

--Calcule la disa=tance
function distance(pos)
  local xd = pos.X - offset.X
  local yd = pos.Y - offset.Y
  local zd = pos.Z - offset.Z
  return math.sqrt(xd*xd + yd*yd + zd*zd)
end

function nearby()
print("check")
t = sensor.getTargets()
for name, details in pairs(t) do
print(name)
if details.Name == "Player" then
local x = sensor.getTargetDetails(name)
print(x.Username)
if checkexist(x.Username) and distance(details.Position) < rayon then
print(x.Username .. " is there!")
return true
else
return false
end
else
return false
end
end
end
while true do
if nearby() == true then
Ouvre()
elseif nearby() == false then
Ferme()
end
end

The last 7 lines are the program itself, the rest are just functions that are called.

So it's simple, is the player is in the area, it sends a signal to 1 translocator to open the door. If the player stays in this area, it should continue to form a pulse (useless but it's the most efficient way I've find).
If the player is gone, it will send a redstone pulse to the bottom so the second carriage translocator closes the door.

But in fact, when I'm nearby the door sometimes it opens sometimes not. And when I go 5-10 blocks away, the computer no longer try to check the area and the program don't work anymore…

It also stops by itself even if I don't move…

That's kinda odd because it's a loop that nothing could be able to break. But it do…

Thank you for the help :)/>

Furest-
Edited on 21 August 2014 - 04:05 PM
Dragon53535 #2
Posted 21 August 2014 - 06:51 PM
I actually made a program myself that works much in the way you want here. The way to make it work is edit the first few lines for direction and then press c to change who can access. Once they reach the specified opening area, the door opens forever until they decide to leave that area in which it closes after 0.1 seconds.

Anyways onto your program, you probably want to set a variable to count as nearby() in your while true do loop. So you would do.

while true do
  local test = nearby()
  if test then -- this is basically seeings if test == true
	--Dostuff
  if not test then -- this is seeing if test == false or nil
	--Domorestuff
  end
end
Edited on 21 August 2014 - 04:51 PM
Dog #3
Posted 21 August 2014 - 07:27 PM

while true do
  local test = nearby()
  if test then -- this is basically seeings if test == true
	--Dostuff
  if not test then -- this is seeing if test == false or nil
	--Domorestuff
  end
end

That won't work. The syntax of the 'if' statement is incorrect (2 if statements and only one end). This is what Dragon53535 probably meant…


while true do
  local test = nearby()
  if test then
	--# Dostuff
  else
	--# DoOtherStuff
  end
end

Hope that helps :)/>
Edited on 21 August 2014 - 05:27 PM
Furest_ #4
Posted 21 August 2014 - 07:47 PM
Hello,
Thanks for anwering ;)/>
I've tried your method but it don't work better.
It says me "check" (so it starts the nearby() function) but it don't go further.
Example:

function nearby()
print("check")
t = sensor.getTargets()
print("targets acquired")

Edit: after trying to reboot the computer many times, it worked once, analyzed for several seconds and when I got next to the door, it freezes again…

The computer won't print "targets acquired". That seems odd because sometimes it works, sometimes not but there is no reason for it not to do it…
Edited on 21 August 2014 - 05:53 PM
Dragon53535 #5
Posted 21 August 2014 - 08:25 PM
That won't work. The syntax of the 'if' statement is incorrect (2 if statements and only one end). This is what Dragon53535 probably meant…


while true do
  local test = nearby()
  if test then
	--# Dostuff
  else
	--# DoOtherStuff
  end
end

Hope that helps :)/>

Thank you for realizing that, however it was going to be an elseif statement, and i forgot to add the else :P/> mybad there.

Anyways Furest, you can easily use the program i posted above to open a door using a whitelist of players and the openccsensors sensor block, and it works quite well. However for your problem, can you post your entire code up to this point?
Dog #6
Posted 21 August 2014 - 08:36 PM
After looking over your code I can say that Dragon53535's suggestion just complicates things by adding an extra variable you don't need. The way you coded it originally is simpler and works just as well (not trying to pick on you, Dragon).

Having said that, I think I see the problem. You are loading an API named sensor, then you are overwriting that API's pointer by wrapping your sensor-device with the variable name sensor. Use a different variable name for wrapping and calling your sensor and the program should work.

I have two other suggestions for you:

First, properly indent your code so it is easier to read and troubleshoot. I think you'll find it'll also be easier to edit in the future.

Second, you should localize all your variables and functions. You localized a couple of variables but have left the rest (and all your functions) global. If you had localized 'sensor' when you wrapped the sensor-device you might not have had this problem. However, it is bad practice to use variable names that are already assigned to API's, functions, etc., so you should *still* rename the variable you are using for wrapping the sensor.

I localized and indented the end of your code as an example

local function nearby()
  print("check")
  local t = sensor.getTargets()
  for name, details in pairs(t) do
    print(name)
    if details.Name == "Player" then
      local x = sensor.getTargetDetails(name)
      print(x.Username)
      if checkexist(x.Username) and distance(details.Position) < rayon then
        print(x.Username .. " is there!")
        return true
      else
        return false
      end
    else
      return false
    end
  end
end

while true do
  if nearby() == true then
    Ouvre()
  elseif nearby() == false then
    Ferme()
  end
end

Hope that helps :)/>
Edited on 21 August 2014 - 06:42 PM
Dragon53535 #7
Posted 21 August 2014 - 09:30 PM
After looking over your code I can say that Dragon53535's suggestion just complicates things by adding an extra variable you don't need. The way you coded it originally is simpler and works just as well (not trying to pick on you, Dragon).
Looking at it yeah, i forgot that the if nearby() is in a while true, so initially i was going with the reason being that it runs through nearby() twice and i thought what if someone stepped in during the if nearby() == false but then i realized they can't fool it as the while true would cause it to run through again and then return true.

Dog you're actually quite wrong with how you're assuming this. In my code (that worked flawlessly) i just noticed how i never even loaded the API, which means i believe that's a default API? or at least doesn't need to be loaded at all, you can just wrap to it. SO his code should work.
Edited on 21 August 2014 - 07:31 PM
Dog #8
Posted 21 August 2014 - 11:49 PM
Dog you're actually quite wrong with how you're assuming this. In my code (that worked flawlessly) i just noticed how i never even loaded the API, which means i believe that's a default API? or at least doesn't need to be loaded at all, you can just wrap to it. SO his code should work.
I'm not sure what you mean. The code I posted *is* Furest_'s code, just with proper indentation and localization of variables. I didn't even correct the use of 'sensor' for the wrapped peripheral (something I left for Furest_ to do). As for whether the sensor API is loaded by default or not, that I do not know - I'm working with what is officially documented in the OpenCCSensors thread.
Edited on 21 August 2014 - 10:22 PM
Lyqyd #9
Posted 22 August 2014 - 01:11 AM
Dog you're actually quite wrong with how you're assuming this. In my code (that worked flawlessly) i just noticed how i never even loaded the API, which means i believe that's a default API? or at least doesn't need to be loaded at all, you can just wrap to it. SO his code should work.

Negative. Dog is right, and you are wrong. Your code uses the OpenPeripheral sensor, the code in this thread is written for the OpenCCSensors sensor. They are not interchangeable.
Dragon53535 #10
Posted 22 August 2014 - 02:09 AM
Negative. Dog is right, and you are wrong. Your code uses the OpenPeripheral sensor, the code in this thread is written for the OpenCCSensors sensor. They are not interchangeable.
Ahh, i didn't realize that open had a sensor, well then i apologize to Dog then for not realizeing that, and then yes, he does need to change his sensor variable.
Furest_ #11
Posted 22 August 2014 - 10:52 AM
How, i go to sleep and when I get up, there are tons of messages in english to read xD
Well, my code was correctly indented on notepad++. I think that the code thing of the forum broke it :/

I've tried with once:


os.loadAPI("ocs/apis/sensor")
sensor = peripheral.wrap("left")
and

os.loadAPI("ocs/apis/sensor")
mysensor = sensor.wrap("sensor")

None of those methods work… And before I wrote this version of the code, my program didn't even worked with the sensor.wrap() method…

Here's my actual code

print("start")
whitelist = {"furest","arthuremen1"}
print("whitelist done")
os.loadAPI("ocs/apis/sensor")
mysensor = sensor.wrap("left")
-- vérifie si le joueur détecté est whitelist
function checkexist(nickname)
  for key, nom in pairs(whitelist) do
    if nom == nickname then
	  return true
    end
  end
return false
end
--Ouvre la porte
function Ouvre()
rs.setOutput("bottom", true)
sleep(0.2)
rs.setOutput("bottom", false)
return true
end
--Ferme la porte
function Ferme()
rs.setOutput("right", true)
sleep(0.2)
rs.setOutput("right", false)
return true
end

--Distance du centre de détection
local offset = {
X = 0,
Y = 8,
Z = 0
}
local rayon = 3
--Calcule la distance
function distance(pos)
  local xd = pos.X - offset.X
  local yd = pos.Y - offset.Y
  local zd = pos.Z - offset.Z
  return math.sqrt(xd*xd + yd*yd + zd*zd)
end
function nearby()
print("check")
t = mysensor.getTargets()
print("targets got")
for name, details in pairs(t) do
  print(name)
  if details.Name == "Player" then
   local x = mysensor.getTargetDetails(name)
   print(x.Username)
   if checkexist(x.Username) and distance(details.Position) < rayon then
    print(x.Username .. " is there!")
    return true
   else
   return false
   end
  else
   return false
  end
end
end
while true do
proche = nearby()
if proche then
  Ouvre()
else
  Ferme()
end
end

Here's the pastebin link: http://pastebin.com/PrSJHHcE
Edited on 22 August 2014 - 08:54 AM
Dragon53535 #12
Posted 22 August 2014 - 02:53 PM
I believe you misunderstood, what we were meaning was

os.loadAPI("ocs/apis/sensor")
mysensor = sensor.wrap("left")

Ps, apparently the openccsesnsor looks like the openperiph
Edited on 22 August 2014 - 12:58 PM
Lyqyd #13
Posted 22 August 2014 - 05:14 PM
They do look similar/the same, but it's the OpenP sensor that looks like the OpenCCSensors sensor, since the OCS one existed first. :P/>

What is the current behavior of the script, OP? Is it getting through the process of fetching the target list at this point?
Furest_ #14
Posted 23 August 2014 - 09:58 AM
Sorry for the two posts at once. I though it would be more vidisible as I posted a new one :P/>
So when my program freezes and I hold Ctrl and T to stop it, it says:
startup: 54: terminated, which is exactly at the line
 t = mysensor.getTargets() 
It's like it had no targets to get… that's a bit silly. It would be useless if it's forbidden to detect nothing :/

So, most often, it detects le, open the door and then freezes. I really can't explain that better because it's quite inconsistent…

Also, I've tried to shorten my conditions in one line. This is now what it looks like:
http://pastebin.com/fbs4FJxS
Edited on 23 August 2014 - 08:03 AM
Lyqyd #15
Posted 23 August 2014 - 05:47 PM
You need to use sensor.wrap to wrap the sensor peripheral, not peripheral.wrap. Also, which version of OCS are you using and do you have a proximity card in the sensor block?
Furest_ #16
Posted 23 August 2014 - 05:50 PM
I've tried with both sensor.wrap and peripheral.wrap. Sensor.wrap doesn't make it less buggy. I have 2 proximity sensor cards in the sensor. My version is 1.6.4.4 ;)/>
Lyqyd #17
Posted 23 August 2014 - 05:55 PM
How on earth do you have two cards in one sensor? Can I see a screenshot of that?
Furest_ #18
Posted 23 August 2014 - 10:51 PM
I simply crafted two of 'em and stacked each another ;)/>

screen: http://www.noelshack...23-23-48-46.png
This is how I did. (Nope, the bees didn't helped that much xD)

I tried with one card only and… nothing happened :/ Then I rebooted and it worked up to when I was out of the detection area…
Edited on 23 August 2014 - 08:55 PM
Dragon53535 #19
Posted 24 August 2014 - 01:57 AM
So you're wanting it to stop when you leave the area specified and not when you leave the detection area?
Furest_ #20
Posted 24 August 2014 - 09:39 AM
well, not really. What I expect it to do is:
I enter the area (the loop is going on): it opens the door.
I leave the area: it closes the door and wait for me to come back one day :)/>
But instead, when I leave the area, is simply stops looping…

By area, I mean the area setted in my program (range of 3 or 5) and calculated by itself :)/>
Edited on 24 August 2014 - 08:15 AM
Furest_ #21
Posted 28 August 2014 - 11:17 AM
So do someone have an idea of what causes this bug?
Dragon53535 #22
Posted 28 August 2014 - 01:54 PM
When you say the program stops looping, does it close the door? and in my playtesting i never got x.Username to work correctly. Frankly as i've never dabbled in openccsensors until this thread i don't know exactly what your problem is however, i do know that upon looking at your code i can never get the yes output to correctly determine if i was there, so there might be a problem on my end as i was testing in single player. However as i'm currently away from home i cannot test further and any input you give will help me determine the nature of your error and an idea of where to start when i get home.

tl;dr Give me specifics, did the door close, did restarting the program make it run again, how far were you, things like that.
Bomb Bloke #23
Posted 28 August 2014 - 03:58 PM
Best I can make out, he's saying that when his script runs "mysensor.getTargets()" it has a random chance of freezing at that point. This suggests that the peripheral is waiting for an event that it fails to catch (either because it wasn't thrown or for some other reason), and so the script just sits there waiting forever.

In which case the issue would need to be fixed within OpenCCSensors.
Dragon53535 #24
Posted 29 August 2014 - 03:56 AM
I found a fix for you, now this will require a slight recoding on your part however i used parallel.waitForAny() on your nearby function and a sleep function i made, and when i left the area it never quit like it does when you normally leave. This is because the code gets stuck normally on either mysensor.getTargets() and mysensor.getTargetDetails(name) using the parallel API it shuts down the function after a second when my sleep(1) function finishes.

Your Sleep can never be lower than 0.2 or it might not be able to run through the target checker fast enough.
Edited on 29 August 2014 - 02:02 AM