I've been super busy with my distracting day-job; it really requires all day focus and attention, and that means less rover building, which sucks. The interesting aspect of it is that the teams I work with are mix of people with wildly different amounts of technical, project, engineering, and operational experience. This makes for some interesting cross-over with the rover, since there are some basics with all of those things that are almost universal.
But I do have some free time here and there to keep on plugging away on some of the small stuff. I've been avoiding the 'big chunk' - the primary rover logic - until I have enough planned time off to get it done in one slug. So for now - small stuff.
One example I recently knocked off was the camera system, and an attempt to make thumbnail images small, and also predictably small. I'd thought about just using whatever imagemagick outputs as downsized jpegs, but I found they don't always end up 'small'. The reason for 'predictably small' is that I'd decided to split the radio communications into a separate module, and I wanted the radio itself capable of buffering a bit of uplink/downlink data without the rover being 100% powered on. There is a type of memory called FRAM, or Ferroelectric RAM, which is easy to use and fairly roomy; Adafruit has an I2C interfaced 32kB module that looks about right.
I decided to carve up the memory roughly into 8K quarters, like so:
- Comm Table
- CMD Table
- Engineering Log
- Last Thumbnail
I'll talk about the first three sections later, but I want to start with the thumbnail system; everyone likes a pretty picture.
This means that last thumbnail image can be at most 8K. I had decided that it's likely I'd use an HD webcam (or pair of them) as the primary imagers (a decision I'm re-thinking, actually). One image, at HD sizes, is huge. I wondered how small it could be, and found that in some cases jpegs of 160x90 pixels still wouldn't compress below 12K.
So if you want something done right, you do it yourself. I opted for a representation similar to jpeg, using the red channel as an RLE monochrome image, and a second table of 2x2 pixels of blue and green offsets. Using a Run Length Encoding scheme means that at worst, the image never grows above 7200 bytes. Each byte is actually two pixels, and within that the brightness value
Here is a sample result, comparing the source to different views of the compressed data:
Some stats and info
Across the top row are images scaled to the same size:
- The 'Source JPEG' is 1280x720, a still from a Logitech 920 webcam. It looks far worse in outdoor/daylight than I expected, because it does a great job as an indoor video conference cam.
- Compressed JPEG is a 2x scaled view of what imagemagick did at a reasonable compression quality.
- The RLE+Color image is a 2x scaled view of my compressed thumbnail.
Below that is a 2x view of the red channel, which is combined with the color table info.
The next row are the same three images, all at 160x90, which is actual size for the thumbs.
The color data is much smaller; it's based on the blue and green offsets from the average from the 2x2 red channel, so it's only 80x45 pixels, or 3600 bytes.
In circumstances where the RLE red channel is compressed small enough, around 4500 bytes, the color table can go along for the ride. And if the jpeg is small enough, it can go instead, since they look better.
Here are a couple more examples:
That's all for now. The Walking Dead season opener has started, and I'm missing out :)