As part of the SGVHAK Air Hockey Project I have been working on Python code to track the puck and predict its location. As part of the prediction algorithm I chose to use a 2D physics library to be more sophisticated than just using Snell's law and ray casting to predict bounces off the table walls. I started off by adapting a Python air hockey game I found on Github. I separated the code into a part that handles the table walls and puck as the simulation component. I made the rest of the game, the pieces that interact with Pygame, live in a separate class. I did this so that the pure physics pieces could be used separate from the game itself. I also hooked the game into the vision object detection system by pulling frames from the Pygame buffer. When I got to the point of using the Pixy camera I only used the simulation part and things seemed to work fine on my laptop.

After finally getting the Pixy working on the Raspberry Pi recently, I tried to test my simulation code on it. I have the ability to use my software with OpenCV and a USB camera but I thought the Pi too slow for that and delayed testing on it until I could use the Pixy. The Pixy sends back coordinate information and does not place any intense computational requirements on the Pi running the air hockey code as OpenCV does. The game I had adapted uses Pymunk which is an encapsulation of the Chipmunk 2D Physics library. But, when running the code on the Raspberry Pi I found that the simulation part did not work. One of the walls was present in the simulation, but everything else failed. It turns out I wasn't the only one having this problem. For whatever reason, Pymunk fails royally on the Raspberry Pi. See the following IPython session:

In [1]: import pymunk
Loading chipmunk for Linux (32bit) [/usr/local/lib/python2.7/dist-packages/pymunk/libchipmunk.so]

In [2]: static_body = pymunk.Body()

In [3]: static_lines = [pymunk.Segment(static_body, (150, 100.0), (50.0, 550.0),3.0),
   ...:                 pymunk.Segment(static_body, (450.0, 100.0), (550.0, 550.0), 3.0)]

In [4]: for line in static_lines:
   print line.a, line.b
   ...:
Vec2d(150.0, 100.0) Vec2d(50.0, 550.0)
Vec2d(1.50604665224e-314, 1.00642933657e-304) Vec2d(1.5060476799e-314, 1.00654059241e-304)

As you see above, the second line segment looks like uninitialized values. My best guess, without actually haven looked into it too much, is that there are some architecture specific assumptions that work fine on 32 bit and 64 bit x86 machines, but not on the Raspberry Pi. I know Chipmunk has been used on Arm systems, but I believe the fault lies in the bindings.

Instead of debugging the library I decided to convert my simulation code to Box 2D using the pybox2d bindings. After reading their entire manual and a couple days of work I succeeded. Finally, I had something that works on the Raspberry Pi. I have kept the Pymunk based game to use for testing. Using two different Physics engines gives me a small amount of assurance that I can predict the path using a non incestuous simulation method during testing. I did not remove any of the old Pymunk stuff, instead I have added the Box2D capabilities as new options. One day when our physical table gets built maybe the code will finally be put to use.