<< return to Pixycam.com

python and set servos not working

(edit - I forgot to mention which version of python I’m using - it’s 2.7)

I’m trying to follow objects with the pan/tilt servos via python and I’m kinda stumped. I had it working fine on a raspberry pi 3, but I’ve switched to another ARM platform - an odroid C2 running a fairly lean Debian Jessie. The pantilt_in_c works fine - it controls the servos and follows an object, so I know that there’s nothing wrong with my pixy or my servos or my computer hardware. It works straight out of the “build_pantilt_c_demo.sh” gate.

The pan_tilt.py code has a couple of bugs, but I had to fix those when on the raspberry pi, and they’re not the issue. The issue is I’m getting the following (also tried this as root):

$ python pan_tilt.py 
+ Pixy Tracking Demo Started +
frame 0:
Error: pixy_rcs_set_position() [-152] 
Pixy Error: Invalid command

The servos never budge when that pixy_rcs_set_position() function is called, and it’s returning a -152 which I figure means something like “I tried to move the servo and I couldn’t”.

I also tried this on a completely other OS - the official full-blown-bloated Ubuntu, got the exact same result.

The build of the python module appears to have worked fine. It did issue few warnings about unusued variables, signed/unsigned integer comparisons, and “warning: deleting object of polymorphic class type ‘ChirpReceiver’ which has non-virtual destructor might cause undefined behaviour [-Wdelete-non-virtual-dtor]”.

Anywho… I’m stumped. Has anyone here got any suggestions? Otherwise, I’m going to have to result to having python issue shell commands to get the thing following in C, and then parse the results to get the X:Y positions of the servos so that the python code can then do things based upon where the pixy is looking.

For what it’s worth, This will fix the syntax errors from a misnamed variable in the pan_tilt.py source:

sed -ie "s/\([^_]\)result/\\1set_position_result/" pan_tilt.py

Thanks very much for any advice.

This may be a bit much, but here’s the result of my build. I’d be interested in knowing if any of these warnings are critical.


$ ./build_pantilt_python_demo.sh
mkdir: cannot create directory ‘/home/nshaver/build/pixy/build/’: File exists

Building libpixyusb SWIG module

running build_ext
building 'pixy’ extension
creating build
creating build/temp.linux-aarch64-2.7
creating src
creating src/common
creating src/common/src
creating src/host
creating src/host/libpixyusb
creating src/host/libpixyusb/src
creating src/host/libpixyusb/src/utils
aarch64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC -D__LINUX
_=1 -I/usr/include/libusb-1.0 -I/usr/local/include/libusb-1.0 -I…/…/src/common/inc -I…/…/src/host/libpixyusb/src/utils -I…/…/src/host/libpixyusb/include -I/usr/include/python2.7 -c pixy_wrap.cxx -o build/temp.linux-aarch64-2.7/pixy_wrap.o
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
aarch64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC -D__LINUX__=1 -I/usr/include/libusb-1.0 -I/usr/local/include/libusb-1.0 -I…/…/src/common/inc -I…/…/src/host/libpixyusb/src/utils -I…/…/src/host/libpixyusb/include -I/usr/include/python2.7 -c …/…/src/common/src/chirp.cpp -o build/temp.linux-aarch64-2.7/…/…/src/common/src/chirp.o
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
…/…/src/common/src/chirp.cpp: In member function ‘int Chirp::setLink(Link*)’:
…/…/src/common/src/chirp.cpp:100:83: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
m_buf = (uint8_t )m_link->getFlags(LINK_FLAG_INDEX_SHARED_MEMORY_LOCATION);
^
…/…/src/common/src/chirp.cpp: In member function ‘int Chirp::recvFull(uint8_t
, ChirpProc*, bool)’:
…/…/src/common/src/chirp.cpp:1274:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
if (res<sizeof(uint32_t))
^
…/…/src/common/src/chirp.cpp: In member function ‘int Chirp::recvData()’:
…/…/src/common/src/chirp.cpp:1342:9: warning: ‘res’ may be used uninitialized in this function [-Wmaybe-uninitialized]
if (res<(int)chunk+3)
^
aarch64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC -D__LINUX__=1 -I/usr/include/libusb-1.0 -I/usr/local/include/libusb-1.0 -I…/…/src/common/inc -I…/…/src/host/libpixyusb/src/utils -I…/…/src/host/libpixyusb/include -I/usr/include/python2.7 -c …/…/src/host/libpixyusb/src/pixy.cpp -o build/temp.linux-aarch64-2.7/…/…/src/host/libpixyusb/src/pixy.o
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
…/…/src/host/libpixyusb/src/pixy.cpp: In function ‘int pixy_get_firmware_version(uint16_t*, uint16_t*, uint16_t*)’:
…/…/src/host/libpixyusb/src/pixy.cpp:435:16: warning: unused variable ‘chirp_response’ [-Wunused-variable]
int chirp_response;
^
aarch64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC -D__LINUX__=1 -I/usr/include/libusb-1.0 -I/usr/local/include/libusb-1.0 -I…/…/src/common/inc -I…/…/src/host/libpixyusb/src/utils -I…/…/src/host/libpixyusb/include -I/usr/include/python2.7 -c …/…/src/host/libpixyusb/src/chirpreceiver.cpp -o build/temp.linux-aarch64-2.7/…/…/src/host/libpixyusb/src/chirpreceiver.o
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
aarch64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC -D__LINUX__=1 -I/usr/include/libusb-1.0 -I/usr/local/include/libusb-1.0 -I…/…/src/common/inc -I…/…/src/host/libpixyusb/src/utils -I…/…/src/host/libpixyusb/include -I/usr/include/python2.7 -c …/…/src/host/libpixyusb/src/pixyinterpreter.cpp -o build/temp.linux-aarch64-2.7/…/…/src/host/libpixyusb/src/pixyinterpreter.o
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
…/…/src/host/libpixyusb/src/pixyinterpreter.cpp: In member function ‘void PixyInterpreter::close()’:
…/…/src/host/libpixyusb/src/pixyinterpreter.cpp:70:12: warning: deleting object of polymorphic class type ‘ChirpReceiver’ which has non-virtual destructor might cause undefined behaviour [-Wdelete-non-virtual-dtor]
delete receiver_;
^
…/…/src/host/libpixyusb/src/pixyinterpreter.cpp: In member function ‘int PixyInterpreter::get_blocks(int, Block*)’:
…/…/src/host/libpixyusb/src/pixyinterpreter.cpp:90:42: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
number_of_blocks_to_copy = (max_blocks >= blocks_.size() ? blocks_.size() : max_blocks);
^
…/…/src/host/libpixyusb/src/pixyinterpreter.cpp: In member function ‘void PixyInterpreter::interpret_CCB1(const void**)’:
…/…/src/host/libpixyusb/src/pixyinterpreter.cpp:222:18: warning: unused variable ‘index’ [-Wunused-variable]
uint32_t index;
^
…/…/src/host/libpixyusb/src/pixyinterpreter.cpp: In member function ‘void PixyInterpreter::interpret_CCB2(const void**)’:
…/…/src/host/libpixyusb/src/pixyinterpreter.cpp:245:18: warning: unused variable ‘index’ [-Wunused-variable]
uint32_t index;
^
aarch64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC -D__LINUX__=1 -I/usr/include/libusb-1.0 -I/usr/local/include/libusb-1.0 -I…/…/src/common/inc -I…/…/src/host/libpixyusb/src/utils -I…/…/src/host/libpixyusb/include -I/usr/include/python2.7 -c …/…/src/host/libpixyusb/src/usblink.cpp -o build/temp.linux-aarch64-2.7/…/…/src/host/libpixyusb/src/usblink.o
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
aarch64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC -D__LINUX__=1 -I/usr/include/libusb-1.0 -I/usr/local/include/libusb-1.0 -I…/…/src/common/inc -I…/…/src/host/libpixyusb/src/utils -I…/…/src/host/libpixyusb/include -I/usr/include/python2.7 -c …/…/src/host/libpixyusb/src/utils/timer.cpp -o build/temp.linux-aarch64-2.7/…/…/src/host/libpixyusb/src/utils/timer.o
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
c++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-z,relro -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wl,-z,relro -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security build/temp.linux-aarch64-2.7/pixy_wrap.o build/temp.linux-aarch64-2.7/…/…/src/common/src/chirp.o build/temp.linux-aarch64-2.7/…/…/src/host/libpixyusb/src/pixy.o build/temp.linux-aarch64-2.7/…/…/src/host/libpixyusb/src/chirpreceiver.o build/temp.linux-aarch64-2.7/…/…/src/host/libpixyusb/src/pixyinterpreter.o build/temp.linux-aarch64-2.7/…/…/src/host/libpixyusb/src/usblink.o build/temp.linux-aarch64-2.7/…/…/src/host/libpixyusb/src/utils/timer.o -lboost_thread -lboost_system -lboost_chrono -lpthread -lusb-1.0 -o /home/nshaver/build/pixy/build/pantilt_in_python/_pixy.so


Build complete

To run the get_blocks libpixyusb SWIG example execute the following commands:

cd …/build/pantilt_in_python
python pan_tilt.py

In anticipation of perhaps the first question that an expert here might ask, I’ve put some debugging into the python script to see exactly what it’s sending to pixy_rcs_set_position(channel, position). Here’s what it spits out when I wave my tennis ball in front of it, with that debugging:

+ Pixy Tracking Demo Started +
c:p 0:500
c:p 1:500
c:p 0:546
c:p 1:503
c:p 0:552
c:p 1:573
c:p 0:568
c:p 1:611

So, it appears to be sending valid values (between 0 and 1000) for channel (0 and 1) to the set function.

I found where the -152 is defined - common/inc/pixydefs.h:

#define PIXY_ERROR_INVALID_COMMAND          -152

That error is only referenced in code in one place - host/libpixyusb/src/pixyinterpreter.cpp:

int PixyInterpreter::send_command(const char * name, va_list args)
{
  ChirpProc procedure_id;
  int       return_value;
  va_list   arguments;

  va_copy(arguments, args);

  // Mutual exclusion for receiver_ object (Lock) //
  chirp_access_mutex_.lock();

  // Request chirp procedure id for 'name'. //
  procedure_id = receiver_->getProc(name);

  // Was there an error requesting procedure id? //
  if (procedure_id < 0) {
    // Request error //
    va_end(arguments);

    // Mutual exclusion for receiver_ object (Unlock) //
    chirp_access_mutex_.unlock();

    return PIXY_ERROR_INVALID_COMMAND;
  }

I assume that send_command is invoked (in this case) via host/libpixyusb/src/pixy.cpp:111:

  int pixy_command(const char *name, ...)
  {
    va_list arguments;
    int     return_value;

    if(!pixy_initialized) return -1;

    va_start(arguments, name);
    return_value = interpreter.send_command(name, arguments);
    va_end(arguments);

    return return_value;
  }

And that is invoked by that same program (pixy.cpp) at line 396:

  int pixy_rcs_set_position(uint8_t channel, uint16_t position)
  {
    int chirp_response;
    int return_value;

    return_value = pixy_command("rcs_setPos", UINT8(channel), INT16(position), END_OUT_ARGS, &chirp_response, END_IN_ARGS);

   if (return_value < 0) {
      // Error //
      return return_value;
    } else {
      // Success //
      return chirp_response;
    }
  }

So, the thing setting the -152 is doing it because it doesn’t like the name it’s receving in getProc(name), and best I can tell the name that’s getting sent is “rcs_setPos”.

Best I can tell, getProc is defined in the common/inc/chirp.hpp:211:

class Chirp
{
public:
    Chirp(bool hinterested=false, bool client=false, Link *link=NULL);
    ~Chirp();

    virtual int init(bool connect);
    int setLink(Link *link);
    ChirpProc getProc(const char *procName, ProcPtr callback=0);

and getProc is a type “ChirpProc” which is a int16_t.

Ok, I’m not a c programmer, so I’ve pretty much exhausted my ability to track down things. I’ve arrived at wondering why PixyInterpreter::send_command is determining that “rcs_setPos” is an invalid procedure_id. I think device/main_m4/src/rcservo.cpp might be where “rcs_setPos” is defined as a valid proc, and it’s the first one, so perhaps it might ought to be procedure_id number 0.

Long story short… I’m still stumped.

Ok, one more thing that might help someone figure this out - I saw that there’s a “debug” option in the pantilt_in_python script. In order to figure out exactly what “name” and “procedure_id” are when the problem happens, I added some debugging to the program that encounters the error - host/libpixyusb/src/pixyinterpreter.cpp, as follows:

int PixyInterpreter::send_command(const char * name, va_list args)
{
  ChirpProc procedure_id;
  int       return_value;
  va_list   arguments;

  va_copy(arguments, args);

  // Mutual exclusion for receiver_ object (Lock) //
  chirp_access_mutex_.lock();

  // Request chirp procedure id for 'name'. //
  procedure_id = receiver_->getProc(name);
  log("pixydebug: PixyInterpreter::send_command error - name=%s procedure_id=%d \n", name, procedure_id);

  // Was there an error requesting procedure id? //
  if (procedure_id < 0) {
    // Request error //
    va_end(arguments);

    // Mutual exclusion for receiver_ object (Unlock) //
    chirp_access_mutex_.unlock();

    return PIXY_ERROR_INVALID_COMMAND;
  }

I then rebuilt libpixyusb with that new logging, and rebuilt pantilt_in_python with the debug flag. Now when I run it, I can see the following:

pixydebug: PixyInterpreter::send_command error - name=rcs_setPos procedure_id=-1

So, it’s getting a -1 from getProc when it sends “rcs_setPos”. That certainly seems wrong. Here’s the complete output of my debug test run of pantilt_in_python. Still stumped though:

$ python pan_tilt.py 
+ Pixy Tracking Demo Started +
pixydebug: USBLink::open()
pixydebug:  libusb_init() = 0
pixydebug:  libusb_open_device_with_vid_pid() = 8257744
pixydebug:  libusb_set_configuration() = 0
pixydebug:  libusb_claim_interface() = 0
pixydebug:  libusb_reset_device() = 0
pixydebug: USBLink::open() returned 0
pixydebug: Chirp::Chirp()
pixydebug: Chirp::Chirp() returned
pixydebug: Chirp::setLink()
pixydebug: USBLink::send()
pixydebug: USBLink::send() returned 64
pixydebug: USBLink::receive()
pixydebug:  libusb_bulk_transfer(64 bytes) = 0
pixydebug: USBLink::receive() returned 64 (bytes transferred)
pixydebug:  remoteInit() = 0
pixydebug: setLink() returned 0
pixydebug: USBLink::receive()
pixydebug:  libusb_bulk_transfer(64 bytes) = 0
pixydebug: USBLink::receive() returned 64 (bytes transferred)
pixydebug: USBLink::send()
pixydebug: USBLink::send() returned 64
pixydebug: USBLink::receive()
pixydebug:  libusb_bulk_transfer(64 bytes) = 0
pixydebug: USBLink::receive() returned 64 (bytes transferred)
pixydebug: PixyInterpreter::send_command error - name=rcs_setPos procedure_id=-1 
Error: pixy_rcs_set_position() [-152] 
Pixy Error: Invalid command
pixydebug: Chirp::~Chirp()
pixydebug: USBLink::send()
pixydebug: USBLink::send() returned 64
pixydebug: USBLink::receive()
pixydebug:  libusb_bulk_transfer(64 bytes) = 0
pixydebug: USBLink::receive() returned 64 (bytes transferred)
pixydebug: Chirp::~Chirp() returned

Hello Nick,
Sorry for the problems you are having. Just to clarify, you said it worked on the Raspberry Pi 3? (in Python?)

I’m trying to get a good description of how to reproduce. We have some Raspberry Pi’s but no Odroid.

Edward

Hi Edward,

Correct - it did work on raspberry pi just using your stock Linux build scripts. On odroid ARM with Debian Jessie the C pantilt works fine. The python pantilt runs into the issues I detailed above.

Hi Nick,
I asked around and we’re sort of stumped. We agree with your finding that things go off into the weeds at getProc(). But we’re unsure why getProc would fail, especially since setLink() seems to have no problem. The Odroid is little endian I assume. That’s the only explanation we came up with. Can you debug a little further and shed some more light on how getProc is failing?

Edward

Hi Edward,

Thanks for checking around on it. I’m pretty sure all the raspberrys are little endian. I’ll check my odroid c2 when I get home, but I assume it’s probably little too.

I’ll dig in some more, and either figure it out, or get closer to the root of the problem and report back here what I figure out. I’m enjoying learning more about c++ and swig, so it’s time well spent for me.

Nick

Ok, I’ve narrowed it down to one line of code that makes it work on the odroid C2. It only works when pantilt_in_python is built with the debug switch though. I’ve yet to make it work without the debug switch. Here’s what makes it work:

1. checkout fresh copy of source:

$ git clone https://github.com/charmedlabs/pixy.git
Cloning into 'pixy'...
remote: Counting objects: 6761, done.
remote: Total 6761 (delta 0), reused 0 (delta 0), pack-reused 6761
Receiving objects: 100% (6761/6761), 11.49 MiB | 2.51 MiB/s, done.
Resolving deltas: 100% (4362/4362), done.
Checking connectivity... done.

2. modify src/common/src/chirp.cpp - add one debug line in just the right spot. Debugging other spots don’t seem to help:

$ diff -r pixy/src pixy_one_line_fixes_it/src/
diff -r pixy/src/common/src/chirp.cpp pixy_one_line_fixes_it/src/common/src/chirp.cpp
710a711
> 		log(procName);


ChirpProc Chirp::getProc(const char *procName, ProcPtr callback)
{
    uint32_t res;
    ChirpProc cproc = -1;

    if (callback)
        cproc = updateTable(procName, callback);
    log(procName);   //////////////// <<<<<<<<---- THE ONE LINE THAT FIXES IT, LINE 710 <<<<<<<=0)
        return res;

    // a negative ChirpProc is an error
    return -1;
}

3. compile libpixyusb and pan_tilt_python

$ ./build_libpixyusb.sh 
-- The CXX compiler identification is GNU 4.9.2
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Found libusb-1.0:
--  - Includes: /usr/include/libusb-1.0
--  - Libraries: /usr/lib/aarch64-linux-gnu/libusb-1.0.so
-- Boost version: 1.55.0
-- Found the following Boost libraries:
--   thread
--   system
-- Configuring done
-- Generating done
-- Build files have been written to: /home/nshaver/build/pixy/build/libpixyusb
Scanning dependencies of target pixyusb
[ 16%] Building CXX object CMakeFiles/pixyusb.dir/src/chirpreceiver.cpp.o
[ 33%] Building CXX object CMakeFiles/pixyusb.dir/src/pixyinterpreter.cpp.o
[ 50%] Building CXX object CMakeFiles/pixyusb.dir/src/pixy.cpp.o
[ 66%] Building CXX object CMakeFiles/pixyusb.dir/src/usblink.cpp.o
[ 83%] Building CXX object CMakeFiles/pixyusb.dir/src/utils/timer.cpp.o
[100%] Building CXX object CMakeFiles/pixyusb.dir/home/nshaver/build/pixy/src/common/src/chirp.cpp.o
/home/nshaver/build/pixy/src/common/src/chirp.cpp: In member function ‘int Chirp::setLink(Link*)’:
/home/nshaver/build/pixy/src/common/src/chirp.cpp:100:83: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
         m_buf = (uint8_t *)m_link->getFlags(LINK_FLAG_INDEX_SHARED_MEMORY_LOCATION);
                                                                                   ^
Linking CXX static library libpixyusb.a
[100%] Built target pixyusb

-- libpixyusb build complete
--
-- Please run 'install_libpixyusb.sh' as root to install to your system.
nshaver@odroid-jessie64:~/build/pixy/scripts$ sudo ./install_libpixyusb.sh 
[100%] Built target pixyusb
Install the project...
-- Install configuration: ""
-- Installing: /usr/local/lib/libpixyusb.a
-- Installing: /usr/local/include/pixy.h
-- Installing: /usr/local/include/pixydefs.h
nshaver@odroid-jessie64:~/build/pixy/scripts$ ./build_pantilt_python_demo.sh debug
mkdir: cannot create directory ‘/home/nshaver/build/pixy/build/’: File exists
-----------------------------------------
 Building libpixyusb SWIG module
-----------------------------------------
OS is __LINUX__
running build_ext
building '_pixy' extension
creating build
creating build/temp.linux-aarch64-2.7
creating src
creating src/common
creating src/common/src
creating src/host
creating src/host/libpixyusb
creating src/host/libpixyusb/src
creating src/host/libpixyusb/src/utils
aarch64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC -DDEBUG=1 -D__LINUX__=1 -I/usr/include/libusb-1.0 -I/usr/local/include/libusb-1.0 -I../../src/common/inc -I../../src/host/libpixyusb/src/utils -I../../src/host/libpixyusb/include -I/usr/include/python2.7 -c pixy_wrap.cxx -o build/temp.linux-aarch64-2.7/pixy_wrap.o
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
aarch64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC -DDEBUG=1 -D__LINUX__=1 -I/usr/include/libusb-1.0 -I/usr/local/include/libusb-1.0 -I../../src/common/inc -I../../src/host/libpixyusb/src/utils -I../../src/host/libpixyusb/include -I/usr/include/python2.7 -c ../../src/common/src/chirp.cpp -o build/temp.linux-aarch64-2.7/../../src/common/src/chirp.o
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
../../src/common/src/chirp.cpp: In member function ‘int Chirp::setLink(Link*)’:
../../src/common/src/chirp.cpp:100:83: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
         m_buf = (uint8_t *)m_link->getFlags(LINK_FLAG_INDEX_SHARED_MEMORY_LOCATION);
                                                                                   ^
../../src/common/src/chirp.cpp: In member function ‘int Chirp::recvFull(uint8_t*, ChirpProc*, bool)’:
../../src/common/src/chirp.cpp:1274:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         if (res= blocks_.size() ? blocks_.size() : max_blocks);
                                          ^
../../src/host/libpixyusb/src/pixyinterpreter.cpp: In member function ‘void PixyInterpreter::interpret_CCB1(const void**)’:
../../src/host/libpixyusb/src/pixyinterpreter.cpp:222:18: warning: unused variable ‘index’ [-Wunused-variable]
   uint32_t       index;
                  ^
../../src/host/libpixyusb/src/pixyinterpreter.cpp: In member function ‘void PixyInterpreter::interpret_CCB2(const void**)’:
../../src/host/libpixyusb/src/pixyinterpreter.cpp:245:18: warning: unused variable ‘index’ [-Wunused-variable]
   uint32_t       index;
                  ^
aarch64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC -DDEBUG=1 -D__LINUX__=1 -I/usr/include/libusb-1.0 -I/usr/local/include/libusb-1.0 -I../../src/common/inc -I../../src/host/libpixyusb/src/utils -I../../src/host/libpixyusb/include -I/usr/include/python2.7 -c ../../src/host/libpixyusb/src/usblink.cpp -o build/temp.linux-aarch64-2.7/../../src/host/libpixyusb/src/usblink.o
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
aarch64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC -DDEBUG=1 -D__LINUX__=1 -I/usr/include/libusb-1.0 -I/usr/local/include/libusb-1.0 -I../../src/common/inc -I../../src/host/libpixyusb/src/utils -I../../src/host/libpixyusb/include -I/usr/include/python2.7 -c ../../src/host/libpixyusb/src/utils/timer.cpp -o build/temp.linux-aarch64-2.7/../../src/host/libpixyusb/src/utils/timer.o
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
c++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-z,relro -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wl,-z,relro -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security build/temp.linux-aarch64-2.7/pixy_wrap.o build/temp.linux-aarch64-2.7/../../src/common/src/chirp.o build/temp.linux-aarch64-2.7/../../src/host/libpixyusb/src/pixy.o build/temp.linux-aarch64-2.7/../../src/host/libpixyusb/src/chirpreceiver.o build/temp.linux-aarch64-2.7/../../src/host/libpixyusb/src/pixyinterpreter.o build/temp.linux-aarch64-2.7/../../src/host/libpixyusb/src/usblink.o build/temp.linux-aarch64-2.7/../../src/host/libpixyusb/src/utils/timer.o -lboost_thread -lboost_system -lboost_chrono -lpthread -lusb-1.0 -o /home/nshaver/build/pixy/build/pantilt_in_python/_pixy.so

-----------------------------------------
 Build complete
-----------------------------------------

To run the get_blocks libpixyusb SWIG example execute the following commands:

 > cd ../build/pantilt_in_python
 > python pan_tilt.py

4. execute pan_tilt_python

+ Pixy Tracking Demo Started +
pixydebug: USBLink::open()
pixydebug:  libusb_init() = 0
pixydebug:  libusb_open_device_with_vid_pid() = 8293248
pixydebug:  libusb_set_configuration() = 0
pixydebug:  libusb_claim_interface() = 0
pixydebug:  libusb_reset_device() = 0
pixydebug: USBLink::open() returned 0
pixydebug: Chirp::Chirp()
pixydebug: Chirp::Chirp() returned
pixydebug: Chirp::setLink()
pixydebug: USBLink::send()
pixydebug: USBLink::send() returned 64
pixydebug: USBLink::receive()
pixydebug:  libusb_bulk_transfer(64 bytes) = 0
pixydebug: USBLink::receive() returned 64 (bytes transferred)
pixydebug:  remoteInit() = 0
pixydebug: setLink() returned 0
pixydebug: USBLink::receive()
pixydebug:  libusb_bulk_transfer(64 bytes) = 0
pixydebug: USBLink::receive() returned 64 (bytes transferred)
pixydebug: USBLink::receive()
pixydebug:  libusb_bulk_transfer(20 bytes) = 0
pixydebug: USBLink::receive() returned 20 (bytes transferred)
rcs_set                                       ///////////////// ( the output from that one new line of code - the value of procName )
Pospixydebug: USBLink::send()
pixydebug: USBLink::send() returned 64
pixydebug: USBLink::receive()
pixydebug:  libusb_bulk_transfer(64 bytes) = 0
pixydebug: USBLink::receive() returned 64 (bytes transferred)
pixydebug: USBLink::send()
pixydebug: USBLink::send() returned 64
pixydebug: USBLink::receive()
pixydebug:  libusb_bulk_transfer(64 bytes) = 0
pixydebug: USBLink::receive() returned 64 (bytes transferred)\

and so on...

I don’t understand why a single debug line would make things work, but I’m hoping this makes perfect sense to somebody who knows this code, or at least knows c++. Surely this has been seen before.

If I don’t compile pan_tilt_python with the debug switch, that one line of code is no help.
If I don’t make that one line of code change, compiling pan_tilt_python doesn’t work, even with the debug switch.

Edward - will you check with your folks and see if this strange kind-of-fix makes any sense? I feel like I’m really close to having Pixy working on the odroid.

Thanks very much for your help.

Ok, I dug in just a bit more and tried to recreate whatever it is that the log(procName) is somehow fixing in line 710 of src/common/src/chirp.cpp. I saw that the log() function is doing an fflush(stdout), so I tried simply doing that flush. It fixes it just like the log(procName) did. I also figured out that it can do the flush at line 713 rather than 710, but it has to be before the call(CRP_CALL_ENUMERATE, 0,.

I tried to dig into the call and put the flush just a bit deeper, but that didn’t seem to work. I’m guessing at this point that something’s going wrong in the “int Chirp::call(uint8_t service, ChirpProc proc, va_list args)” function.

Hello Nick,
It looks like you shed a good amount of light on the issue – nice work! Unfortunately, it doesn’t make anyone here say “aha!”. Issuing flush to stdout does cause a delay, so that’s the best theory. The root of the issue might be in the USB. Different platforms have some differences in USB functionality.

But please trying replacing usleep(100); to line 710. You might need to also add #include <unistd.h> to the top of the file.

Let me know what you find.

Edward

Hi Edward,

I gave the usleep(100) a try, no help. I may punt and drive the servos from a servo controller that I’m using for the robot. It’s got plenty of spare PWM channels, so there’s nothing really gained by having the pixy move its servos on this particular project. Maybe by the time my next project rolls around, the odroid will be on a newer kernel. It’s stuck back at 3.14 right now, but its processor will have mainline support in the kernel soon, so it’ll be up at 4.whatever. There’s a chance something in the rPi’s 4.x kernel is what’s making the difference between rPi working, and this odroid not working.

Thanks for all your help.

Nick

Hi Nick,
We suspect it’s USB related, but we’ll keep an eye out for similar behavior and post back to this thread if we find anything.

Thanks for your feedback!

Edward