loading
 
Serial Sequence
Tim Bateson from United Kingdom  [22 posts]
8 years
In the serial communications console area i am sending the code

\x10\xff\xef\x80\x80\x80\x80

This simulates a triangle button, works correct.

I have created a mini vBscript

size=GetVariable("COG_X")
if size < 100 then
SetVariable "Left", "\xe7\xff\xf8\x80\x80\x60\x80"
else
SetVariable "Left", "\x20\xff\xff\x80\x80\xa0\x80"
end if

This changes the variable Left when i move the blue ball in front of camera so all good there

In the sequence window of the serial i add my variable Left and it doesnt send out either of the strings above, totally different data.

I presume this is a conversion issue but i have tried different formats of the data and i am struggling to get the correct sequence data to output.

Any help please??
Tim Bateson from United Kingdom  [22 posts] 8 years
Im in a rut now!!!

I am currently using a lynxmotion HR3 robot which is a 6 legged hexapod with a basic atom running the PS remote code from serial commands.  It put double backslash above but single sends codes in the serial console and my robot responds either with movement or action (AS predefined in the basic atom code).

All i want to establish is that when the COG value is less or greater than a number the hex 7 digit code to make it move left or right is sent serially to my robot.  I am trying to do this as above using a Variable "Left".

Is this the best way as i have been trying for about 2 week now to no avail at all.  How should i create a variable and how should i include it in the Send Sequence box?  Or can i write the direct serial command out into a VbScript.

Please advice as anything might just stop me throwing my laptop and robot out the window!!!!

Thanks
Anonymous 8 years
Tim,

The variables are not processed in the same way as the direct text. I.e. it is assumed that the actual value to be sent is contained in the variable. Thus you have to use the direct binary values in the variable in order for it to send out binary values. For example use ...

SetVariable "Left", chr(231) & chr(255) & chr(248) .... etc.

as apposed to the hex \ denotation. The hex denotation is used since it is very difficult to type in binary characters into the text area ... but constructing a binary variable is not (relatively speaking).

Hope this helps ...

Thanks for the donation!

STeven.
Tim Bateson from United Kingdom  [22 posts] 8 years
That is fantastic!!!!!!
Thanks a lot.
Just one more thing and im all done for now..........
If the variable left above moves it left and right, if i need to move it fwd and back as well, how do i send 2 lots of info?

Do i just add the variables in the send sequence window with a <cr> between them?
Anonymous 8 years
Yes, you could do that but it would probably be better just to append the second movement to a single variable. In other words after you've used the chr(x) for the first sequence use a chr(13) which is what a <cr> translates to and then continue with the next sequence. In that way your serial interface is just a single variable. The reason this is better is that if your second variable is not used then a extra <cr> would be printed for no reason.

Also note that your hardware needs to support this kind of sequence. If the hardware waits on one command before executing the next then this will also not work very well. Sometimes you'll have to use single a diagonal command in order to move left and forward ... but that will be revealed by the above test.

STeven.
Tim Bateson from United Kingdom  [22 posts] 8 years
size= GetVariable("COG_X")
SetVariable "Move" , chr(000)&chr(255)&chr(255)&chr(128)&chr(128)&chr(128)&chr(128)&chr(13)
if size < 80 then
SetVariable "Move" , chr(231)&chr(255)&chr(248)&chr(128)&chr(128)&chr(096)&chr(128)&chr(13)
elseif size>120 then
SetVariable "Move" , chr(032)&chr(255)&chr(255)&chr(128)&chr(128)&chr(160)&chr(128)&chr(13)
end if

Distance=GetVariable("COG_BOX_SIZE")
if Distance >40 then
SetVariable"Distance",chr(064)&chr(255)&chr(191)&chr(128)&chr(128)&chr(128)&chr(128)&chr(13)
else SetVariable "Distance", chr(000)&chr(13)
end if

This is my basic code, i tried ur solution.  If i am at any stage apart from inbetween 80 and 120 on the move variable (ie do nothing) then no matter if the distance is >40 it wont send the command while the move variable is kicking out a signal.

Is there an easy solution as they both work exactly how i want individually!

Thanks
Tim Bateson from United Kingdom  [22 posts] 8 years
Quick note to above

If i change the 3rd line of the box size variable SetVariable Move etc and remove the next line else... then it overwrites whatever the move variable is doing but if there is a better way id appreciate a nudge in that direction!!
Anonymous 8 years
What is in your serial module? I.e. what is the send sequence text?

Perhaps you could include your entire robofile?

STeven.
Tim Bateson from United Kingdom  [22 posts] 8 years
Hi Steven

Attached is my robo.file

I have attached a H3R lynxmotion robot with a serial command set instead of the PS2 controller.  I have hijacked the code so if i send for example

chr(231)&chr(255)&chr(248)&chr(128)&chr(128)&chr(096)&chr(128)&chr(13)

this makes the robot rotate till my blue ball is back in the centre of the camera.

I am happy the codes work.  So the vbscript attached rotates the robot depending on the COG_X which is great.  However at the moment using the COG_BOX_SIZE i want eventually to get the robot to walk upto or away from the ball depending on distance.  My problem is unless the move variable is in

chr(000)&chr(255)&chr(255)&chr(128)&chr(128)&chr(128)&chr(128)&chr(13) in which case i just send my data worked out by the latter half of the vbscript to my move variable.  But if the move is in any off the other 2 states, obviously the latter info is not sent.

Can you advice a way around as it works exactly how i want it, just need more than one variable outputted serially.

Thanks for your time
program.robo
Tim Bateson from United Kingdom  [22 posts] 8 years
And on top of the above

I am thinking of being able to localize my robot once i have cracked the above.  Triangulation etc

Any ideas on how i can go about this, i was obviously thinking 3 objects, maybe 2 other coloured balls to go with my blue.  But how can i process the info to get the position of my robot relative to the objects?

initial ideas would be rotating to view the 3 objects and working out the distance and then somehow calculating the positon of the camera?

Or maybe using 2 cameras, facing front and back and calculate ??

just wondered if you had any ideas as obviously my project is based on your software.

Thanks
Anonymous 8 years
Tim,

thanks for the robofile as that helped us determine what the issue might be. In your VBScript file you had set two "Move" variables depending on the distance. The first SetVariable would set Move and the second SetVariable would then reset Move to the new code overwriting the first SetVariable. That doesn't work very well since the first part is just lost. A better way to do it is to make the Move variable contain both commands simply by appending on onto the other using an '&'. Note that the way this works is that the Move command is not used until the serial module is encountered so you can set and reset the Move variable as many times as you want in the VBScript module without it effecting anything ... the only valid value of Move would be what it happens to be once the VBScript module ends and the Serial module starts. (Keep in mind that modules are run one after another and not all simultaneously).

Attached is the tweaked robofile. Can you try that and see if that works better?

STeven.
program.robo
Tim Bateson from United Kingdom  [22 posts] 8 years
I have viewed your new script (below)

size= GetVariable("COG_X")
if size < 50 then
  SetVariable "Move" , chr(231)&chr(255)&chr(248)&chr(128)&chr(128)&chr(096)&chr(128)&chr(124)&chr(255)&chr(255)&chr(128)&chr(252)&chr(128)&chr(128)
elseif size>150 then
  SetVariable "Move" , chr(032)&chr(255)&chr(255)&chr(128)&chr(128)&chr(160)&chr(128)&chr(124)&chr(255)&chr(255)&chr(128)&chr(252)&chr(128)&chr(128)
else
  SetVariable "Move" , chr(000)&chr(255)&chr(255)&chr(128)&chr(128)&chr(128)&chr(128)
end if

did i not already have this??

That will move the robot left, right or stay stil depending on the COG_X value.  I want it to move back and forward depending on COG_BOX_SIZE as well as left, right.  Thus 2 commands sent serially so if the COG_X produces A and COG_BOX_SIZE produces B, i need to send A and B.

Tim Bateson from United Kingdom  [22 posts] 8 years
I see the change now, you have added the 7 bits onto the 7 bits but obv i have left
right
nothing (neutral)

and the 2nd 7 is
forward
back

Therefore say <50 i have it above moving left (always) and backwards but that wont always be the case as it could be left and forwards.  So this wont fix my variable problem??

Can i do something along the lines of making a new variable distance based on COG_BOX_SIZE as well as one based on COG_X
if size<50 and distance<100 then.....
move left and back.
If size<50 and distance>100 then.....
move left and fwd


Thanks for your help
Anonymous 8 years

Tim,

Yes, that can work, using both the box_size and the X you can create more complex movements. Just string them along in ONE SetVariable statement such that the serial module gets all those bits together. Note that programming motion control code is tricky ... so be patient and if things get too confusing break it down into simple trial cases (i.e. north, south, east, west and then add northeast, northwest, etc.) but, again, always be sure to keep appending the bits as apposed to overwriting them.

STeven.
Tim Bateson from United Kingdom  [22 posts] 8 years
size= GetVariable("COG_X")
dist= GetVariable("COG_BOX_SIZE")

if size < 50 & dist > 50 then
  SetVariable "Move" , chr(231)&chr(255)&chr(248)&chr(128)&chr(128)&chr(096)&chr(128)&chr(124)&chr(255)&chr(255)&chr(128)&chr(252)&chr(128)&chr(128)
elseif size > 150 & dist < 50 then
  SetVariable "Move" , chr(032)&chr(255)&chr(255)&chr(128)&chr(128)&chr(160)&chr(128)&chr(168)&chr(255)&chr(255)&chr(128)&chr(040)&chr(128)&chr(128)
elseif size > 150 & dist > 50 then
  SetVariable "Move" , chr(032)&chr(255)&chr(255)&chr(128)&chr(128)&chr(160)&chr(128)&chr(124)&chr(255)&chr(255)&chr(128)&chr(252)&chr(128)&chr(128)
elseif size <50 & dist <50 then
  SetVariable "Move" , chr(231)&chr(255)&chr(248)&chr(128)&chr(128)&chr(096)&chr(128)&chr(168)&chr(255)&chr(255)&chr(128)&chr(040)&chr(128)&chr(128)
else
  SetVariable "Move" , chr(000)&chr(255)&chr(255)&chr(128)&chr(128)&chr(128)&chr(128)
end if


Does this look ok?  I dont get errors when running it but the move variable does not seem to change on ball movement

Note

chr(000)&chr(255)&chr(255)&chr(128)&chr(128)&chr(128)&chr(128) = Neutral
chr(231)&chr(255)&chr(248)&chr(128)&chr(128)&chr(096)&chr(128) = Left
chr(032)&chr(255)&chr(255)&chr(128)&chr(128)&chr(160)&chr(128) = Right
chr(124)&chr(255)&chr(255)&chr(128)&chr(252)&chr(128)&chr(128) = Back
chr(168)&chr(255)&chr(255)&chr(128)&chr(040)&chr(128)&chr(128) = Fwd

Thanks
Tim Bateson from United Kingdom  [22 posts] 8 years
And just to really get my moneys worth ha

Triangulation i mentioned - i have been looking at the documentation on Calculate distance.  Im thinkin if i have 2 fixed objects then if i can calculate the distance of them, i.e a triangle and a square then somehow (Not quite thought beyond this bit yet!) i can work out how far my robot is relative to the 2 objects?

Am i flying down the wrong path??
Anonymous 8 years
Tim,

One problem at a time ...

I'd probably simpify the logic a little and make the robot turn and when within range then move forward/backward. (Also remember that & is a bitwise operator as apposed to 'AND' in basic) This logic would be a little easier to test.. something like:

x = GetVariable("COG_X")
s = GetVariable("COG_BOX_SIZE")

mx = GetVariable("IMAGE_WIDTH")

if x < mx - 30 then
  SetVariable "Move" , chr(231)&chr(255)&chr(248)&chr(128)&chr(128)&chr(096)&chr(128)
elseif x > mx + 30 then
  SetVariable "Move" , chr(032)&chr(255)&chr(255)&chr(128)&chr(128)&chr(160)&chr(128)
elseif s > 150 then
  SetVariable "Move" , chr(124)&chr(255)&chr(255)&chr(128)&chr(252)&chr(128)&chr(128)
elseif s <50 then
  SetVariable "Move" , chr(168)&chr(255)&chr(255)&chr(128)&chr(040)&chr(128)&chr(128)
else
  SetVariable "Move" , chr(000)&chr(255)&chr(255)&chr(128)&chr(128)&chr(128)&chr(128)
end if


Note that you had incorrectly used

if size < 50 & dist > 50 then

which should be

if size < 50 and dist > 50 then

and I think you also confused size and dist ... I think they should have been the other way around. Thus our change of those vars just to be sure.

Note the usage of 60 pixels around the middle of the screen (note that middle is width/2 and most likely NOT 50) to allow the robot to move forward/backward. If this is too big then reduce that size.

STeven.

Tim Bateson from United Kingdom  [22 posts] 8 years
Yes i agree that is simpler.  I understand what you have said.

When i run this script, the image width never changes, value is always 640 so not a lot happens.

But in the first instance because x is always <mx +30 as it never changes from 640 it works great.

Am i missing something as i presume the image width should change as i move the ball towards the camera
Tim Bateson from United Kingdom  [22 posts] 8 years
Also i want too display on screen a variable telling me how far away the object is.  I presuming i need a little vbscript to do this, would this be related to above and i would use the variable "image height" and do a little calculation, as that stays at the same value also.

Thanks
program.robo
Tim Bateson from United Kingdom  [22 posts] 8 years
I realise the image width and height is now the resolution set by the camera.
So obv with the above in mind, the image size is always greater than the ball size so only triggers the one movement of my robot.

I also have realised i am trying to over complicate things and i just want the distance of the ball displayed on the screen.  Thinking more about it, if i create a table so that say COG_SIZE is looked at

If it is 10-20 the ball is set 10cm away

If it is 20-30 the ball is set 20cm away

If it is 30-40 the ball is set 30cm away

do you think this would work as i have 5 days to nail this (No pressure!)
Anonymous 8 years
Tim,

Correct. Sorry for the confusion, IMAGE_WIDTH and IMAGE_HEIGHT are the dimensions of the webcam image and not the object in question. Yes, you have the technique correct, you can use the COG_SIZE to calculate the distance to an object. You can determine this by sampling at various intervals the size and distance of the ball.

Keep in mind that the curve is an exponential one of the form y = a(x^b) where ^ means x to the power of b.

You can read more about that on page 70 of

http://millrace.uoregon.edu/kinpubs/elecprod/PE4748Modi(18-2).pdf

STeven.
Tim Bateson from United Kingdom  [22 posts] 8 years
THANKS

That is some read!

Ive more or less cracked distance i think.

Below is my other script as suggested by you with a tweak or two.  As i said, as mx is always 640, x is never greater than mx +30, so never gets past the first line, which works fine by the way.  How can i get it to do what i am trying to do?

x = GetVariable("COG_X")

s = GetVariable("COG_BOX_SIZE")

mx = GetVariable("IMAGE_WIDTH")

if x < mx - 30 then
  SetVariable "Move" , chr(127)&chr(255)&chr(255)&chr(128)&chr(128)&chr(255)&chr(128)
elseif x > mx + 30 then
  SetVariable "Move" , chr(078)&chr(255)&chr(248)&chr(128)&chr(128)&chr(255)&chr(128)
elseif s > 150 then
  SetVariable "Move" , chr(124)&chr(255)&chr(255)&chr(128)&chr(252)&chr(128)&chr(128)
elseif s <80 then
  SetVariable "Move" , chr(168)&chr(255)&chr(255)&chr(128)&chr(040)&chr(128)&chr(128)
else
  SetVariable "Move" , chr(000)&chr(255)&chr(255)&chr(128)&chr(128)&chr(128)&chr(128)
end if


Thanks Steven
Anonymous 8 years
Tim,

Opps, my bad, mx is meant to be 1/2 of the width of the image as in "middle x". Please correct the line to read

mx = GetVariable("IMAGE_WIDTH") / 2

i.e. add the /2.

That should help!
STeven.
Tim Bateson from United Kingdom  [22 posts] 8 years
That works great for anyone following this thread!  

Last question and im happy with my progress, for my triangulation i have worked out the correct maths on paper.  Works a treat.

My equation states to work out my
x coord = (r1^2-r2^2+d^2)/(2*d)
and for my
y coord = ( (r1^2-r3^2+i^2+j^2)/(2*j) ) - (i/j)*x

This gives me my correct values.  For short term im going to set my variables as fixed numbers so say

Set Variable "r1", 2
Set Variable "r2", 4

Does this seem ok and is the above equations in the correct format for VBscript??
Tim Bateson from United Kingdom  [22 posts] 8 years
Ill answer my own question, that worked fine!

The only trouble is when my object is very close to the camera it wont pick it up properly hence no COG measurements so it stops my distance calc working.  Have you seen this before and is there anything i can introduce for it??
Anonymous 8 years
Tim,

Yes, that is a common problem as you approach the camera the object will start to get darker as it will shades the camera. You could increase the lighting shining from directly behind the camera but this will cause the object to become more white as it approaches the camera. Any possibility not to move the object so close?

Also, we're assuming a lot here on what the image looks like. If the above doesn't seem to make sense post an image of when the COG gets lost and we can better suggest a possibility.

STeven.
Tim Bateson from United Kingdom  [22 posts] 8 years
Thats exactly what i have done, as soon as the ball is within 40cm i display distance as N/A as i do also when there is no COG measurement.  

It also rotates both ways depending on the COG X value and moves back and forth depending on the COG SIZE measurement.

I also have added a localization co-ordinate equation based on the distance from 3 fixed points by using the COG SIZE to calculate distance using my 5th order polynomial equation.

Unfortunately i have to input the distances manually as i cant think of a way to make the robot rotate and pick out the 3 objects in its 360 degrees vision and record COG SIZE.  But it achieves localization and displays.  It also displays the distance to the ball.

All in all a success, be it not perfect!
Tim Bateson from United Kingdom  [22 posts] 8 years
Any ideas why my program works fine on my laptop at 640 x 480 and then why i transfer the program too my mini dell laptop so it can sit on my robot is really struggles to process filtered image?

Is it just a RAM issue, i.e the 1GB difference as on the mini i have halved the resolution and still to no avail
Anonymous 8 years
Tim,

Check the frame rate of the dell before executing the pipeline. Most likely the camera is not getting enough light and causes the pipeline to be really slow.

Also have a look at the FAQ surrounding this issue:

http://www.roborealm.com/FAQ.php#q20

We tried your robofile from above and get about 12 fps on the Mini-Dell netbook. What fps are you getting?

STeven.
Tim Bateson from United Kingdom  [22 posts] 8 years
I have 15 now, i have no explanation for this but after a full days fault finding, i needed to change the physical com port setting from COM 5 to COM 7.  This then works, cant seem to find an explanation after looking around but it has fixed the problem!

One last thing (3 days to go!!)

For my triangulation, that works when i fix the variables, is there anyway you can think to rotate the robot (I know the command to rotate) and record the COG_BOX_SIZE values of 3 blue fixed circles located at 3 fixed points?

I cant think how the script can be wrote so it knows when to record a COG_BOX_SIZE while rotating never mind 3 COG_BOX_SIZES.

Thanks for all your help by the way, peace in 3 days!
i can send you the completed .robo file if you want it for any further issues like mine

Tim

Anonymous 8 years
I assume that by record you mean just keep in memory? How about this code in a VBScript module:

list = GetArrayVariable("cogs")

ReDim list(ubound(list)+1)

list(ubound(list)) = GetVariable("COG_BOX_SIZE")

SetArrayVariable "cogs", list

which would create an ever increasing array called cogs that has all the values in it.

Alternatively you could also use the Write_Variable module to write the value for each frame to disk ...but that would require another app to open and process it.

STeven.
Tim Bateson from United Kingdom  [22 posts] 8 years
Yeah i was looking at the array function, im not swept up on Vbscript but i have been looking in the microsoft library

If i put this in my script i get the cogs variable created but no data ever goes in it.

Ive read up on everything u have mentioned, am i missing another module or do i need to change some names?

I only want to store 3 COG_BOX_SIZES and the rest my script can be altered no problem
Anonymous 8 years
Tim, if you post your robofile here with what you have so far we can help you get that running ... without a context the above is the best we can offer. Integrating that into your script should just require a name change of the variable array you are creating and perhaps the COG_BOX_SIZE if you are renaming that variable ...

STeven.
Tim Bateson from United Kingdom  [22 posts] 8 years
ist = GetArrayVariable("cogs")

ReDim list(ubound(list)+1)

list(ubound(list)) = GetVariable("COG_BOX_SIZE")

SetArrayVariable "cogs", list

Needs to be added again as i took it out.

My code rotates depending on COG_X and moves fwd and back depending on COG_BOX_SIZE.

The rest uses the formulas that calculate the co-ordinates of the robot against 3 fixed set point.  The r1, r2 and r3 values i want to be able to calculate autonomously by working 3 distances by 3 stored COG_BOX_SIZE objects

Here it is...


program.robo
Anonymous 8 years
Tim,

Ok, so do I understand you correctly. You want to track 3 object at the same time and then use the position of those 3 objects in a position calculation? the above code was meant to record a single COG_BOX_SIZE over time ... if you want 3 COG_BOX_SIZE at the same time you need to use 3 instances of the Center of Gravity module followed by a Set_Variable module to rename COG_BOX_SIZE to some other temp variable (say box1) in order for the next COG module not to override it. Just before each COG module you probably would want to use the Marker module to restore the image to the original pixels such that you can reprocess it for another object. For example, your pipeline would look something like

RGB Filter red
COG
Set_Variable box1 = COG_BOX_SIZE
Marker (restore to original)
RGB Filter blue
COG
Set_Variable box2 = COG_BOX_SIZE
Marker (restore to original)
RGB Filter green
COG
Set_Variable box3 = COG_BOX_SIZE

STeven.

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