loading
 
WaitVariable - how to use it
Kresimir Majdenic from Croatia  [38 posts]
2 years
I wrote an application in Delphi. Application utilize Robo-Realm (see attached RRTest.Pas procedure) to analyze image (Temporary.jpg) and read barcodes on it.
In version 2.67.37 it worked pretty much OK (with occasional RR crash) but I was using WaitImage.
Today I've installed newer RR version 2.76.5 and it does not work anymore.
It looks like WaitImage slows RR down to not usable (every call to RR method takes several seconds to execute and even then results are not correct).
On the other hand WaitVariable seems not to be working as I expected (I've expected that my Delphi application shall wait until variable in RR change its value - that is why I introduced variable at the very beginning and very end of RR file - to have a signal of START and STOP).

WaitVariable does not wait (it returns immediately) and read value is EMPTY (I expected to see values 1 at the begining and 2 at the end of robo file run).

As a result ... it seems like Delphi application runs too fast, RR does not execute so fast and I do not get results.
When I run the same robo file from within RR GUI it works perfectly. It returns correct barcode values and it runs far under 1 second.

What am I doing wrong?

(I use Windows 7 x64, Delphi 2009 professional - 32 bit, RR 2.76.5).
OMR.zip
Steven Gentner from United States  [1371 posts] 2 years
For ease of use (on my side) I've converted your pas to vb so that it can be run on the command line. It shouldn't matter either way since the same COM object is being run.

For the first  

rr.WaitVariable "BarcodeRecognition","1",5000

you are never guaranteed to see this since that variable's value may already have been changed to "2" depending on how your system executes what when. So instead, you actually don't need that variable at all since you are just interested in processing the current image at least once.

The

rr.WaitImage

would never have worked (or just returned without waiting) since the "Run" mode was off. There is now a check for that in case someone else has this issue. It will return a "not running" if this is the case and return immediately.

With that moved down, you actually don't need to set the variable "BarcodeRecognition" as you will be ensured that after waitImage the image has at least been processed once.

Also, if you do intend to just set Variables use the Set_Variable module as that has much less overhead than the VBScript module for just setting variables (obviously the VBScript module can be used for more than just setting variables where the Set_Variable module cannot).

Finally, I noticed a rotation module in the robofile. Did the "check all orientations" checkbox in the Barcode module not work? Or was it picking up invalid codes?

Note that it still takes a couple seconds to work as RR is really meant for very fast successive processing so as much of the setup, memory allocations will happen on startup. Sometimes its better to startup RR at the beginning of your app, send it commands as needed and then shut it down at the end. Think of it more like communicating to a server than a single DLL call. I.e. webservers stay running even if no requests come in so that they can respond quickly when they do.

Same goes for loading in a robofile. Load in one large one and use conditionals or tabs to get different functions at different times using a 'mode' variable. Using this will speed up requests considerably.

Please download the latest RR version as this is what the following vbs version was tested on. Naturally, you will have to change the path information or can update your pas file instead.

rr.Startup wraps the open and connect on a local system.

--//--

set rr=CreateObject("RoboRealm.API.1")

rr.Startup()

rr.Run "off"

rr.LoadImage "source","C:\temp\Kresimir\uB_OMR_Images\Temporary.jpg"

rr.LoadProgram "C:\temp\Kresimir\uB_OMR_Scripts\Barcode_reader.robo"

rr.Run "on"

rr.WaitImage

rr.Run "off"

WV = rr.GetVariable("BarcodeRecognition")

SampleID = rr.GetVariable("BARCODE_2")

PageID = rr.GetVariable("BARCODE")

WScript.Echo "WV:" & WV & " SampleID:" & SampleID & " PageID:" & PageID

rr.Disconnect

--//--

Anonymous 2 years
Thank you very much for you kind reply.

Yesterday I've spent some time reading documentation thoroughly - since I didn't do it before :)
and I've realized I was trying to do things the way they are not meant to be done (just as you said in your reply :).
To answer your question regarding rotation module - it's not because of reading barcode but because of OMR in tables (I make image "correctly oriented" and then perform crop of each of 4 tables and then identifying if some checkmarks exists or not at certain X,Y positions).

The problem arose since I'm getting an image outside RR, deliver image to RR, perform OMR, read OMR results and this is where cycle ends.
Anonymous 2 years
I've read your reply several times. I've made some changes in my Delphi application. Now RR no longer crash or freez but have a problem with getting variable values.

This was my first version:
           SampleID         := RoboRealmOLE.GetVariable('SampleID');
           PageID           := RoboRealmOLE.GetVariable('PageID');
           VersionNumber    := RoboRealmOLE.GetVariable('VersionNumber');
           ProcessingErrors := RoboRealmOLE.GetVariable('ProcessingErrors');
           ProcessStatus    := RoboRealmOLE.GetVariable('ProcessStatus');
           ImageProcessed   := RoboRealmOLE.GetVariable('IMAGE_PROCESSED');
           ImageCount       := RoboRealmOLE.GetVariable('IMAGE_COUNT');
           ProcessTime      := RoboRealmOLE.GetVariable('PROCESS_TIME');
           RunTime          := RoboRealmOLE.GetVariable('RUN_TIME');

I'm receiving results but with offset of two "variables" [logs.jpg] ... for instance value for SampleID and PageID are empty. VersionNumber gets value which suppose to be in SampleID, ProcessingErrors gets value which suppose to be in PageID etc.

Then I've checked communication log (Options\API Server tab) and there [Debug.jpg] it can be seen that communication between my application and RR is just perfect.

After that I've tried with GetVariables (trying to get SampleID,PageID,VersionNumber,ProcessingErrors,ProcessStatus at once). As you can see [Debug2.jpg] RR received my request correctly and replied correctly too. But in Delphi (VariableResults is of Variant type):

VariableResults  := RoboRealmOLE.GetVariables('SampleID,PageID,VersionNumber,ProcessingErrors,ProcessStatus');

Returned just one value - 5 (as you can see in [Logs2.jpg]).

I thought that there is something wrong with Delphi so I've run small "TCP Chat" application, made a connection to RR (TCP port 6060) and sent same message sequence as I have seen in RR API Message log. And again RR received correctly all my messages and replied correctly  - but most of replies did not reach TCP Chat application. It almost looked like RR API writes reply messages to message log but never send them back to TCP Chat - is that possible?


     
Kresimir Majdenic from Croatia  [38 posts] 2 years
In previous Delph application I call RoboRealmOLE.GetProgram (I've wanted to check if correct robo file is loaded in RR in order to avoid loading robo file for every image analysis).

After I've removed that line returning of variables values finally run correctly. Now I get all variables, correctly.

Is there any other way of checking which robo file is currently loaded?
Steven Gentner from United States  [1371 posts] 2 years
Kresimir,

We'll check to see if there is an issue with GetProgram but that is probably not what you wanted anyhow. The GetProgram will literally return back the XML loaded in RoboRealm as apposed to the name of the currently loaded file.

For that, you can get the variable ROBO_PATH or ROBO_NAME or ROBO_LABEL which will indicate the name of the currently loaded robofile.

We normally will load in a single robofile at the start of the connection and only reload if the connection fails for some reason. Otherwise, one can assume that the loaded robofile is always present unless you specifically request it to be deleted. Using a state or mode variable (calling different tabs) we get different functionality from a single robofile without having to worry about reloading.

STeven.
Steven Gentner from United States  [1371 posts] 2 years
Kresimir,

If you continue to use the GetVariables (plural) you may need to specify a specific element that you want to read. Getting a '5' back which is the length of the array that is returned is probably a reasonable result if you don't specify an index into the array. This now does matter what language one is using the COM object in. The COM object will pass back an array of variant values which will be interpreted by the containing language in different ways (arrays are always a bit tricky in COM). In our case, WScript will return an error on the result if you don't specify an index. So

list = rr.GetVariables("X,Y,Z)

WScript.Echo list

will error but

WScript.Echo list(0)

will print out the value of the first variable X.

STeven.
Kresimir Majdenic from Croatia  [38 posts] 2 years
Once again thank you for your reply. I've done some changes according to your suggestions. It runs but I do not get results always.
For instance:
- I start RoboRealm and load robo file and image file
- Run my delphi test application, connect to RR and run robo file
- In RR GUI I can see that it has been started but returned values are empty
- When I check what RR wrote into Variables.txt file (at the end of robo file) it's empty in first run

Now, I manually run (pressing run button in GUI) and mark each and every module ... and after I select the last module, run my delphi app again ... then I get all values correctly.

I must be missing something important. This time I've attached robo file, image file, a small drawing of how I thought execution flow goes and even executable of my test application.

Is it possible that you take a look and see what is wrong?

Best regards.

RoborealmTest.zip
RoborealmTest - exe.zip
Kresimir Majdenic from Croatia  [38 posts] 2 years
I've put BEEP at the end of Main pipeline (just before EXIT) so that I can hear every time one cycle ends.
I think that my problem is due to new image not being loaded when Delphi application send request LoadImage and/or program not being run when delphi application send Run('on').
The thing is that I can process let's say 50 images without any problem and then happens several attempts with no correct reply/behaviour of RR (I get no reply [GetVariables] or reply with empty values)

1. Is there anything I can do to make sure that RR loaded new image?
2. New image is always saved under the same name and at the same place (I replace files) - could that be a problem to RR - always the same name?
3. Since the name of file is always the same - is it better to put module LoadImage at the begining of pipeline?
4. how to be sure when Delphi calls

Run('on')
WaitImageFor(2500)
Run('off')

that LoadImage module loaded image and that "fresh" results are got out of that new image?

Best regards.
Kresimir Majdenic from Croatia  [38 posts] 2 years
Sorry for being so persistent ...

I've tried to call Run('off') twice in a row
- first time function run('off') returned 0
- second time it returned -1
Is it suppose to be that way?

Similar happens with Run('on') too
- first 3 times function returned -1
- forth time 0
- fifth time -1
- sixth time 0
- etc.

Is that has something to do with the fact that my pipeline ends with EXIT?
Kresimir Majdenic from Croatia  [38 posts] 2 years
I've solved the problem.

Complete redesign of a robo file helped a lot. Furthermore I've realized that sometimes it takes several cycles before RR recognize all elements on image (as oppose to my first assumption that it shall be done in a single pass).

Once again, thank you very much for your suggestions.
Steven Gentner from United States  [1371 posts] 2 years
Kresimir,

It should be all done in a single pass unless there is a tracking option enabled.

The issues you saw in the previous post were due to the Write_Variables option. There was an option missing that allowed variables to be written DESPITE being the same value each time. Inherent in the module was a change check that would NOT write any new entries in the file UNLESS there were changes in any of the values.

Since this was not clear it has been moved to a visible option that you can disable. If you download the latest version and uncheck this option you should get an entry in every file each time the system is run.

Note, the Exit at the end of the pipeline doesn't really do anything ... will also cause the image not to update if you happen to have a live camera feed.

STeven.
Kresimir Majdenic from Croatia  [38 posts] 2 years
Thank you for explaining about write_variables.

I've tried with tracking option turned OFF but then it does not work correctly. Number of found objects (markers) changes from one cycle to another. Sometimes it finds first one, sometimes second one, sometimes both (I need them both to be found).
Steven Gentner from United States  [1371 posts] 2 years
Would you be able to post the robofile, template image (the image you are search for) and test image (the image you are searching on) so that we can attempt to replicate this? Or are those the same files in your other post?

STeven.
Kresimir Majdenic from Croatia  [38 posts] 2 years
Template image [TemplateImage - 02.jpg] and test image [ToAnalyze - 02.jpg] are attached.

  

This forum thread has been closed due to inactivity (more than 4 months) or number of replies (more than 50 messages). Please start a New Post and enter a new forum thread with the appropriate title.

 New Post   Forum Index