Friday, November 2, 2012

New Project - Active/Responsive Ambient Lighting

So, while browsing the wonderful web one day recently a friend of mine, +Clint Shuman, sent me a link to an RGB LED grid that acted as a responsive ambient light for a TV. Awesome right? I love stuff like this. It's simple, but it really adds an interesting touch to movie night. Naturally, we immediately set out to program our own version.

The concept of active ambience is pretty interesting. The fire in that Avatar video link really enhances the feeling of having that torch flipped around. I definitely like that but there are a few limitations to this implementation of ambipi.

First, it is Windows only. Although Windows is a perfectly pervasive and acceptable OS, it is not the only one - nor is it frequently the choice of my media enthusiasts. A home theater build using Linux is often a less expensive and adaptable solution. Further, the limitation of using XBMC that is specially compiled for this feature limits the playing pool to a release cycle based on this feature. One can't simply update to the latest and greatest XBMC the whenever they please (ambipi extensions, not boblight for those thinking of it).

Which leads to the main hurdle: what about active ambience for other uses of the machine? VLC? Video conferencing? And the list continues. I want a solution that works with the display output and not only one application (although it has plenty of extensions). Adalight and others certainly have achieved this, but I would like to solve the problem in python and make it as cross platform/device as possible with additional configuration. Ultimately, how nifty would this type of thing be on displays, at trade shows, etc? Pretty eye catching.

So enter python and some good fun playing with websockets to test the results. I don't have any LEDs to plug into my Raspberry Pi, so Clint and I setup a cherrypy server with a websocket to communicate back to the server. The webpage has a configurable grid of squares. Although we started with a 3x2 grid, we have moved on to a 5x3 as we feel it'll produce a better ambience. The test with 8x8 went well but for now I just want to focus on getting a basic setup working flawlessly. Originally we made a full grid with all pieces of the screen updating (that is, all 15 boxes in a 5x3) but then decided to do a perimeter only since we won't have LEDs in the center behind the display. A perimeter of boxes on a 5x3 results in a 12-count. The grid generation algorithm was changed to simply build a full row if it was the first or last row and since the algorithm is only run once, there's no performance hit.

At first, we were at about 8 fps using screencaptures for each individual grid. This is super slow (200-300 millisecond response time based on grid size). So we changed the algorithm to capture the screen once and then resize it before sending it off to be analyzed by bounding box. This significantly improved performance and currently we're around 15-20 fps depending on how tempermental my CPU is feeling. Oddly my computer at work runs at about 45 ms pretty consistently while at home I'm more consistently in the 80-100 ms range. I still haven't figured out why that is, but I did just upgrade to Windows 8 so maybe there are some issues I haven't found yet relating to that (work is Windows XP).

Ultimately, I'd like to move to the win32api and see if I can get any improvement over the Python Imaging Library (PIL). For linux, we currently have GTK being used. It's possible we'll go to native C and use X to grab the window if needed, but we'll need to run some tests. GTK is staying pretty consistent with where PIL is (45 ms). I thought GTK would be far faster, but perhaps there's room for improvement with the algorithm.

The current plan (for me, Clint will use an Arduino) is to have my computer serving the image data over UDP to a Raspberry pi. Alternatively, could leave the Pi plugged in but that does involve the limitation of putting the computer next to the pi and therefore next to the tv. I don't currently have any spare computers lying around so a network method is preferable.





Sunday, October 28, 2012

Learning C

I don't have years of programming experience. The time that I devote to learning languages tends to be allocated to Python or something work related (.Net). However, I'm currently enrolled in a course focused on introductory C. At times I feel as though I have stepped into a time machine.

I used to play this video game and the people who were really obsessed maxed all their stats as much as they could. There were intense calculations that could be done. People could spend hours figuring out the best way to spellcraft their armor or weapons so that every possible point or stat could be claimed. More hours would be spent "farming" locations for "drops" to create the perfect armor set. It sounds like a complete waste of time, and maybe it was, but it was certainly fun. I was one of those obsessed people that did everything they could to maximize their "utility."

C reminds me of this mindset. I can completely see how people who are obsessed with performance or being in control of as many aspects of a program as possible would love C. You get to control almost everything so you get to optimize almost everything. You manage your memory. You fine tune everything. No doubt C is fast, but for once in my life I find myself enjoying the automatic management I get from lots of other, higher-level languages. Obtaining input in C presents a good example:

#include <stdio.h>

void main ()
{
    int inputChoice;
    do {
        printf("Please make a selection from the choices (1-4): ");
        scanf("%d*[\n]");
        if (inputChoice < 1 || inputChoice > 4) {
            printf("Error - you have entered an invalid choice.");
        }
} (while inputChoice < 1 || inputChoice > 4);}




This is how we collect input in C. We have to protect ourselves, and an easy way for a beginner like myself in C to protect against bad data is to use a do loop. Oh, that section with *[\n]? Yeah. That prevents the system from trying to store the newline character (\n). Yep. You have to handle that.

The thing is, I completely understand how awesome this must have been for a long time. But now it's just not necessary to me to spend a lot of time doing all this when I can literally do it in one line of code in another language. Take python for example:

inputChoice = input('Please make a selection')

I'm cheating because there's no error handling. But we can add that with a couple of lines admittedly. The point isn't so much the length. It's having to handle things like the newline character. You also can't test data types in C. 

Sunday, September 23, 2012

Higher Education Is A Gateway Drug

If you're like me, then you've been told your whole life the same thing:
Be good. Get good grades. Get into a good school. Get a good job.
That's a lot of repetition for the word "good." But all of those conditions are not sufficient to produce the final result. This mantra is espoused by parents and society (teachers, advisors, etc.) as if it's a logical conclusion:
IF you're good and get good grades and get into a good school  THEN you'll get a good job.
This is pretty faulty logic. For the P,Q logic geeks out there you can of course pick this apart pretty quickly. But the point here is that the good job doesn't necessarily come from the previous conditions. They help, sure, but there's an X factor somewhere. We can call it luck, ambition, drive, personal draw (the nature of someone being drawn to another or "taking a liking to" another), and I'm sure many others.

One thing is clear: getting a good education isn't about getting a job. It's about becoming a better thinker. I'm not sure when we decided that time spent in a college or university was job training, but that's how people treat it now. I have been guilty of treating university education as job training. It usually presents itself in the following form:
Why do I have to take class X? I'll never have to use that in my future job.
Well no kidding. If your focus is to only learn what you need for use on the job, go get a technical certificate and just work in the real world instead of going to university. The point of higher education is not to make better workers. That's job training, technical training, conferences, and the like. Pursue those avenues for making a better or more knowledgeable worker. The purpose of higher education is to make better thinkers. It frustrates me to no end to hear about how an individual believes they have no need to take an English (that is, composition/rhetoric) course because it doesn't apply to their mathematics degree.

Yes, it does.

Effectively communicating applies to all degrees and careers. If you can't write, you're at a disadvantage. If you can only perform basic math, you're at a disadvantage. You also look foolish in a meeting where you're discussing projections when you don't understand how someone arrived at a particular conclusion based on some basic algebraic formula. I remember thinking to myself in a class on Natural Resources why would I possibly ever need to know what the silver lining on a cloud is called.

The reality is that having an education has intrinsic value. Humans have incredible powers of perception, but if you don't have a broad base of information you can't draw the same conclusions. The age of Google and instant access to information has enabled us to do more but has simultaneously resulted in lowered expectations of what we need to know. Rather than thinking about all the new things you can learn, instead our society takes the approach of not needing to know something because they know where to find it.

That's good for the over-achieving crowd. But it's bad for those who are disinterested. Those who can use that knowledge and conclude something more quickly are at an advantage in career competition. That's not to say one should attempt to learn everything and always have it at the ready. There are exceptions such as high level theory/equations/etc. But if you have to learn a basic concept before using the higher one, you couldn't plan on what higher level concept you needed. Competition for limited resources. Not much has changed in the world regarding that basic tenet of existence.

So what's the point? Higher education isn't job training. It's teaching folks how to think. Becoming a better thinker has its own intrinsic value. Getting a major in a field focuses that thinking in a particular subject area. But thinking isn't job training. And that's lucky for those getting an education.

However, it's a gateway drug. I made an error in choosing my undergrad, Political Science. Not because I don't love the subject, but ultimately my path in life changed enough that the degree wouldn't be put to use in my career. Except that I focused heavily on writing in my undergrad and I'm an effective communicator. I work in technology now, at a software company. And though I completed a year of classes for an MBA, I'm currently enrolled and seeking my second Bachelor's - in Computer Science. I'm not positive I'll complete the MBA, but as I began with Political Science and intended to pursue a JD/MBA, now I have altered my path to pursue a BS in Computer Science and potentially an MBA as well.

Education is intrinsically valuable. It is also a means to an end and we therefore often view it as onerous or irrational in some cases. But our collective goal should be to increase knowledge and understanding, not merely technical merits. The latter are important, but they're not enough. Those committed to attaining credentials fit the post's title. B.A. then M.B.A. and concurrent B.S. That's definitely beginning a collection...