I got this 3 yr-old code for OpenCV to track a face and send the coordinates to an Arduino. I've confirmed that my Arduino is using com3. But as stated above, I'm getting a Name error telling me that 'serial' is not defined and so won't establish a connection to com3. I'm way too inexperienced with MRL to know how to chase down the serial function, so I'm asking for help.

And fyi, on the serial tab, I get a redline message at the bottom saying there'd been an IO exception, could not open COM3, rate 115200 baud, when I've specified 57600 baud in the code. ANd I can't open the port there, either.

I'm including the code and the output portion of the Java messages that are relevant. Look for the highlighted code:

------------

 # create or get a handle to an OpenCV
opencv = Runtime.createAndStart("opencv","OpenCV")
# Convert the video to Black and White
opencv.addFilter("Gray1", "Gray")                             
# Sometimes gray seems to help# reduce the size - face tracking doesn't need much detail. The smaller the
opencv.addFilter("PyramidDown1", "PyramidDown")
# add the face detect
opencv.addFilter("FaceDetect1", "FaceDetect")
opencv.capture()

#create a Serial service named serial
serialserial = Runtime.createAndStart("serial","Serial")

# This function is called every time the OpenCV service has data available.
# This will depend on the framerate of the video, but will probably be
# somewhere around 15 times a second.
def input():
    global x
    global y
    global sposx
    global sposy
    global posx
    global posy

    # Get OpenCV data
    opencvData = msg_opencv_publishOpenCVData.data[0]

    if (opencvData.getBoundingBoxArray().size() > 0) :    # If the box surrounding a face exists
     rect = opencvData.getBoundingBoxArray().get(0)       # Store the information in rect
     posx = rect.x                                        # Get the x position of the corner
     posy = rect.y                                        # Get the y position of the corner
 
     w = rect.width                                       # Get the width
     h = rect.height                                      # Get the height
     sposx = (w/2)
     sposy = (h/2)
     # Get the x and y of the center in pixels. Origin is in top left corner
     x = (posx + sposx)  
     y = (posy + sposy)
     
     # Convert x,y pixels to (x,y) coordinates from top left.
     # Note that 320 and 240 will need to be changed if another pyramid down is used
     # It may also need to be changed depending on your cameras specifications.
     # This gets the position in a scale from 1, 100
     x = int(translate(x, 1, 320, 1, 100));                  # translate() works the same way the Arduino map() function would
     y = int(translate(y, 1, 140, 1, 100));
     print 'x: ' ,  x                                        # print x to the python readout
     print 'y: ' ,  y                                        # print y to the python readout
     #write a series of bytes to the serial port
     serial.write(250) # pan code
     serial.write(x)   # x coordinate
     serial.write(251) # tilt code
     serial.write(y)   # y coordinate

serial.connect("COM3", 57600, 8, 1, 0) <--- this is line 93
#sometimes its important to wait a little for hardware to get ready
sleep(1)          # Note that this is 1 full second.

# create a message route from opencv to python so we can see the coordinate locations
opencv.addListener("publishOpenCVData", python.name, "input");

# Start capturing video
opencv.capture()  # Add a 1 inside the parenthesis to use camera 1

# Create function to scale values. Mimics Arduino map() function.
def translate(value, leftMin, leftMax, rightMin, rightMax):
    # Figure out how 'wide' each range is
    leftSpan = leftMax - leftMin
    rightSpan = rightMax - rightMin

    # Convert the left range into a 0-1 range (float)
    valueScaled = float(value - leftMin) / float(leftSpan)

    # Convert the 0-1 range into a value in the right range.
    return rightMin + (valueScaled * rightSpan)

--------------------------------------

...
[python.interpreter.4] [WARN] no such method Runtime.registered(Serial) :  - attempting upcasting
[python.interpreter.4] [WARN] searching through 254 methods
[gui] [WARN] no such method GUIService.registered(Serial) :  - attempting upcasting
[python.interpreter.4] [INFO] loading class: org.myrobotlab.serial.PortJSSC
[python] [WARN] no such method Python.onRegistered(Serial) :  - attempting upcasting
[gui] [WARN] searching through 192 methods
[python] [WARN] searching through 172 methods
[python] [INFO] exec(String)
from org.myrobotlab.service import Serial
serial = Runtime.getService("serial")
[webgui] [WARN] no such method WebGui.onRegistered(Serial) :  - attempting upcasting
[webgui] [WARN] searching through 189 methods
[webgui] [INFO] subscribe [serial/publishStatus ---> webgui/onStatus]
[webgui] [INFO] subscribe [serial/publishState ---> webgui/onState]
[AWT-EventQueue-0] [INFO] subscribe [serial/publishStatus ---> gui/getStatus]
[serial] [INFO] loading class: org.myrobotlab.serial.PortJSSC
[gui] [WARN] no such method SerialGUI.onPortNames(ArrayList) :  - attempting upcasting
[gui] [WARN] searching through 53 methods
[python.interpreter.4] [ERROR] python error PyException - null Traceback (most recent call last):
  File "<string>", line 93, in <module>
NameError: name 'serial' is not defined

    at org.python.core.Py.NameError(Py.java:284)
    at org.python.core.PyFrame.getname(PyFrame.java:257) ...
 

 

calamity

7 years 11 months ago

hi

in your script the variable 'serial' is not defined, that why the error happen

in the beginning of your script, you have

serialserial = Runtime...

so the script generate error because you name your variable 'serialserial' instead of simply 'serial'