Using the Android Speech Recognition APIs

In my most recent project, I put together a voice controlled iRobot Create using the Android ADK, an iRobot Create and my Nexus S.  The Android speech recognition API takes care of listening for speech, determining when to end the speech input, and also sending the resulting recording off to “the cloud” for processing.  In the end, what you get back is a list of possible matches (this isn’t an exact science, after all).

There are two ways to incorporate speech recognition into an application.  In the first approach, an ACTION_RECOGNIZE_SPEECH intent is broadcast by your application using startActivityForResult.  The results are obtained by defining an onActivityResult method in your class.  As you can see in the Voice Recognition API demo, it is very simple to write an application using this interface!  The problem I had with this approach is that there was too little control over the speech recognition error handling.  Also, I really wanted the speech recognition to be running all of the time.  So, in the end I decided to use the second approach, using the SpeechRecognizer directly in my code.  This actually didn’t make the code all that much more complicated.  As an added bonus, your application is not being paused and resumed in order to get the results from the speech recognition activity.

Having the mechanics out-of the way, the next thing I did was to create a list of voice commands.  The list of speech recognition matches was compared against the command list.  If there was a match, I added the entire list of matches to a hash table, storing the actual command as the value.  Thus, any time a close match came up, it would be found in the hash table, with the entry being the (hopefully) intended command.

Now we have the name of a voice command.  We could write another if/else statement to perform the appropriate function call for each of the commands, or we could do something a little fancier.  Using reflection, I turned the command name into a method call.  So, to implement the command “forward,” you simply have to add a method called forward to the class!

Now, it isn’t quite that slick.  I still keep an if/else statement in order to get a match on the speech recognition results, and to store close matches in the hash table.  I’ll have to experiment with removing that code to see how it fares.

To browse through the code yourself, check out http://code.google.com/p/adk-moto/source/browse/src/com/jmoyer/adk_moto/ADKMoto.java.  It’s GPLv3 licensed, so cut-n-paste away into your open source projects!

Voice Controlled iRobot Create

I recently created an instructable on hooking together the Android ADK, an iRobot Create, and (of course) an Android cell phone.  The result is a voice-controlled robot, which you can find here.  I also just uploaded the code for this project to google’s code repository.  You can browse the sources here, or clone a copy using the following command:

hg clone http://adk-moto.googlecode.com/hg/ adk-moto

In future posts, I’ll walk through some of the code, explaining how the voice recognition is done, and why I structured things the way I did.

Stay tuned!

Turtlebot Power/Sensor Board Bill Of Materials (BOM)

Turtlebot Power/Sensor BoardI attempted to put together an order, today, for the parts needed to populate the Willow Garage Turtlebot power and sensor board.  They have a link to digi-key that’s supposed to have all of the necessary part numbers, but that plain didn’t work for me.  Also, they were missing some information for several of the parts (such as physical dimensions on surface mount capacitors and a resistor).  So, where there was wiggle room, I just ordered a couple of parts, in the hopes that one fits!

One interesting thing (to me, anyway) was that there was a resistor with a value of “0R”.  I’m guessing that is a 0 Ohm resistor, a beast that I have not yet come across.  But, sure enough, they do exist.  Apparently there are at least a couple uses for such thing.  One use is to simply jumper over a trace.  Another use is a placeholder when there are multiple configuration options available, and you only want to do one board run.  From the documentation provided for the Turtlebot, it doesn’t appear to be the former.  The datasheet for the gyroscope suggests that you could use a resistor here:

"A single external resistor between SUMJ and RATEOUT can be used to
lower the scale factor"

So, I guess the resistor could be a placeholder in case you wanted to adjust the scale factor.  Maybe it’s an oversight that they left it in the final layout.  Who knows?

For those interested, here is a link to the BOM from digi-key that I put together.  The grand total was a whopping $11.24.  Note that there is still a heatsink required (which I ordered separately from Newark.com, only because I forgot to look on digi-key first).  Also, you need the gyro breakout board from Sparkfun.

I’ll post an updated status when the PCB actually arrives.  The lead time from BatchPCB is 3-4 weeks, though, so don’t hold your breath.