|
Serial Sequence Tim Bateson from United Kingdom [22 posts] |
14 year
|
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] |
14 year
|
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 |
14 year
|
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] |
14 year
|
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 |
14 year
|
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] |
14 year
|
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] |
14 year
|
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 |
14 year
|
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] |
14 year
|
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] |
14 year
|
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 |
14 year
|
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] |
14 year
|
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] |
14 year
|
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 |
14 year
|
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] |
14 year
|
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] |
14 year
|
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 |
14 year
|
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] |
14 year
|
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] |
14 year
|
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] |
14 year
|
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 |
14 year
|
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] |
14 year
|
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 |
14 year
|
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] |
14 year
|
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] |
14 year
|
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 |
14 year
|
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] |
14 year
|
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] |
14 year
|
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 |
14 year
|
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] |
14 year
|
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 |
14 year
|
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] |
14 year
|
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 |
14 year
|
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] |
14 year
|
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 |
14 year
|
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.
|
|