Friday, December 12, 2014

Getting Physical: Learning to Interface Python & Hardware

I've always been more of a software guy then a hardware guy. But a litany of factors have resulted in me finally putting a lot of real effort into making an old idea of mine become a reality, so now's the perfect time to start getting hands-on experience working on the hardware side of things!

In short, I need to create a device that can take some real-time distance and motion measurements. Ideally, this device will be small, inexpensive, simple to setup/install, and wireless (which means wireless communication and wireless power). To start, though, I'm just getting a functional prototype going for proof-of-concept, so I'm not worried about the size, wired vs wireless aspect, etc.

It's Alive!

Maybe I'll get a chance to go into some more detail at a later date, but for now I'll skip to the cool part: version 0.2 is operational! (I arbitrarily used v0.1 to getting the accelerometer working, and v0.2 has the distance sensor as well).
Device v0.2: RaspberryPi + GY-521 MPU-6050 accel/gyro + HC-SR04 range sensor

Since I went into this pretty blind (no idea what I'm doing at the outset) and a with low expectations (circuits was one of my worse courses in physics undergrad), I made some choices that erred on flexibility. For one, I started with a Raspberry Pi B+ model. Choosing a RasPi instead of an Arduino came down to two key differences:  1) RasPi is an all-in-one computer while Arduino is a much simpler microcontroller, so the former has a lot more functionality while the latter is intended for a single or fewer uses; and  2) Arduino's programming environment is in C, while Raspberry Pi runs a parred-down Linux, so I can code in just about anything I like: Python, Perl, Java, C, etc. 

There are a wealth of helpful tutorials for getting started in RasPi and interfacing it with various sensors & equipment. For the accelerometer/gyroscope unit, I used a Kootek GY-521 MPU-6050 (also bought a couple ADXL-345 units which were popular on blogs & tutorials). And for distance, I'm used an HC-SR04 ultrasonic range sensor. I'll make a note to come back at a later time and link out to the best tutorials I found, but a simple Google search gives you plenty. 

Oh, and for the Raspberry Pi board itself, I went with a starter kit from CanaKit, which provided a lot of the important peripherals in addition to the basic RasPi board (e.g. power supply, wifi dongle, enclosure). As a complete idiot when it comes to DIY circuits/electronics, I can say the CanaKit package was a really great place to start. 

In the end I'm actually a bit surprised that once I learned the basics of build-it-yourself electronics, the hardware aspect of my project was a surprisingly small portion of the hours I've put into it so far. So I'm already going back to the coding stuff I love! My next task is to start learning multi-threading & queuing in Python, so I can have the two sensors running in parallel and controlled by a single program. 

Wednesday, November 26, 2014

New Moves

A new skill or tool is always best learned through its application. Practice, practice, practice! In the the past I tended to read about something of interest, but not actively apply it to demonstrate and solidify my knowledge. The recognition of that flaw was a hard-learned lesson that slowly, steadily reared its ugly head throughout college. And frankly, I'm sure I'm still guilty of it from time to time, but I'm certainly better at it now!

The Perfect Challenge

While watching a show on Netflix, I thought of trying to model a chess game programmatically. Then I realized that actually makes a perfect project for a whole host of reasons, hitting several challenges I've been wanting explore right on the nose! I want to expand my very limited hands-on experience with machine learning, and chess has a rich history and so tons of data to train on. I've also been looking to get more practice designing MapReduce functions, and chess presents a set of an inherently parallelizable calculation (i.e. simulating outcomes give particular moves). If I get stuck, confused, or otherwise need help, I'm sure there's a plethora of examples out there to work from. I'm in essence intentionally re-inventing a wheel (more like an engine!), so that I have the opportunity to seek guidance when the need arises. I'm sure there's a ton of different statistical tests and tools I can tinker with to take different approaches to assessing the state of a board and determining moves.

Furthermore, there's an incredible range of difficulty to attack: I can keep the task simple by specifying a very specific sequence of moves and/or circumstances (which pieces are where) and trying to determine the "best" move (of course "best" is itself up to me to determine in this case), or go as deep and advanced as I could wrap my head around by attempting to simulate entire games, or varying how many moves out to project, how complicated an algorithm to determine the "best" move(s) to make, and so on. I'd bet one could continue coming up with a plenty more reasons this is such a great challenge to work on.

Starting Positions, Please!

To begin, I laid out the elements I'll need to develop: a board, populated with squares which have given properties like whether or not its location is occupied by a piece; each piece itself having a set of possible moves, and so on. Naturally, I started to get ahead of myself and needed to move backward and start simpler. In the end I wound up setting tonight's goal as establishing a single piece in the center of a small (3 x 3) board and determining it possible moves. I chose the piece to be a King, to have multiple possible moves, but have all such moves be very straightforward to assess. 

I can already see a ton of attributes and functions and the like that I'll need to define in the end: 
  • given a possible move to a new square, is that square occupied? If so, is it a piece of mine (so I can't move there) or is it an opponent's (in which case I can attack). Is there piece "in the way" so I can't move in that direction (with the exception of the Knight, of course)?
  • Am I on/near a boundary? A King can move left, yes, but if he's all the way to the left of the board, then no he can't! 
  • How do I weight possible moves? What's more important, what's less important? And how do I even quantify factors like whether to attack, how to recognize when a piece is "at risk" and whether that risk is acceptable, how to determine a move's importance as a part of a large strategy, so each move is interdependent on other moves...
  • Oh so many more... 

The First Big "Aha" Moment

When trying to define a piece's allowed moves, I wondered how to distinguish between one (say white) pawn's allowed move "up" or "forward" versus the opposing pawn's allowed move "down/backward" -- especially if basing locations on a Cartesian coordinate system board. Then it clicked that a better approach might be to define the entire board, pieces, and match from the perspective of a single player; then a two-person game is really just two separate (but related) instantiations of that single-person game! Each player can see his/her moves as forward, facing opposition pieces which, for the time being, can be considered just stationary obstacles. Then once the basic "moving" functionality is operational, having worked in not only permissible moves but also having those moves dependent on whether squares have another piece on them, I can figure out how to make each player's board setup (and thus moves) interdependent on the opposing player's board. The complexity builds pretty damn quickly, but it was a good realization to have early, I figure. 

The current struggle is how to relate objects to one another. For example, rather than determining moves on/at the level of a particular piece, I'd rather define relative movements for the piece (x+1, y+2, etc) and then use those to determine the set of possible "next locations" at the level of the Square (location) or even Board itself. So piece know's where it is and how it can move, but not where it can move, instead allowing the Square/Location (referenced by the "where it is") to determine and inform the piece where it can move

This is how I'm voluntarily spending my evening. I'm such a nerd. :-) 

Monday, November 24, 2014

# Instantiate Blog

A common occurrence over the last several years (and even more so the last several months) has been discovering the solution to a problem I'm faced with, or otherwise getting useful guidance toward solving it myself, from miscellaneous blogs and personal sites found by Googling. Often these blogs or websites are just the public record of someone's hobbies, whether a personal interest or a professional pursuit.

Embracing the perspective that almost any problem, obstacle, or hiccup that I'll face has already been tackled and overcome (and written about!) by someone else, I'll google the keywords of an error message or desired outcome and land on a blog post by someone who's been there and figured it out. And I can't overstate how frequently I search for tutorials and documentation to guide me into something new which have proven invaluable. These uses, combined with the realization that it could help me professionally to get some of my work, tinkering, stumbles, and accomplishments out there, inspired me to throw together a new blog.

At the outset, I have to cohesive "vision" for its intended purpose or target audience or anything else. But all too often the ramblings of others -- combined with the power of Google -- have been a major help to me, even if the original author(s) was never aware! So why not share my own various explorations?

Some "Things-To-Post" that initially come to mind:

  • Hadoop - Errors & Solutions: basic-level pitfalls and mistakes I made, plus lessons learned.
  • Data Analysis - Matching Countries & Counties: I recently started re-creating my old "senior capstone" project from 2010/2011, and one meticulous task is properly matching & merging data from various sources. 
  • Crazy Ideas & Miniature Projects: things I've thought of, thing I'm working on. If I'm lucky, someone else out there will stumble across it and can share some wisdom. 
  • Simple Scripts: misc. small coding tasks or projects
  • Nifty discoveries, useful tools, etc.: mobile apps, handy utilities, neat sites, awesome products

Plus, I finally have something to link to in online profiles & job apps:
       < Link Personal Webpage / URL >
        And don't forget to feel slightly inadequate if you have nothing to put here! 

It's the small things in life. ;-)