Hi, i'm working on a project as part of my studies that involves building and programming a sentry gun. I have a prototype built and tested with R/C and i have no problem tracking stuff when the camera is static (mounted on the chassis or next to the rig).
What i want to do is be able to attach the camera to the 'barrel', so it moves with it. This way i avoid having to map and re-map servos in accordance to distance, angles, etc. As long as the target stays in the center of the aquired image, i can assume that the aim is correct.
What i'm doing now is dividing the image into 3 'zones', left, centre and right, and panning a camera strapped to a servo in relation to where the target is located. Here's the issue i'm having - When the target reaches the center of the image, the camera keeps rotating until the target is at the opposite end, switches direction, and repeats the process. I'd appreciate it if someone could tell me what i'm doing wrong or missing, and if there's an alternative way of doing it.
I'm using the Arduino module and an arduino nano for servo control.
* When the camera is supposed to stop, as an imput for the servo i provide a reading of its current position, so it just stops.
Solved! Go to Solution.
1) you are not initialising any of your feedback nodes - this means you are probably 1 case behind where you think you are
2) replace your feedback nodes with shift registers - it makes the BD more readable.
3) in your first Mathscript Node you have not closed the parenthese after defining rawy - have you checked what this is doing to your loop
4) NEVER do =0 or !=0 on a DBL datatype (or SGL or EXP) it can produce results with tiny numbers or big numbers
5) the for loop iteration count For 1 iteration in the case structure is a waste of space
6) it would be easire to see what was going on if you chaged the input to the case structiure to an Enum and passed that value out of the second matchscript node - I suspect you are getting stuck in the second node some how. - i.e. rawx is DBL so what happens when it is between 0 an 1, or 419 and 420 or 799 and 800. Try using the Comparison palette to give yourself more easily debuggable code.
(I don't have the Realtime toolkit installed so I can go any deeper than the main VI)
Thanks for the reply, James.
I'm using the feedback nodes as a means of retaining the last known non-zero values, can a shift register be used to do the same? If there is no target currently on the screen, X and Y values are set to zero, instead of there being no data at all.
After changing the data types to integers, swapping the feedback on the servo read with a shift register, and fixing the =0 line in mathscript, the problem persists. The case strucutres switch accordingly, but even when the target is centered and the servo value is being retained(the value reading is being input as the set value), incrementing continues until the opposite case occurs. Then the servo moves in the opposite direction and continues zig-zagging instead of stopping.
What if i replaced the whole case structure with some more lines in mathscript? Instead of incremnting/decrementing, move the servo to an angle determined by the difference between the center value and the current target value, with some treshold. For instance: with an image width of 1000 pixels and an acceptable aim being within 50px from the center, the script would substract current target position from image center position (e.g. 800-500=300px to the right) and move the servo, lets say, 1 degree for each 20 pixels - 15 degrees(300px) to the right - so the two coincide(with a margin of error of 50px). Do the substraction for every new image and adjust accordingly. I'm sorry if this is too confusing, it's hard for me to put down in words..
You might want to try like Tracking Radar does Use a Quadraint (4 areas) Box . Then use the feed back from the 4-way adding and subtracking steps from the servos. I worked on a tracking Radar FPS-79 and it used the feed horn 4 different areas to discriminate the movement and control the servoes. If you get what i mean.
1) Yes Feedback nodes and Shift registers do the same thing, shift registers sit on the edge of a loop and are generally better programming practice.
2) You have not quite understood what I meant about initialising them - if on the first loop you have an image, what is the initial data starting point of the Feedback node? you have not initialised it so it may be the value when the VI last ran, of it may be something else if the VI has been reloaded into memory - you NEED to know for your loop to work as you are relying on the last value being "Something" to compare it to.
3) Please, Please, Please replace your Mathscript nodes with more basic functions from the numeric, structures and comparison palletes - your code runs slower with mathscript nodes and is actually more difficult to read for basic functions like this - you arte showing your text based programming background.
Yes - we have both missed the most obvious part. When you picture is Centred on the target you want to Stop the While loop (don't you?), currently you are only stopping when Stop is pressed or an error occurs. You will always move if you do not handle the "Do not move - I am on target" case!!
(Reposting updated code may help us help you!)
I agree with 22V10, I believe that splitting into quadrants is necessary, you may be in the correct field horizontally but not vertically as you never adjust your tilt reading so you could expect to be panning from side to side if you ar not tilted on the correct angle to start with!
Further to the "Never compare SGL, DBL EXP to 0 / !0, if you coerce the number to the closest integer AND you are not working with complex numbers you should be OK.
Please find attached my updates to your VI (removed mathscript nodes) and added shift registers - noticed while doing this that you do not know the initial starting position of the Pan and Tilt - this will be affected by the range of your servos and is something you should consider as you might get to the edge of your rotation and try to drive the camera too far.
Hope this helps
James, thank you very much for the VI, now i understand what you meant by initialising the shift registers. You're right about my text-based programming background, and seeing how you've implemented the case selection really helped. The removal of the mathscript modules does reduce lag quite a lot, too, and now everytihng works exactly as it should. I set the initial servo positions and rawx/rawy values, extended the error line the way you suggested, and added a division by two after the array summation, in order to get an average, rather than a near-double result.
I agree with you and 22v10 that slicing the image up into quadrants might have been a better idea to begin with. The 'center band' that is set in the current vi works quite well and i'll stick with it for now, since i won't have much more time to work on this project.
I avoided adding tilt for now because i thought it would only complicate things. Now that panning works, i've duplicated the method and adjusted it for tilt.
I'm also considering removing the Vision Assistant nodes, since for calibration purposes i need to go into it and create new templates from scratch every time, and this will only get more tedious as i start experimenting with more complex 'targets'. A more viable solution is presented here, where everything is set once the application is launched.
Please find attached an updated copy of the VI. It's a bit laggy, i'll continue working on it and updating.
James, thank you again for providing a working solution. I'd love to give you credit when the project's finished.
nearly there What I meant with the comment about the Type def you can see in the screen shot below - you can see that this makes the code much easier to read than before. - Also you need to watch out for the red coercion dots - chenge the representation or numbers to elimnate this, but be careful what you change - Last time I loaded the VI I had to change the representation of the constants from the default DBL to SGL, now the output of your subVI is DBL they need to be changed back again.
Finally - try an reuse as much of the code as you can with SubVIs - you will note that the Array of "N" to Angle Adjustment funciton is the same for both X and Y, it could be put in a SubVI with different constants as inputs making your loop much smaller and easier to read!