I was trying to become more aquainted with MRL as a user and had some questions. I thought I would create a thread to save the answers for posterity.
First, I was trying the keyboardinput example (HERE). Long story short, it doesn't seem to work. Being unexperienced I don't really know why. It appears input() is never being called, but the keyboard commands appear in the java window.
Upon executing the example I get the readout below.
22632 [python] INFO org.myrobotlab.service.Python - exec #file : Keyboard.input.pykeyboard = Runtime.createAndStart("keyboard", "Keyboard")python.subscribe("keyCommand", keyboard.getName(), "input")print "subscribed"def input():#never gets hereprint "input()"# print 'python object is ', msg_[service]_[method]cmd = msg_keyboard_keyCommand.data[0]print 'python data is ', cmdif (cmd == "A"):print "hello A !"elif (cmd == "B"):print "hello B !"22739 [Thread-10] INFO class org.myrobotlab.service.Runtime - loader for this class sun.misc.Launcher.AppClassLoader22745 [Thread-10] INFO class org.myrobotlab.service.Runtime - parent sun.misc.Launcher.ExtClassLoader22750 [Thread-10] INFO class org.myrobotlab.service.Runtime - system class loader sun.misc.Launcher$AppClassLoader@6bad186f22756 [Thread-10] INFO class org.myrobotlab.service.Runtime - parent should be nullsun.misc.Launcher.ExtClassLoader22760 [Thread-10] INFO class org.myrobotlab.service.Runtime - thread context sun.misc.Launcher.AppClassLoader22761 [Thread-10] INFO class org.myrobotlab.service.Runtime - thread context parent sun.misc.Launcher.ExtClassLoader22764 [Thread-10] INFO class org.myrobotlab.service.Runtime - refreshing classloader22769 [Thread-10] INFO class org.myrobotlab.framework.Service - %s loading %d non-routable methods22779 [Thread-10] INFO class org.myrobotlab.net.CommunicationManager - instanciating a org.myrobotlab.net.CommObjectStreamOverTCP22782 [Thread-10] INFO class org.myrobotlab.service.Runtime - returning org.myrobotlab.service.Keyboard22784 [python] INFO org.myrobotlab.service.Python - exec from org.myrobotlab.service import Keyboardkeyboard = Runtime.getServiceWrapper("keyboard").service22803 [python_outbox_0] ERROR class org.myrobotlab.net.CommunicationManager - Runtime.getServiceWrapper could not return keyCommand.addListener for sender python22858 [keyboard] INFO class org.myrobotlab.framework.Service - adding addListener from keyboard.publishStatus to gui.getStatus23040 [gui] INFO org.myrobotlab.control.ServiceGUI - buildGraph23044 [gui] INFO org.myrobotlab.control.ServiceGUI - buildLocalServiceGraph-begin23045 [gui] INFO org.myrobotlab.control.ServiceGUI - GUIServiceGUI service count 423051 [gui] INFO org.myrobotlab.control.ServiceGUI - buildLocalServiceGraph-end23069 [gui] INFO org.myrobotlab.service.GUIService - org.myrobotlab.control.TabControl[,249,3,53x16,alignmentX=0.0,alignmentY=0.0,border=,flags=8388608,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,horizontalAlignment=LEADING,horizontalTextPosition=TRAILING,iconTextGap=4,labelFor=,text=keyboard,verticalAlignment=CENTER,verticalTextPosition=CENTER]
Thanks in advance.
-Matthew
Hi Matthew.... I just fixed
Hi Matthew.... I just fixed the script..so refresh Keyboard service page, test it and let us know if it works for you... :D
Ciaooo
Thanks Alessandruino. It
Thanks Alessandruino. It works fine now.
My next question is in regards to the Serial.asciiToChar.py example. I was trying to mimic Grog's blog post by connecting my arduino to MRL and printing some data in the python window. I changed the COM port to the correct one for my Arduino and deleted the write stuff at the bottom. When I execute it, it says that the COM port is opened, but I don't see any data. If I connect Tera Term or the Arduino Serial Monitor I see it just fine.
I looked in the Serial javadoc but didn't see anything about the read method.
Also, when I stop the python script, close Serial, and then restart the script it it gives me an error. I have to restart MRL for it to work again.
Hope this helps
As for the "NameError: name 'sleep' is not defined" error, did you include the "import time" at the top of the script? I'm guessing that's where the sleep function/method comes from.
I have played with that example as well and although I can see data in the Serial "tab" that gets opened in the WebGui (are you using WebGUI or the old application GUI?) I don't see any of the data back in the the Python console. I'm not sure if I messed it up or if it was broken.
So you have an arduino hooked
So you have an arduino hooked to the computer... And you would like to See serial data sent from what? Arduino is sending serial data?
kmcgerald, the strange thing
kmcgerald, the strange thing is that I do have the import time there. No errors the first time I run it, but if I stop it and run it again I get the error. It is just a direct copy from the Serial page except I removed the bottom where it writes stuff.
I was using the application GUI. Like you say, the python readout stays empty. On the WebGUI I don't even see the serial service. Wether I start the WebGUI before or after executing the python script, it never appears. I also tried running the script from the WebGUI python page without success.
Alessandruino, at the moment the Arduino is sending a number to the computer. Basically I was just trying to get MRL to display any data that comes in over serial in the python window.
in which way Arduino is
in which way Arduino is sending a number?are you using an Arduino sketch? btw it is normal that you have errors when you stop script...because in reality script never stops :D so there are sorts of "bad overwriting"...python doesn't like them...so you have to restart mrl or close all services before to restart script...
oh...in your Arduino sketch
oh...in your Arduino sketch are you sending at the same baud of MRL serial service? (9600 baud for example?)
if you could post arduino sketch, and MRL debug would be great!!
Hi Matthew
Thanks for posting the questions in a post - it helps everyone ...
It looks like your trying all sorts of things which is great, even the WebGUI (you are brave!).
I know some of the confusion you may have to do with the concept of "stopping" a script.
Script just change the state of MRL which is always running - rarely would you have the opportunity to stop a script - they run very fast and do things like open up serial connections, poll data, change stuff, etc.
So if one script opens a serial connection, and you "stop" the script - you can bet the serial connection is still open.
Additionally, the serial connection has always been a pain, especially when it comes to closing ports. Unfortunately, it is the nature of the RXTXLib
A no-worky might shed some light on the problem now, maybe the sketch your using too
Interesting about the script
Interesting about the script never stopping, but here are all my sketches. I used 57600 as the baud in both cases.
Here is my Arduino sketch. (on Arduino Mega 2560 r3)
Grog, I'll send a no-worky. I just figured it was operator error and didn't know if that warrented one.
Except I did not have debug
Except I did not have debug on when I got that last one. Ok here's the real debug. The no static route message just repeats at the end.
It's Still Under Development :D
Your repeating publishByte - is a method which is getting called everytime you print. Its just not displaying :)
Here is a script which should work for you - change the COM port of course :)
The Serial.print is doing the ascii equivalent of 12 - so you should see it as 2 bytes (49 &50)
If you want to "see" a 12 - then you have a couple options, you can change your Arduino sketch to do Serial.write(12) instead of Serial.print(12) and it won't go through the ascii conversion, or you can change the pyhton "print data" to "print unichr(data)" .. its software - there's a bazillion ways to do the same thing :D
Also in the script I put a if not connected then connect - which is nice for "re-running the script".
In the future there will be a simple "read" - but at the moment its completely event driven - when there is a byte it is "published" for all listeners
Let us know if it works for you ;)
Success
Ah yes. That script does work. Now I'll try the other direction.
Also, the unichr() does work in that it displays a 1 and then a 2. Is there an easy way to combine the 2 bytes back into an int? Or is that work for the future? I know I've seen sketches for it in Arduino C, but I didn't know if there was something built in.
Thanks for your help!
Wouldn't you rather change
Wouldn't you rather change your sketch to do a Serial.write(12) instead of a Serial.print(12) ?
There's less conversions on both side then :)
Yeah. 12 was just arbitrary.
Yeah. 12 was just arbitrary. I was just wondering in case I wanted to send bigger numbers.
Ya - you can send 0 - 255 :)
Bigger than that and you have to put them together byte by byte... or ascii char by char... :)
I'm working on several other methods - but they aren't ready yet...
publishChar publishInt publishLong publishByteArray publishString
Right. I was trying to do
Right. I was trying to do that myself, but it was not working.. Surprises there. Ha. I'll probably just wait for your methods.
My attempt.
I am curious as to your
I am curious as to your project.. could you elaborate?
At the moment I was just
At the moment I was just trying to figure out how MRL works.
There is no particular project in mind at the moment. What I would like to do is create a sort of plug-and-play OpenCV script that I just outputs x and y coordinates of a face, tracker point, etc via serial that could then be modified from the OpenCV GUI without much knowledge of Python. This would allow anyone with a little bit of Arduino (or any other microcontroller I suppose) to get vision processing without having to know the ins and outs of OpenCV.
I was looking for an easy vision processing interface that could be plugged into existing projects and MRL seemed to be it. The questions about the keyboard service and such were just me trying to figure out how all this works.
Ok, :) Did you look at the
Ok, :)
Did you look at the face tracking scripts - some of them output to an Arduino the pan and tilt coordinates for tracking with servos.
I saw a few of them. They
I saw a few of them. They all appear to use the Arduino service. I wanted to avoid that and just use straight serial so it could be plugged into existing Arduino projects/sketches.
Hopefully, I will be able to copy a lot of that work that has already been done. I remember seeing several cool find face sketches a while ago. I hope to look more into it this weekend when I get some time.
Ok GroG (or anyone else). I
Ok GroG (or anyone else). I have another debug for you. First, here's what it's supposed to do.
Open a serial port with an Arduino. Start opencv and add 2 filters. It should find a face and send the location to python where it will find the center of the box. It will then change the coordinates to a scale from 1-100 instead of 1-320 or 1-240. Then it will write an identifier for pan and write the pan coordinate. Then same for tilt.
I will send a no-worky. I figure it's probably a combination of python errors and calling the wrong methods for opencv. I mostly copied the Tracking.face.py example.
Matthew i noticed 2 issues
Matthew i noticed 2 issues :
x = translate(x, 1, 320, 1, 100);
with
x = int(translate(x, 1, 320, 1, 100)) ;
y = int(translate(y, 1, 240, 1, 100));
This will force x,y value to an int
2. you have to replace this opencv.addListener("publishOpenCVData", python.name, "input",OpenCVData().getClass());
with this one opencv.addListener("publishOpenCVData", python.name, "input");
Let us know if it works for you...
Your Back ! ;) Well first
Your Back ! ;)
Well first -
opencv.addListener("publishOpenCVData", python.name, "input", OpenCVData().getClass());
complains that it OpenCVData wants at least 1 input for the constructor...
the "addListener" or "subscribe" is supposed to be "type parameter aware" - but really isn't - so you can leave the parameter defintion off :P ... someday I may implement it - but not anytime soon
change it to
opencv.addListener("publishOpenCVData", python.name, "input");
Those changes appear to fix
Those changes appear to fix it. Something in the transfer to the Arduino didn't seem to be working, but I haven't really wrung that part out yet.
Should the addListener code be changed in those examples? Or is it something with my particular use of it that I don't need the last parameter? That line was a direct copy from the facetracking example, and I noticed a few others had it as well.
I would take them out...
I would take them out... right now its a simple name mapping
"foo" ---will map to ---> "bar" .. if the return type of foo and the input type of bar are incompatible you'll get a runtime error..
the last parameter was really supposed to help when there was an overloaded "bar" .. say one which takes Integers and another which takes Strings ...
you could differentiate it .. but now in retro-spect .. who wants that added complexity ? - the framework should figure it out for you.. so that we humans only need to specify the method names we want linked together ;)
Well I have had success. It
Well I have had success. It isn't what I would call done, but it will track a face. Here is the code I am running at the moment. It is still a work in progress.
MRL:
I have had a bit of a problem with it thinking other objects are faces. I am going to tweak things and play around with filters to try and improve it. In a cluttered, poorly lit dorm room I may just have to deal with it.
Now another question. I found
Now another question. I found in one of the examples how to set the inrange filter, but it doesn't appear to be working. What is the correct way to do this? This is what I have.