Scan for either of the 3 images during runtime

Asked by Hossain Abeer on 2017-06-03

Hi, I have been trying to write a program for days now. It was supposed to scan for either of the 3 images. This is how I originally wrote, and obviously, it's not working. It detects only the 1st image, and complete ignores the other 2

while True:
       if exists((imgA) or (imgB) or (imgC), 3600):
              click(imgO)
          click(imgP)
          click(imgQ)
          click(imgR)
          sleep(3)

As it's a continuous program, everytime imgA is shown, it detects it and acts accordingly, but it's either completely unaware or ignorant of the other 2 images. By the way, when the other 2 images is detected, it should be doing the same thing.

Thank you for your time

Question information

Language:
English Edit question
Status:
Solved
For:
Sikuli Edit question
Assignee:
No assignee Edit question
Solved by:
RaiMan
Solved:
2017-06-07
Last query:
2017-06-07
Last reply:
2017-06-07

This question was reopened

Hossain Abeer (retroxic) said : #1

Later I have also tried this method, but again, not working

while True:
          if exists((imgA or imgB or imgC), 3600):
               click.......

thanks

masuo (masuo-ohara) said : #2

How to click when SikuliX find one of the three.

if exists("imageA.png",0) or exists("imageB.png",0) or exists("imageC.png",0):
    click("imageO.png")

Hossain Abeer (retroxic) said : #3

Hi masuo,

Thanks for your effort, but that didn't work. Any other method?

masuo (masuo-ohara) said : #4

What is it that it didn't work by #2 method?

Hossain Abeer (retroxic) said : #5

This one:

if exists("imageA.png",0) or exists("imageB.png",0) or exists("imageC.png",0):
    click("imageO.png")

still cant detect the other 2 images.

masuo (masuo-ohara) said : #6

In case of using exists("imageA.png",0), exists("imageB.png",0) and exists("imageC.png",0) individually, to detect each image is work good?
If so, #2 method work in my environment.

[codes to check detection:]
m1 = exists("imageA.png",0)
print "m1:%s" % m1

m2 = exists("imageB.png",0)
print "m2:%s" % m2

m3 = exists("imageC.png",0)
print "m3:%s" % m3

if m1 or m2 or m3:
    print "exists"
else:
    print "not exists"

masuo (masuo-ohara) said : #7

In case it takes time until A, B, C appears,use "while".

counter = 3600
while True:
    if exists("imageA.png",0) or exists("imageB.png",0) or exists("imageC.png",0):
        click("imageO.png")
    sleep(1)
    counter = counter - 1

masuo (masuo-ohara) said : #8

Sorry, I forgot to add condition.

while True: <--- mistake

while counter > 0:

Hossain Abeer (retroxic) said : #9

They didn't work

#6 had problem running the script, and the script couldn't be even saved.

#7 and #8 ran, but still couldn't detect images. in fact, no image was detected

masuo (masuo-ohara) said : #10

@Hossain Abeer

I use SikuliX1.1.1 on Windows, I can save #6 script.
What is your environment?

Hossain Abeer (retroxic) said : #11

Sikulix IDE1.1.0

I have both Java and Python IDEs installed on computer. Running Windows 10, 64bit

Hossain Abeer (retroxic) said : #12

I checked for update from the SikuliX app, but it says no update available. Does this mean that I must download and install version 1.1.1 manually?

masuo (masuo-ohara) said : #13

I tried SikuliX IDE1.1.0 on Windows10,64bit too.
#6 script worked.
Sorry I have no idea anymore , please wait other people's comment.

Hossain Abeer (retroxic) said : #14

I am now running SikuliX IDE 1.1.1.

and i tried the following script

click(G)

while True:
      if exists ((A or B or C), 3600): #A B C are the main images to be detected
            click(X)
            click(Y)
       click(Z)
       click(Y)
       click(G)
     sleep(3)

NOT working

also used

click(G)

while True:
      if exists(A, 3600) or exists(B, 3600) or exists(C, 3600):
            click(X)
            click(Y)
       click(Z)
       click(Y)
       click(G)
     sleep(3)

In both cases, only image A is detected, and acted upon. But B and C are completely ignored

masuo (masuo-ohara) said : #15

This is comment to the following code
 if exists(A, 3600) or exists(B, 3600) or exists(C, 3600):

A is not visible on screern, SikuliX wait 3600 secondes and then try exists(B,3600).

Hossain Abeer (retroxic) said : #16

Well then, this isn't working either

 if exists ((A or B or C), 3600):

Hossain Abeer (retroxic) said : #17

Even if A reappears seconds later, the program can detect it and act over and over again. So I am guessing it is completely ignoring the other two B and C.

masuo (masuo-ohara) said : #18

This is comment to #16.

Why you set multiple parameter to exists()?
It is posible to set parameter to exists() only a Pattern object or a string (path to an image file or just plain text) .

http://sikulix-2014.readthedocs.io/en/latest/region.html?highlight=exists

Hossain Abeer (retroxic) said : #19

But I have used other methods too, but still couldn't detect the other two images. Your method #2 didn't work as well.

In all the cases, the first one of the 3 images A was detected. and others were ignored. Even if A reappears say 2 seconds later, the program detects it and acts, again and again. B and C is never detected

Hossain Abeer (retroxic) said : #20

Hi,

after many trials and errors, i have come up with this script.

click(G)

while True:
      if exists(A, 0) or exists(B, 0) or exists(C, 0):
          click(X)
          click(Y)
           click(Z)
          sleep(2)

else:
     sleep(1)

It can detect either of the A, B or C, at anytime, any order of occurrence
But the problem is, the program quits after say 3 sec if any of the three images was not found. I want it to stay active for an (infinite) long time, and keep on scanning for the 3 images, until I end it manually with "ALT+SHFT+C"

Any idea on how to keep the program awake and scanning, and keep looping the actions?

RaiMan (raimund-hocke) said : #21

 if exists(A, 3600) or exists(B, 3600) or exists(C, 3600):

will never work in your sense, since the or-condition is true if the first test from left to right is true.
hence if A exists, it does not matter, wether B and/or C exist.

another problem is the wait time: if A does not exist, it waits 3600 seconds for A and never tests for B and/or C during this period.

try this:

# the loop continuously checks very fast one after the other for A, B and C
# if none appeared, waits 1 second and repeats the search
# if at least one of A, B or C appeared end the loop
# isA, isB, isC carry the information about each appearence
while true:
    isA = exists(A, 0)
    isB = exists(B, 0)
    isC = exists(C, 0)
    if isA or isB or isC: break
    wait(1)
# now make your complex decisions:
if isA and not isB and not isC:
    # do something if ONLY A was visible
if isA and isB:
    # do something if A AND B was visible, C does not matter
.... hope you got it ;-)

RaiMan (raimund-hocke) said : #22

Sorry for doubling, the thread is rather complex ;-)

... after having done, what is needed for the different appearance combinations, it might be necessary to start all over (means an outer additional loop)

Hossain Abeer (retroxic) said : #23

Hi RaiMan,

thanks for dropping in. Finally, i can get to talk to the legend of Sikuli.

Do it need to end the script with

else:
    sleep(1)

      to loop it?

Because, what's happening is that, after detecting any of the 3 images, say it has detected C, then it will act accordingly,which is click click click, and then 2 or 3 sec later, it quits the program. I want to loop it, you know, repeat the process over and over again, until I manually end using "ALT+SHFT+C"

Just this end part. the looping of the process, keeping the program active. And then I am all done. Problem solved.
Thank you

RaiMan (raimund-hocke) said : #24

if I understand your intention right and the indentation, then this script should never end:

# this loop will run forever, see comment
while True:
      if exists(A, 0) or exists(B, 0) or exists(C, 0):
          click(X)
          click(Y)
          click(Z)
          sleep(2)

else: # this does not make sense, since it refers to the while, which is always true
     sleep(1)

comment: it would only stop, if one of the click(...) produce a FindFailed exception

so this should do what you want (supposing the click(...) have images as targets):
while True:
      if exists(A, 0) or exists(B, 0) or exists(C, 0):
          try:
              click(X)
              click(Y)
              click(Z)
          except: pass
          sleep(2)

RaiMan (raimund-hocke) said : #25

Nevertheless: the solution in comment #21 is the more general solution:

# now with an outer loop, that needs to be interrupted using "ALT+SHFT+C"
while True:
    while True:
        isA = exists(A, 0)
        isB = exists(B, 0)
        isC = exists(C, 0)
        if isA or isB or isC: break
        wait(1)
    if isA and not isB and not isC:
        # do something if ONLY A was visible
    if isA and isB:
        # do something if A AND B was visible, C does not matter
    # more if's as needed

Hossain Abeer (retroxic) said : #26

Thanks RaiMan, that solved my question.

Hossain Abeer (retroxic) said : #27

Hi,

The script #25 solved my problem, and performs accordingly. But a new objective has arisen from this.

Say, the program has detected B, of the 3 images (A, B and C), now I want the program to ignore this B for next 10 sec, while still searching for A and C.

I tried this:

while True:
    while True:
        isA = exists(A, 0)
        isB = exists(B, 0)
        isC = exists(C, 0)
        if isA or isB or isC: break
        wait(1)

   if isA:
        click(X)
        click(Y)
        click(Z)
        waitVanish(isA)

didn't work. the program quits.

Thanks

Best RaiMan (raimund-hocke) said : #28

--- didn't work. the program quits.
The above code cannot simply quit silently. So there must have been an error message. In this case because of the
waitVanish(isA)
which needs an image or pattern as parameter.
So please post also error messages, if your code does not work as expected.

--- want the program to ignore this B for next 10 sec
in your code I cannot see any trial to solve this.

the principle solution is something like this:
ignoringB = 0
while True:
  while True:
    isA = exists(A, 0)
    isB = exists(B, 0)
    isC = exists(C, 0)
    if isB and ignoringB > 0:
      if time.time() < ignoringB:
        isB = False # ignore B
      else:
        ignoringB = 0 # recognize again
    if isA or isB or isC: break
    wait(1)

  # do your work
  # decide somehow to ignore B for a while
  ignoringB = time.time() + 10 # the time 10 secs in the future

Hossain Abeer (retroxic) said : #29

Thanks RaiMan, that solved my question.