Pixy2

We're using the Pixy 2 camera for the Hubble challenge. It can also be used for line following, but we're not going to be using that.

The Pixy2 can be taught up to 7 colour signatures and, through the python or C++ API will give a list of any objects it can see that match the colour signatures.

For teaching objects, either the PixyMon application can be installed - or you can press and hold the button on the top of the camera itself. The led will cycle through 7 colours to indicate which signature to record. When you release the button on the appropriate signature, then the led shows the approximate colour of the object it is looking at. Pressing the button again records the signature.

The PixyMon application, which can be built and run on the Pi - or on Windows - allows you to actually see the image and select the object you want to track using the mouse, so is more accurate. We're hoping to use this method on the day - connecting to the Pi using Remote Desktop.

This link gives a lot of information on recording the signatures:

https://docs.pixycam.com/wiki/doku.php?id=wiki:v2:teach_pixy_an_object_2

Building the code on the Raspberry Pi for Python 3

The Pixy2 code is provided as open source on github.

This page describes how to install the pre-requisite software and build the Python examples.

https://docs.pixycam.com/wiki/doku.php?id=wiki:v2:building_libpixyusb_as_a_python_module_on_linux

However - the python build will generate code that can only be used with Python2.

To build the python demos for use in python3, the following changes need to be made.

  • pixy2/scripts/build_python_demos.sh

Change the call to python to python3:

     29 cd ../src/host/libpixyusb2_examples/python_demos
     30
     31 swig -c++ -python pixy.i
     32 python3 setup.py build_ext --inplace -D__LINUX__
     33
     34 if [ -f ../../../../build/python_demos/_pixy.so ]; then
     35   rm ../../../../build/python_demos/_pixy.so
     36 fi
  • pixy2/src/host/libpixyusb2_examples/python_demos/setup.py

Change the print statements to have parenthesis:

     20 import os
     21 print ("dir = ")
     22 print (os.path.dirname(os.path.realpath(__file__)))
     23

Once this has been done, the pixy2/scripts/build_python_demos.sh script can be run.

For some reason this returns failure - I'm not sure why - but if you then go into the pixy2/build/python_demos folder and run the demos. They'll need to be fixed for python3 to add parenthesis around the print statements - but that is all.

Lighting the Lamp

Annoyingly, the makers of the Pixy2 decided not to allow the lamp to be switched on and off through the python interface.

The C++ method is described on this page:

The API uses SWIG to allow a python application to interface to functions in a C++ library. After digging around I found that the main files that implement this are the SWIG interface file (pixy.i) and the C++ python interface file (pixy_python_interface.cpp) which actually defines the functions that can be called from python. I found I needed to make the following changes to allow the lamp to be lit:

  • pixy2/src/host/libpixyusb2_examples/python_demos/pixy_python_interface.cpp

Add the following function definition (in bold) to this file:

     11 int change_prog (const char *  program_name)
     12 {
     13   return pixy_instance.changeProg (program_name);
     14 }
     15
     16 void set_lamp(int upper, int lower)
     17 {
     18     pixy_instance.setLamp(upper, lower);
     19 }
     20
     21
     22 int get_frame_width ()
     23 {
     24   return pixy_instance.frameWidth;
     25 }

  • pixy2/src/host/libpixyusb2_examples/python_demos/pixy.i

Add the following interface (in bold) for the set_lamp function:

     24 /*!
     25   @brief       Select active running program on Pixy
     26   @param[in]   program_name  "color_connected_components"  Block detection program
     27                              "line"                        Line feature detection program
     28 */
     29 extern int change_prog (const char *  program_name);
     30
     31 /*!
     32   @brief        Set Lamp
     33   @param[in]    upper   1 = lamp on, 0 = lamp off
     34   @param[in]    lower   1 = lower LED all white
     35 */
     36 extern void set_lamp(int upper, int lower);
     37
     38 /*!
     39   @brief       Gets the Pixy sensor frame width.
     40   @return      Returns Pixy sensor width (in number of pixels) that is being sent to the host.
     41 */
     42 extern int get_frame_width ();

Now we just need to run the scripts/build_python_demos.sh script again to rebuild the python demos with the set_lamp function exposed.

Below shows the modified get_rgb_demo.py script with the call to switch on the upper lamps:

      1 import pixy
      2 from ctypes import *
      3 from pixy import *
      4
      5 # Pixy2 Python SWIG get Red/Green/Blue example #
      6
      7 print ("Pixy2 Python SWIG Example -- Get Red/Green/Blue")
      8
      9 pixy.init ()
     10 pixy.change_prog ("video");
     11 pixy.set_lamp(1,0);
     12
     13 X = 158
     14 Y = 104
     15 Frame = 1
     16
     17 while 1:
     18   RGB = video_get_RGB (X, Y)
     19   print ('Frame %d RGB: ' % (Frame))
     20   print (RGB)
     21   Frame = Frame + 1