After discussion on the PyPy dev e-mail alias, it seems that to get PyPy performance, I need to change GPIO and RPIO from using the CPython ‘C’ API to using CFFI to call the GPIO / RPIO ‘C’ code from PyPy (or CPython come to that). It’s the CPython ‘C’ API that’s the performance hog for anything but CPython. But it’s not entirely clear to me how to use CFFI on the GPIO / RPIO ‘C’ code. I don’t think it’s tricky – but I’m ignorant so there’s a lot of learning to do. I think some googling’s needed to find some examples.
There’s a plan B though: kitty uses an OS FIFO to read data from the picamera on a separate thread while the camera thread is still filming. This works well. I could do the same thing, moving motion processing to a separate thread (though it’ll probably need to be a process due to the GIL) and feed it sensor data over a FIFO. The motion process just waits on a select() for the next batch of sensor data, and processes it (taking ~ 3ms) while the next batch of sensor data is collected and averaged (taking ~ 10ms). No data is lost, and timing is wholly driven by the MPU sampling rate. I’m pretty certain this could work.
But that lead me to realize there’s a dirty, no, absolutely filthy and perhaps despicable hack I can do. The motion processing is consistently taking just over 3ms. If I add that time to the 10ms taken to sample the sensors 10 times, then assuming the sensor readings in those 10 samples are pretty consistent (I’m assuming this already to some extent by averaging them), then including the 3ms for motion processing will make the velocity integration more accurate when there is acceleration. Essentially it’s interpolating the 3 missing samples lost during motion processing based upon the average of the 10 that were collected successfully. I could also do the same for missed data samples.
So I tried it out, and after a few minor tweaks, it worked. I wanted to get a video to back up all these boring words, but by then, her main LiPo was running low, and she got all wibbly wobbly at that point. I’ll try later when it’s up to full charge again.
So for now, dirty will do nicely, though I do intend to try the FIFO method too, initially with threads to get the code working, and then I’ll move over to using processes which is a little bit trickier.