Showing posts with label software. Show all posts
Showing posts with label software. Show all posts

05 February 2010

RoboRealm Vision Processing - Wrappers Classes

I've been working with RoboRealm over the last week. It is a vision processing application. One of its nice features is being able to access it from another program. You can let it do the heavy lifting of extracting information from a web cam image and then your program just gets a few important data points for analysis.

The module I've been working with is Center of Gravity which locates a blob in the image and reports its size and location. In particular, I'm looking for a red circle.

The interface I've used is the RR_API which is a XML over a socket connection. Reading a single variable is straightforward but reading multiple variables with one request is a lot of detail chasing. I hate chasing details over and over again. That is why they originally created subroutines and, more recently, classes. So I wrote some classes to wrap the read variable routines. I haven't need to write information, yet, so that will wait until needed.

The files are in Google Code.

Individual variables are handled through the RoboRealmVar class and its base class RoboRealmVarBase. The base class is needed to provide an interface for reading multiple variables. More on that below.

RoboRealmVar is a template class to allow for handling different data types. One of the details with th RR interface is all data is returned as a char string so it has to be converted to the correct data type. The class handles that automatically. The header file has instances of the template for int, float, and string. Other types could be added but may need a char* to data type conversion routine. See the string instantiation for how that is done.

Variables are declared by:

rrIntVar mCogX;
rrIntVar mCogBoxSize;
rrIntVar mImageWidth
;

The examples are all class members, hence the prefix 'm' on their names.

Initialize the variables with the instance of the RR class. In the example mRoboRealm is the instance of RR opened through RR_API:

mCogX("COG_X", mRoboRealm),
mImageWidth("IMAGE_WIDTH", mRoboRealm),
mCogBoxSize("COG_BOX_SIZE", mRoboRealm),


and then read them using an overload of operator():

int cogx = mCogX();

Multiple variables are read using the RoboRealmVars class. Declare it and instantiate it with:

RoboRealmVars mCogVars;
mCogVars(mRoboRealm)

Again, my examples are from inside a class.

Then add the individual variables to the list by:

mCogVars.add(mCogX);
mCogVars.add(mImageWidth);
mCogVars.add(mCogBoxSize);

then read them through:

mCogVars();

You can access their values just as shown above through the individual variables.

Hopefully this will be useful to others.

03 February 2010

Create Fun with Grandson

Last weekend two grand kids were here. The girl, Dorian, is a teenager. The boy, Kade, is six. Just before Christmas I was working on the Fit PC Slim to iRobot Create interface when they visited. He had his nose up close asking when it would be done. He asked the same thing in another visit since then. I had to reply it was not done but I was working on it.

So this visit I just had to have something working. I got the basic wander and bump into routines working with the Slim - a reproduction of the Create demo 1 behavior. I figured that would be good for about 2 minutes of interest so needed more.

Since this project will be using a web camera for vision I used some velcro to plunk the camera onto the Create just behind the IR sensor. The velcro raised it enough to see over the top of the sensor. I brought up RoboRealm and setup its built-in web page viewer. This lets you see the camera's images. I pointed the laptop at the web pages to display what the Create was seeing.

That was good for about 20 minutes and we got called for lunch and told to put the robot away. Awwww!!!

Next visit is in a couple weeks - they are visiting here pretty regularly now. The goal is to have the Create follow a "leash" - a red dot mounted on the end of a stick. That means getting the software to talk with RR to get information on the center of gravity (COG) of the red dot and send the drive commands to the Create to center and drive toward the dot. It should stop when it gets a little bit away from the dot, and even back up if the dot gets closer.

03 September 2009

ADC2 - Package Name

One of the last minute requirements for submission to ADC2 was that the Java package name be different from the name used in the Android Market. My package originally was com.mysticlake.galacticguardian.

As you know I'm not a Java guru so I wondered what I could do that would be easy. I finally changed the 'com' to 'adc2'. Eclipse readily made the change and all was good.

Except for version control. I use Subversion. The repository lives on my laptop computer. (Then I always have everything with me.) Subversion did not care for changing the top directory name. For all my years of development experience I've not worked with version control systems except in the most rudimentary fashion. Guess I need to figure out branching and merging.

Game Submitted to ADC2 - Galactic Guardian: Zap GPS

I finished my game and submitted it 6 hours before the deadline of 31 Aug 11:59:59 PT. No death march to the last minute here!

It was a bit of a crunch because a week ago my throat started feeling gluncky and by Wed I knew I was not well. (Or at least less well than usual.) Today is the first day I feel okay. But I persevered. My wife, Shari was really supportive taking over the cooking and a couple other household tasks I usually perform. I am retired but she still works as a college professor. Fortunately, it was the first week of classes so she didn't have much grading or other work to do. Not that cooking was a big deal because all I wanted were BLTs and cereal most of the time. We did manage a Crosby, Stills and Nash concert last Friday evening which was a good time away from everything.

You can see the material that appears in the game Info at Mystic Lake Software. I need to do more with the web site but wanted to get that page up quickly. I'll be using the web page for describing the game for users and, possibly, some of my thinking about the game itself. In this blog I'll discuss the technical development. There is bound to be some overlap but I'll keep that to a minimum.

The game came together pretty well. I went to the doctor Thursday morning, annual physical scheduled a few weeks ago, and took the Android with me. While waiting in the examining room I played the game and found it more interesting than I had realized. Of course all the time I had played it previously I was watching more for problems or if something I'd just implemented worked. That was the first time I'd just played with it.

The weekend before my granddaughter Meg had her 10th birthday. I showed her the game as it was then and she found it interesting. She went over to my mother and described it to her quite excitedly. That was encouraging.

I doubt that the game will have enough pizazz for the developers challenge but you never know. If I didn't enter it I surely couldn't win so may as well try. Plus it gave me a deadline to work toward and use as an explanation to others about why I was busy.

Next task is to make some minor changes and submit it to the Android market so it will be direclty accessible to all, not just those who will judge. Then on to making some improvements...and maybe make it a paid for application.

03 July 2009

Android Activity Analysis

I have been looking at the details of the life cycle of an Android Activity. There are many web sites that discuss this and many examples. But none of the example addressed all the onXXX() methods of Activity. I also found problems with some of the examples. In one case, the GUI update thread could be left running after the Activity supposedly was stopped.

I was trying to determine when the GUI update thread should be created, stopped, paused, etc that initiated this effort. I have a game underway (doesn't everyone?) and figuring out all the Activity infrastructure was giving me fits. Each example did it in a different manner and while there may be no one correct manner most of them seemed a little off. Usually they seemed to omit some of the steps needed to pause, stop, or destroy everything properly.

A number of discussions presented the life cycle as a state machine, as an alternative to the Google flow chart (or here). [I don't mean to single out Eric Burke of StuffThatHappens by using his chart to illustrate my point. He has good Android material on his site.] Like the examples, they didn't seem as well thought-out as possible. For example, notice in Eric's state chart how many places onResume() appears. That indicates to me that the representation of the state machine is needs more work.

I offer the chart below as a simpler representation which eliminates the redundant calls to onResume() and other routines. This diagram is simplified by the introduction of the Pause state reached by onStart() and onPause(). There may be another state after onCreate() and onRestart() are called but my work so far does not show it as important.


From Mystic Lake Software

The file accompaning this page, TemplateSurfaceView.zip, contains a skeleton application for an Android Activity using a SurfaceView as the drawing surface. The application doesn't do anything except report current state to LogCat.

In the TemplateSurvaceView (TSV), the Activity onXXX() routines are mimicked with corresponding doXXX() methods in the TSV class.

doStart() - create thread
doPause - pause thread
doResume - resume thread
doStop() - kill thread

It becomes clear that the onXXX() routines are nicely symmetrical with each pair being able to setup and tear down the parts needed for the application. The one misleading, oddball is onRestart(). At first thought it might somehow pair with doStart(), but this is not the case. The doStart() method is paired with doStop(). The doRestart90 appears to be available to duplicate some of the work done by onCreate() that may have been undone during onStop().

Once I had the diagram figured out the requirements became apparent and the TSV code was generally straightforward. Not so obvious was how to handle the Thread since many of the obvious Thread methods that would be used are deprecated due to deadlock problems. I won't go into the details here because this is a Java issue, not specific to Android. But read the article Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated? for more information.

SRC2 - Explicit Steering - Wheel Speed

SRC2 Rover This fourth post about the  qualifying round of the NASA  Space Robotics Challenge - Phase 2  (SRC2) addresses t he speed of the ...