jq Is the grep, sed and awk for json

The only problem with jq is that its not installed by default in ubuntu or ubuntu-server. Its not in the default ubuntu-cloudimg. One must apt-get install jq.

https://stedolan.github.io/jq/manual/ says, “jq is a lightweight and flexible command-line JSON processor.

In working with juju, we work with json formatted cookies in a ~/.go-cookies file. Sometimes we need to investigate these cookies to develop, verify, and debug our services.

An unexpired cookie value might be as good as a password or authentication token and so for the purpose of our debugging sometimes everything but the value is good enough. The jq filter ‘.[]|del(.Value)‘ strips all of the .Value properties from every object in the input array. This results in:

“Name”: “macaroon-a40e7abc65a78faf130dc652d45052c1c8b5b4aeff8181f44a15175b6525558f”,
“Domain”: “api.staging.example.com”,
“Path”: “/identity/”,
“Secure”: false,
“HttpOnly”: false,
“Persistent”: true,
“HostOnly”: true,
“Expires”: “2016-05-09T19:52:21Z”,
“Creation”: “2016-04-11T15:52:21.466266522-04:00”,
“LastAccess”: “2016-04-11T15:52:21.928768825-04:00”,
“Updated”: “2016-04-11T15:52:21.928768825-04:00”,
“CanonicalHost”: “api.staging.example.com”
“Name”: “macaroon-a605d07b7a95ba7e57a267ed507f673bce1188d0de7f544074f1c33ec4a8ff2a”,
“Domain”: “www.example.org”,
“Path”: “/identity/”,
“Secure”: false,
“HttpOnly”: false,
“Persistent”: true,
“HostOnly”: true,
“Expires”: “2016-05-03T21:46:35Z”,
“Creation”: “2016-04-05T17:46:36.351842179-04:00”,
“LastAccess”: “2016-05-02T15:11:10.525298848-04:00”,
“Updated”: “2016-04-05T17:46:36.351842179-04:00”,
“CanonicalHost”: “www.example.org”
“Name”: “macaroon-authn”,
“Domain”: “www.example.org”,
“Path”: “/NEENR/”,
“Secure”: false,
“HttpOnly”: false,
“Persistent”: true,
“HostOnly”: true,
“Expires”: “2016-05-03T19:11:09.794240373Z”,
“Creation”: “2016-05-02T15:11:10.592852105-04:00”,
“LastAccess”: “2016-05-02T15:23:26.813664654-04:00”,
“Updated”: “2016-05-02T15:11:10.592852105-04:00”,
“CanonicalHost”: “www.example.org”

Now lets say you want to remove the cookie with the Path value “/NEENR/”.

The jq filter: ‘.[] | select(.Path!=”/NEENR/”)’ does that job.

These examples show filter and map, but what about reduce?

Min, max, min_by and max_by are nice default reducers.

  • min_by(.Expires) shows the next expiring cookie.
  • max_by(.Created) shows the most recently created cookie.
  • [.[]|.Expires]|max if you don’t care about the rest of the cookie and just want the max date.
  • [.[]|.Expires]|min if you just want the min date.

See the Array Construction section of the manual for the details on the syntax. I like to think of it as the .[]|.NAME returns elements and if I want them in an array I wrap it in [] for array construction.

jq is a sweet tool that I’m glad to have in my toolbox.

Version from debian/changelog

Almost two years ago I did some scripting of updating debian/changelog and building a package to enable a CI environment for some software. I wanted to parse the changelog correctly and so I copied and changed some perl from the source of dpkg-buildpackage. This turned out to be the wrong solution.

There is a nice tool called dpkg-parsechangelog. You can get just the version for use in scripts with this simple awk:

dpkg-parsechangelog | awk ‘/Version/ { print $2 }’

I didn’t even think to write about it until I ran across someone else who’d written some perl to do exactly the same thing. Dear world, we need to stop reinventing this wheel.

Ubuntu Xenial 16.04 Has All The Good Stuff

A couple of days ago, Ubuntu Xenial was released. There is a press release with some good stuff in it.

I’ve been looking forward to this release for the following reasons:

  • Postgresql 9.5
  • systemd
  • haproxy 1.6.3
  • uwsgi 2.0.12
  • nginx 1.9.15

I know, it doesn’t look that exciting until you recall that the last LTS release of Ubuntu, Trusty, 14.04, was missing fabulous features OOTB in each of these components.

Postgresql 9.3 did not have the the awesome JSONB improvements of 9.4 and 9.5

haproxy 1.4 didn’t have ssl support.

uwsgi… well latest uwsgi is just always great to have.

nginx 1.9.15 has http2 support, out of the box!

Finally, while I loved upstart, systemd is nice and has been rock solid.

This is the greatest Ubuntu ever. I’ve not even mentioned how awesome lxd is on it. That is covered elsewhere. This is just my personal little list. Thanks Ubuntu.

MacGyvering Windows 8.1 Remote Assistance

My Mother called me up rather frazzled this evening.

This isn’t too surprising. Since her stroke 16 years ago she can sometimes become confused or forget simple things, things she once knew.

Tonight, the cause of her frazzled state was her computer.

After listening to her rant and ramble about her computer, I quickly realized that she had some web browser pop-up phishing telling her she had a virus. Partly because of who she is, and partly because of brain damage from stroke, she called the phone number that the pop-up displayed. When they told her they can fix it for $199 and if she took it to Best Buy, they would charge her $350-$400, this fueled her worry.

After some calming I finally had her start the Windows Remote Assistance application, but unfortunately she has forgotten what saving files actually means and she has no email configured. So she is unable to save the remote assist file and she can’t use Windows Remote Assistance to automatically email the request to me. It was at this point that I suggested she mail the laptop to me. I also may have said, “never again!” when I agree to support a laptop that someone else gifted her.

But, I couldn’t let it go. This was a challenge and I love a challenge.

I searched around a bit and tried my hand at the msra.exe command line. After a bit of trial and error, I realized I can have her open a powershell and type

msra /saveasfile helpme 12345678

Yes, I’m ok with the 12345678 password in this case. Trying some other password over the phone and having her type it was error prone.

“Did you say bee?”

“No I said pee, like Paul.”

“Bee like ball?”


I still needed a way to get a file to me. I’ve had an aversion to PowerShell ever since it launched, despite tech reviewing a very fine PowerShell book. I knew it was probably my best bet at getting a file to me. After a bit of poking I found the invoke-webrequest helper, thingy. I don’t know PowerShell terminology. It looks like a function to me.

I have my home server on the internet. Its running Ubuntu Linux  and I’ve had 4 line php upload scripts with html forms that let people send me files for years. Could I use this?

The shoelace was there. The paperclip was there. Did I also have some bubble gum?

All I really needed as an index.php in a /mom/ directory that looked like this:

file_put_contents('err.out', file_get_contents('php://input'));

Wow that is some trivial stuff. Bland bubble gum, I guess.

Why an index.php and a /mom/? Well, because that will be easy for me to relay over the telephone.

I did some testing and found invoke-webrequest works nicely coupled with this http request body dumping php.

invoke-webrequest -uri jrwren.xmtp/mom/ -infile .\helpme
.msrcincident -method post

I was able to call my mom back, tell her, to press windows key-r, reminding her that windows key is usually between the ctrl and alt on the keyboard, and to type powershell and press enter.

“Powershell, P-O-W-E-R-S-H-E-L-L- no spaces?”


On first try, I tried to have her use the password 1234, but msra.exe complained that it was too short. Working through this mistake, I tried to have her use the up arrow to edit the previously executed command line in powershell.

“What is the up arrow?”

This honestly dumbfounded me and I had absolutely no idea what to do for a minute or so.

“The up arrow on my keyboard is on the right. There is an inverted tee of arrows, left right up down to the left of my left control key.”

Whew, I got lucky and she found it.

Once we had the msra.exe create the helpme file, I had her type out the invoke-webrequest command, prompting her to press tab after typing helpme to autocomplete the file extension.

The multiline color output of running the command shocked and surprised her. It maybe even scared her a little bit, but as she was reading it aloud, I heard her say, “200 OK”

“200 OK is great”, I said.

I checked my server and there was an err.out file along side the index.php. The only two files in the mom directory.

My home server always has samba setup. I used Windows Explorer to navigate to H:\public_html\mom and I renamed err.out to helpme.msrcincident. I double clicked it.

Mom said, “Oh what is this? jrwren wants to share your computer.”

I rejoiced inside.

The hard part being done, I was able to connect and control her computer. Microsoft has done a very nice job with Windows Remote Assist, ever since Windows 7. I’m impressed that my Windows 7 can connect flawlessly to her Windows 8.1. I’m thankful that PowerShell is out of the box in all versions of windows. I do not think I’d have been able to walk her through this over the phone with this few keystrokes without PowerShell.

To the evil con artists who extort money from poor little old disabled ladies who work two jobs: please stop.

I Welcome Parse Developers to Juju

Hello Parse developers,

I was curious how easy it would be to get the published parse-server-example to run with Juju. The end result is that there is a new juju charm named parse-server available.*

Deploying parse-server is as easy as running these commands in a bootstrapped juju environment. This means that it can run ANYWHERE.

juju deploy cs:~evarlast/trusty/parse-server-0
juju deploy mongodb
juju add-relation parse-server mongodb
juju expose parse-server

You’ll then be able to use the http api at port 1337.

For example:

curl -X POST -H “X-Parse-Application-Id: myAppId” -H “Content-Type: application/json” -d ‘{“whatever”:”data”}’

If you wish to take a look at this charm, its in the charmed branch of my fork of the parse-server-example. I do not recommend using this charm as an example of writing a good production charm. This is an example of a quick and dirty hack of a charm which happens to work.

Part of what makes Juju awesome is the magic of application modeling. While my hack of a parse-server charm isn’t production ready, it is building on a very production ready mongodb charm, which can be scaled out and made HA very easily. Charms are reusable open source ops. The mongodb ops have been captured in the mongodb charm. Any required parse-server ops need to be capture in a parse-server charm. The only ones captured so far are configuring the mongodb relation. While its a hack of a demo charm, it is a start.



* The real reason is that I have cloud envy and I saw the azure release at https://azure.microsoft.com/en-us/blog/azure-welcomes-parse-developers/ and I thought to myself, gee that is a lot of clicks, seems like there is a better way.

Comparative Risk Analysis in IT Systems

You can quote me on this: “comparative risk analysis is among the most cost effective security measure your org can make. Why lock back door when front is wide open?” https://twitter.com/JayRWren/status/662015840636784640

What do I mean by this?

I mean, there is little point in applying inconsistent security system analysis in your system. The weakest link in a chain fails. When two links in the chain are identified to both be equally weak, nothing can be gained by spending resources (time and money) to improve the strength of only one link.

Let me get specific.

Lets say you have some services in production which interact. Lets call them Service A and B. You are introducing a new service, Service C. At the time of introduction concerns are raised about some security aspects of C.

Let me be clear, these concerns are 100% valid. Let us say for example that Service C is consuming Services of Service A using an overly privileged account rather than a least privilege account. The correct solution is to introduce a lesser privilege account capable of doing only the operations required by Service C.

From a “is it optimally secure” point of view for deploying Service C. That is all.

Rather than this point of view, lets take an overall systems point of view. Service B is using the exact same overly privileged account to perform operations on Service A. Further, the sources of data which Service B is using (publicly exposed https server accepting GET, POST, PUT, etc) are the same or more than Service C.

What is gained by going back, retooling Service A and C to use that lesser privilege account? Well, security of course. C is less vulnerable.

That is true. You’ve locked the back door while the front door is wide open.


How much did it cost? 80 people hours and the (often difficult to tie to a dollar amount) delay of introducing that much needed Service C.

Was the risk of privilege escalation reduced?

I honestly don’t know.


  • DuckDuckGo search for comparative risk analysis yields some fun reads.
  • In health, it is like counting calories and eating very well while continuing to abuse elicit drugs. http://www.ncbi.nlm.nih.gov/pmc/articles/PMC390121/
    “I totally would not eat that mcdonalds. It is so gross. Where is my lighter, I need another ciggy.”

Ubuntu Cloud Image Based Containers with LXC

At a previous employer, we standardized on Ubuntu cloud images on AWS EC2 and in our OpenStack. You can find the images at http://cloud-images.ubuntu.com. If you are using Ubuntu on EC2 or another Certified Public Cloud, then its most likely one of these cloud images.

We leveraged cloud-init and extended an already existing simple management system to allow passing user-data to EC2 instances and OpenStack Nova instances. The use of ephemeral instances proved very powerful and influenced our thinking greatly. We came up with great solutions using these very simple techniques.

Even before I left that job, I longed for an easy way to do the same thing for myself. I played a bit with the AWS CLI tool (the newer python boto based tool) and yes, aws ec2 run-instances –user-data works. I always longed to get the same thing on my home server and on my laptop.

Finally, I figured out how to do this with LXC. Its simple yes, but I finally learned how to do what I want.

tl;dr example:

lxc-create -n crisp-Hadley -t ubuntu-cloud -- -r trusty -S ~/.ssh/id_rsa-.pub -u one.yaml

cat > one.yaml
 all: "|tee -a /tmp/cloud.out"

 - rm -f /etc/dpkg/dpkg.cfg.d/multiarch
 - for i in 1 2 3 4 5 ; do curl -s http://packages.elasticsearch.org/GPG-KEY-elasticsearch | apt-key add - && break ; sleep 2 ; done
 - source: deb http://packages.elasticsearch.org/logstash/1.4/debian stable main
 - source: ppa:evarlast/experimental
 - mongodb
final_message: "The system is finally up, after $UPTIME seconds"
 - service myapp start


Most LXC tutorials that I’ve seen walk the user through using the download template. The download template is not bad for new users, but I want something more powerful. It turns out there are a number of templates available by default in /usr/share/lxc/templates and you can even create your own.

The template I am interested in is the ubuntu-cloud template. These lxc templates are not so much templates at all as they are scripts. Some of them use other scripts called hooks defined in /usr/share/lxc/hooks. The ubuntu-cloud template, defined in /usr/share/lxc/templates/lxc-ubuntu-cloud.


The help for templates is a little hidden and lxc is a little stupid at letting you view the help. You COULD run lxc-create, use the — to pass options to the template and use -h. That has the unfortunate side effect of creating the container anyway. You’d have to lxc-destroy it even though you only used -h. Instead, it is easier to invoke the template directly and get help.

$ /usr/share/lxc/templates/lxc-ubuntu-cloud -h
LXC Container configuration for Ubuntu Cloud images.

Generic Options
[ -r | --release <release> ]: Release name of container, defaults to host
[ --rootfs <path> ]: Path in which rootfs will be placed
[ -a | --arch ]: Architecture of container, defaults to host architecture
[ -T | --tarball ]: Location of tarball
[ -d | --debug ]: Run with 'set -x' to debug errors
[ -s | --stream]: Use specified stream rather than 'tryreleased'

Additionally, clone hooks can be passed through (ie, --userdata). For those,
 /usr/share/lxc/hooks/ubuntu-cloud-prep --help

Here, we see that if we don’t specify the -r option, it defaults to match the host. I’m running vivid on my host, but I’d really like to stick with trusty inside of containers. The -a is interesting, and I can only guess that it only works where compatible. -a i386 would let me use the i386 cloud image on an amd64 host. I can’t think of any other use where a mixing architecture would work in a container.

But there is nothing here about cloud-init

cloud-init via cloud-prep

The last line of help says clone hooks can be passed through. This is useful and IMO the most important item. Run the help for ubuntu-cloud-prep exactly as suggested.

$ /usr/share/lxc/hooks/ubuntu-cloud-prep --help
Usage: ubuntu-cloud-prep [options] root-dir

  root-dir is the root directory to operate on

  [ -C | --cloud  ]:       do not configure a datasource.  incompatible with
                           options marked '[ds]'
  [ -i | --instance-id]:   instance-id for cloud-init, defaults to random [ds]
  [ -L | --nolocales ]:    Do not copy host's locales into container
  [ -S | --auth-key ]:     ssh public key file for datasource [ds]
  [ -u | --userdata ]:     user-data file for cloud-init [ds]

Options for –userdata and –auth-key. Are those what I think they are? It turns out, yes, they work exactly like choosing a public key and user-data when starting an EC2 or Nova instance.

Putting all this together you can create cloud-config yaml files and specify and ssh key, and starting an LXC is just like starting a public cloud instance.

For example, want a postgresql server running?

$ cat > psql.yaml
 all: "|tee -a /tmp/cloud.out"
 - postgresql
 - echo "listen_addresses = '*'" >>/etc/postgresql/9.3/main/postgresql.conf
 - sudo -u postgres createuser -D -R -S myuser
 - sudo -u postgres createdb -E utf8 -O myuser mydb
 - echo host mydb myuser trust >> /etc/postgresql/9.3/main/pg_hba.conf
 - service postgresql restart 
$ lxc-create -n mypostgresql -t ubuntu-cloud -- -r trusty -S ~/.ssh/id_rsa.pub -u psql.yaml
$ lxc-start -n mypostgresql
$ lxc-info -n mypostgresql
Name:           mypostgresql
State:          RUNNING
PID:            6899
CPU use:        3.67 seconds
BlkIO use:      168.00 KiB
Memory use:     23.21 MiB
KMem use:       0 bytes
Link:           veth452FOE
 TX bytes:      3.84 KiB
 RX bytes:      20.36 KiB
 Total bytes:   24.20 KiB
$ psql -h -U myuser -d mydb
psql (9.4.2, server 9.3.7)
SSL connection (protocol: TLSv1.2, cipher: DHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

mydb=> \q

One of my favorite things about using the cloud-image like this is that unlike the download images, openssh server is running and listening by default. The user ubuntu has the public key which you provided in its authorized_keys file. Everything is ready to go.

11 lines of config, 373 bytes is not much at all for a running postgresql server.

When I don’t want to use juju, this is my go to option.

Elasticsearch on Ubuntu

It sucks, but it doesn’t have to.

1. Import the GPG KEY from the elasticsearch repo.

 curl -s http://packages.elasticsearch.org/GPG-KEY-elasticsearch | sudo apt-key add –

2. Add the repo.

echo "deb http://packages.elasticsearch.org/elasticsearch/1.3/debian stable main" |sudo tee /etc/apt/sources.list.d/packages_elasticsearch_org_elasticsearch_1_3_debian.list

3. Update your apt cache.

sudo apt-get update

4. Install the elastic search package.

sudo apt-get install elasticsearch

If this is a server, then configure ES to run on system start and start ES now:

sudo update-rc.d elasticsearch defaults 95 10
sudo service elasticsearch

If this is a development environment, then the following may help.

Homebrew on MacOSX allows for ability to simply run “elasticsearch –config=myconfig.yml” and have different elasticsearch instances. I want this on my Linux dev system.

1. Copy elasticsearch shell script to a place in the path. $HOME/bin works just as good as /usr/local/bin here, if it is in your path. Then you can skip the sudo on these commands.

sudo cp /usr/share/elasticsearch/bin/elasticsearch /usr/local/bin/

2. Copy the in.sh file there too.

sudo cp /usr/share/elasticsearch/bin/elasticsearch.in.sh /usr/local/bin/

3. Set the ES_HOME in the in.sh file.

sudo sed -i ‘2 a ES_HOME=/usr/share/elasticsearch’ /usr/local/bin/elasticsearch.in.sh

4. DFSG don’t work if the app isn’t built correctly, so symlink the config back in place. Config won’t get used, but logging.yml will.

sudo ln -s /etc/elasticsearch/ /usr/share/elasticsearch/config

That shall do it. You can now test run a few different instances.

for $dir in a b ; do
mkdir $dir
pushd $dir
cat > config.yml <<EOM
cluster.name: cluster_$dir
path.data: ./data
path.logs: ./log/
http.port: 1234
elasticsearch –config=config.yml &

Now you have a slightly less terrible elasticsearch on your Linux system, about on par with what you get from homebrew on a Mac.

update:fixed path in sources list creation.
Note: you can substitute 1.4 or 1.5 to get those versions of elasticsearch. Also note, elasticsearch isn’t dependant on a JVM, so you will need to apt-get install openjdk-7-jre-headless or zulu-8. See http://jrwren.wrenfam.com/blog/2015/03/18/zulu-jre-from-azul-systems-is-a-hidden-gem/

Setup a New Mac

A couple years later, and I find myself referring to my own guide

But in a different order of important things.

0. Caps Lock key is a Control key, Preferences->Keyboard, fix that, while I’m there, remove some of the -F keys from being bound, I’m going to need apps to see them.
1. I NEED THE SSH KEY, and copying a private key can be kind of a challenge, cuz… privacy.
2. Finder needs to see hidden files. http://lifehacker.com/188892/show-hidden-files-in-finder says – defaults write com.apple.finder AppleShowAllFiles TRUE ; killall Finder
3. AppStore has a nice purchases view, so I can easily find apps I have on the old/other Mac – click yes to Evernote.
4. Get iTerm2 – http://www.iterm2.com/#/section/home and DO NOT CLICK the big DOWNLOAD button… click the download tab/section at the top and get the Test Releases download, start it, and under profiles->default-> select the keys tab & click the Left option as +Esc selection
5. Copy .bashrc and .bash_profile
6. Copy Music/iTunes folder, maybe?
7. Manually inspect https://raw.githubusercontent.com/Homebrew/homebrew/go/install before actually going there and doing the http://brew.sh installation via ruby -switches $()… because… SECURITY!… also, I like to sudo mkdir /usr/local ; sudo chown $USER /usr/local ; so that home-brew install doesn’t run anything as root.
8.  System Preferences -> Keyboard -> Shortcuts -> All Controls (at the bottom) – so that I can tab to selections in dialog boxes
9.  MacVIM – because I like it
10.  vim things like python-mode, vim-fugitive
11.  firefox aurora and login with my firefox password
12.  brew install go
13.  add GOROOT to .bashrc and GOROOT/misc/vim to vim rtp
14.  … I don’t really know what else.

UGH, how could I forget: download Envy Code R and tell vim to use it: http://damieng.com/blog/2008/05/26/envy-code-r-preview-7-coding-font-released  Add set guifont=Envy\ Code\ R:h13 to .vimrc

Follow the rest of the old post http://jrwren.wrenfam.com/blog/2012/03/07/setting-up-a-new-mac/

Book Review: BeagleBone Robotics Projects

I was asked by Packt Publishing if I would read and review this book. I’ve owned a BeagleBoneBlack for a little while now. My use case was not robotics. This book might shed some new light on my old Black, so I agreed to review it.

The book starts off very accessible. Chapter 1 covers just about everything I did with my BBB when I first received it, hooking it up like a PC, replacing the default distro, making sure I could SSH to it were all in there. The author, Richard Grimmett, goes a step further and installs XFCE gui and vncserver and walks through connecting from a Windows PC using vncclient. All in all, chapter 1 is a great super basic tour.

Chapter 2 dives into programming on the thing and introduces Python. It does it in a really weird (to me) way. It has the reader running emacs in a putty window remote connected to the device. This must just feel weird to me because I do a lot of remote programming and its never with emacs (I’m a vim guy) and its rarely remote. For a new user, it seems to me like it would have been simpler and more friendly to say “use an editor of your choice” and “here is notepad2 or sublime” along with “here is how you copy files to and from the device.” I think this is mostly my background causing me to see things differently. The emacs in putty walk-through is very adequate.

Its not a programming book, so this is really a nit pick, but technically some of the descriptions of python aren’t really true. For example, if __name__==”__main__”: does not “tell the program to begin its execution at this point.” Again I’m nit picking, but I do feel like a different phrase that isn’t so very false to someone who knows python could have been found. Still, its not a programming book. The beginning of the chapter does list many resources for learning python.

Ugh, and then the book moves on to C++ and has quotes like this, “C++ is the original language of Linux” I’ve used Linux for almost as long as I’ve programmed C, and I am very (perhaps overly?) sensitive to the difference between C and C++.

OMG what do you mean Speech Input and Output? Really?  Chapter 3 tackles it. Really. For real. Speech Input and Output on that tiny little board. I can make my own Siri! This is a really cool topic; espeek is something I’ve only played with a little bit prior to reading this. It looks fun.

Speech recognition is done with software I’ve never used before called PocketSphinx. It isn’t packaged and so one has to compile it. Pretty sweet BBB being able to compile stuff like that. (I’m thinking of iOS and Android where I’ve not seen a compiler run on device.) The demo walks through limiting the grammar of speech input so that you don’t have to train the recognizer.

I’m a programmer, so I’m going to nitpick programmer things. I really wish authors wouldn’t do this, “I like to make a copy of the current file into continuous.c.old, so I can always get back to the starting program if it is required.” I really do wish authors would just say “go read about version control systems.”

Whew, speech is fun. Next step is video. Hook up a webcam and let’s do some image recognition. The book walks through OpenCV and it is as this point that we are forced to do a bunch of Linux sysadmin stuff to make our SD have enough free space to have a dev environment. This really could have gone anywhere in the book. I kind of like that it put it off until it was necessary.

The python image tracking example using OpenCV looks pretty cool. It is a complete example without going too deep or going off in the weeds.

Making the Unit Mobile introduced me to mobile platforms. The Magician Chassis that the book shows first, I found online for under $20! I knew that this stuff was accessible, but this is downright cheap. I feel almost guilty NOT getting one and trying it out.

The motor controller tutorial looks very straightforward. I already have ideas for code changes. Immediately after the simple time based tutorial it goes into speech controlled movement, which is pretty sweet.

After the wheeled robot tutorial is a walking robot example. The author makes a compelling argument for this type of robot, and the Pulse Width Modulation servo motors are cool, but I have to admit, this type of robot just doesn’t excite me. The book also punts on the PWM, using a controller which interprets serial USB commands into the PWM for the servos. For beginners, this is certainly the right choice.

Incidentally, the –help output from UscCmd includes Version, Culture, PublicKeyToken values like a Mono program might. I wonder if it is written in C# and running via Mono. I’m going to assume it is. That is pretty sweet. Indeed the linked download page mentions C#. http://www.pololu.com/docs/0J40/3.b

The sonar sensors section is a straightforward and great introduction to the use of them. I never knew how those things worked or what kind of value they returned. Now I do. Mounting the sensor to a survo makes for a nice subsystem on the bot.

Next, a fully remote control system is built. I don’t know if I like the choice of using an LCD monitor. It seems like overkill, but depending on the particular robotic application it would be a good choice. For the applications I have in mind, I think I’ll skip it. A wireless usb keyboard and mouse makes for an obvious choice. At this point, I just keep thinking about bluetooth and using an extra Wiimote, mostly because I think it would be a more fun control.

Oh, a GPS receiver! This could be necessary for when I lose my robot in a parking lot or the woods. As with the LCD Monitor and KB chapter, I kind of feel like I know how to do this since I’ve looked into it before. It is great coverage and good intro to the topic.

Much of my day job is what would traditionally be called Systems Programming so Chapter 10 is kind of a duh to me. I’d have started there, but that is just how I think about coding these days. Its great to have this in a chapter to tie some things together. In other words, read this chapter!

Using the BBB in sea, air and submarine applications is an interesting idea. I don’t think it is for me yet, but the book gives introduction to some ideas on the topic. The introduction to feedback control is very welcome.

Overall this is a great book. It really gave me a lot of ideas. It also showed me how easy it is to get started, something which I’d been a little hesitant to do. I’m actually a little excited to dive in now. I’ll be doing a bunch of this stuff with my 6yo over the next few years.