<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8561422555282976331</id><updated>2012-01-23T20:38:58.824-06:00</updated><category term='thinking aloud'/><category term='sensor manager bug'/><category term='fit pc slim'/><category term='android'/><category term='vision'/><category term='robot hardware'/><category term='robot neural'/><category term='java'/><category term='zap gps'/><category term='sensors'/><category term='software'/><category term='g1'/><category term='RoboRealm'/><category term='subsumption'/><category term='robot'/><category term='adc2'/><category term='robot software'/><category term='robot learning'/><category term='game'/><category term='galactic guardian'/><category term='create'/><category term='robot behavior'/><title type='text'>Mystic Lake Software</title><subtitle type='html'>Commentary and analysis on software development techniques, implementaion details, and other flights of fancy from a guy who wrote his first FORTRAN program in 1968. Experience since then includes embedded systems, mainframes, micros, PC, and now the Android cell phone. Some excursions into robotics may be encountered along the way. Mystic Lake Software is my DBA should I ever make money from something I write in the future.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.mysticlakesoftware.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://blog.mysticlakesoftware.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Rud</name><uri>http://www.blogger.com/profile/05243211372637967124</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_dHdvnzWVL3Y/SlIHQ7QIyvI/AAAAAAAAACw/UgFpPAV8TSQ/S220/Rud+Cruise.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>17</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8561422555282976331.post-4607260762048701544</id><published>2010-07-16T22:33:00.004-05:00</published><updated>2010-07-16T22:50:35.229-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='galactic guardian'/><category scheme='http://www.blogger.com/atom/ns#' term='zap gps'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Android - Galactic Guardian: Zap GPS Lite Released</title><content type='html'>I finally released the free, lite version of Zap GPS to the Android market. If it is received at all well, I will do a paid version. If you have tried the Lite version and have ideas on how to improve it or enhance it for a paid version please feel free to comment.&lt;br /&gt;&lt;br /&gt;The Lite version omits one capability that the ADC2 version contained: cloaking. I felt that was an interesting capability that would be better in a paid version. Cloaking is implemented by hiding a Sentinel if the GPS (Global Positioning Satellite) signal is lower than a threshold. The player still needs to damage the Sentinel to proceed to the next round but it is more difficult since the Sentinel cannot be seen. When both Cloaking and Command &amp;amp; Control (sequential destruction) are present it can be difficult since a cloaked Sentinel  may also drop off the Sentinel list because its signal is weak and then lost. But if may reappear if the signal increases. If it is the lowest sequential number the player has a real challenge.&lt;br /&gt;&lt;br /&gt;One additional feature is timing the player. The player would be allowed a period of time to damage the Sentinels in the list. After that time Sentinels would be "repaired" and added to the list. That isn't implemented but would be easy to do.&lt;br /&gt;&lt;br /&gt;The big feature to add would be competition among users. That would require setting up a web presence to record scores and show the best players for, say, the day, week, and month. The effort for that would be about the same as developing the game up until now. Not sure I want to expend that much effort for little or no reward.&lt;br /&gt;&lt;br /&gt;Any other ideas for Zap GPS? Any ideas for a different Galactic Guardian game?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8561422555282976331-4607260762048701544?l=blog.mysticlakesoftware.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mysticlakesoftware.com/feeds/4607260762048701544/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.mysticlakesoftware.com/2010/07/android-galactic-guardian-zap-gps-lite.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/4607260762048701544'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/4607260762048701544'/><link rel='alternate' type='text/html' href='http://blog.mysticlakesoftware.com/2010/07/android-galactic-guardian-zap-gps-lite.html' title='Android - Galactic Guardian: Zap GPS Lite Released'/><author><name>Rud</name><uri>http://www.blogger.com/profile/05243211372637967124</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_dHdvnzWVL3Y/SlIHQ7QIyvI/AAAAAAAAACw/UgFpPAV8TSQ/S220/Rud+Cruise.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8561422555282976331.post-8507359543037474943</id><published>2010-02-05T10:38:00.004-06:00</published><updated>2010-02-12T15:58:44.107-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='robot software'/><category scheme='http://www.blogger.com/atom/ns#' term='vision'/><category scheme='http://www.blogger.com/atom/ns#' term='robot'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='RoboRealm'/><title type='text'>RoboRealm Vision Processing - Wrappers Classes</title><content type='html'>I've been working with &lt;a href="http://www.roborealm.com/"&gt;RoboRealm &lt;/a&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;The files are in &lt;a href="http://code.google.com/p/mysticlakesoftware/downloads/list"&gt;Google Code&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Variables are declared by:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;rrIntVar mCogX;&lt;br /&gt;rrIntVar mCogBoxSize;&lt;br /&gt;rrIntVar mImageWidth&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;The examples are all class members, hence the prefix 'm' on their names.&lt;br /&gt;&lt;br /&gt;Initialize the variables with the instance of the RR class. In the example mRoboRealm is the instance of RR opened through RR_API:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;mCogX("COG_X", mRoboRealm),&lt;br /&gt;mImageWidth("IMAGE_WIDTH", mRoboRealm),&lt;br /&gt;mCogBoxSize("COG_BOX_SIZE", mRoboRealm),&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;and then read them using an overload of operator():&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;int cogx = mCogX();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Multiple variables are read using the RoboRealmVars class. Declare it and instantiate it with:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;RoboRealmVars mCogVars;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;mCogVars(mRoboRealm)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Again, my examples are from inside a class.&lt;br /&gt;&lt;br /&gt;Then add the individual variables to the list by:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;mCogVars.add(mCogX);&lt;br /&gt;mCogVars.add(mImageWidth);&lt;br /&gt;mCogVars.add(mCogBoxSize);&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;then read them through:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;mCogVars();&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;You can access their values just as shown above through the individual variables.&lt;br /&gt;&lt;br /&gt;Hopefully this will be useful to others.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8561422555282976331-8507359543037474943?l=blog.mysticlakesoftware.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mysticlakesoftware.com/feeds/8507359543037474943/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.mysticlakesoftware.com/2010/02/roborealm-vision-processing-wrappers.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/8507359543037474943'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/8507359543037474943'/><link rel='alternate' type='text/html' href='http://blog.mysticlakesoftware.com/2010/02/roborealm-vision-processing-wrappers.html' title='RoboRealm Vision Processing - Wrappers Classes'/><author><name>Rud</name><uri>http://www.blogger.com/profile/05243211372637967124</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_dHdvnzWVL3Y/SlIHQ7QIyvI/AAAAAAAAACw/UgFpPAV8TSQ/S220/Rud+Cruise.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8561422555282976331.post-1269837061986519165</id><published>2010-02-03T10:32:00.004-06:00</published><updated>2010-02-03T10:49:10.263-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='robot software'/><category scheme='http://www.blogger.com/atom/ns#' term='robot hardware'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='fit pc slim'/><title type='text'>Create Fun with Grandson</title><content type='html'>Last weekend two &lt;span id="SPELLING_ERROR_0" class="blsp-spelling-corrected"&gt;grand kids&lt;/span&gt; were here. The girl, Dorian, is a teenager. The boy, &lt;span id="SPELLING_ERROR_1" class="blsp-spelling-error"&gt;Kade&lt;/span&gt;, is six. Just before Christmas I was working on the Fit PC Slim to &lt;span id="SPELLING_ERROR_2" class="blsp-spelling-error"&gt;iRobot&lt;/span&gt; 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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Since this project will be using a web camera for vision I used some &lt;span id="SPELLING_ERROR_3" class="blsp-spelling-error"&gt;velcro&lt;/span&gt; to plunk the camera onto the Create just behind the IR sensor. The &lt;span id="SPELLING_ERROR_4" class="blsp-spelling-error"&gt;velcro&lt;/span&gt; raised it enough to see over the top of the sensor. I brought up &lt;span id="SPELLING_ERROR_5" class="blsp-spelling-error"&gt;RoboRealm&lt;/span&gt; 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.&lt;br /&gt;&lt;br /&gt;That was good for about 20 minutes and we got called for lunch and told to put the robot away. &lt;span id="SPELLING_ERROR_6" class="blsp-spelling-error"&gt;Awwww&lt;/span&gt;!!!&lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8561422555282976331-1269837061986519165?l=blog.mysticlakesoftware.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mysticlakesoftware.com/feeds/1269837061986519165/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.mysticlakesoftware.com/2010/02/create-fun-with-grandson.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/1269837061986519165'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/1269837061986519165'/><link rel='alternate' type='text/html' href='http://blog.mysticlakesoftware.com/2010/02/create-fun-with-grandson.html' title='Create Fun with Grandson'/><author><name>Rud</name><uri>http://www.blogger.com/profile/05243211372637967124</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_dHdvnzWVL3Y/SlIHQ7QIyvI/AAAAAAAAACw/UgFpPAV8TSQ/S220/Rud+Cruise.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8561422555282976331.post-7950910703848265988</id><published>2010-01-28T12:24:00.001-06:00</published><updated>2010-01-28T13:33:35.913-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='robot software'/><category scheme='http://www.blogger.com/atom/ns#' term='robot neural'/><category scheme='http://www.blogger.com/atom/ns#' term='robot learning'/><category scheme='http://www.blogger.com/atom/ns#' term='thinking aloud'/><title type='text'>Thinking Aloud - Long Ago Neural AI</title><content type='html'>I got thinking about way back when in 1972-74 in  undergrad school. I was doing some work in AI, albeit within the psych department. This was before the heyday of neural network although there was some activity in the area. I ran across the book, &lt;em&gt;Intelligence: Its Organization and Development&lt;/em&gt; by Michael Cunningham. He proposed a rigorous, testable way in which intelligence organizes in the infant. I guess it didn't work out since it didn't make the front page of the New York Times as a major breakthrough sometime in the intervening decades.&lt;br /&gt;&lt;br /&gt;Interestingly, a web search turns up little information beyond citations. None of the titles in the citations indicate a successful implementation or breakthrough based on the work.&lt;br /&gt;&lt;br /&gt;I still have a paper I wrote about the book and a description of a FORTRAN implementation that never got finished.&lt;br /&gt;&lt;br /&gt;One of the challenges back then, and remains so somewhat today, is that testing ideas like this requires a simulation environment that can be as complex to produce as the actual ideas you want to test. But I realized that today I do have a physical device, my Create robot, that could be used for testing.&lt;br /&gt;&lt;br /&gt;I'm not going to layout all the details of Cunningham's proposal since he took a book to develop and describe the idea. I won't even list the roughly 2 dozen specific assumptions in the model. What I am going to do is walk through some thoughts on how a project might proceed to see if it is worth pursuing.&lt;br /&gt;&lt;br /&gt;You start with input and output elements - sensors and actuators in today's robot parlance. There are some reflex connections between these elements. For example, a pain reaction reflex so if an infant's hand touches something hot it jerks away. Or if the side of the mouth touches something the head turns in that direction in an attempt to suckle.&lt;br /&gt;&lt;br /&gt;Jumping over the start up process (which is always a pain), lets assume the robot is moving forward and hits a wall. The bumper switch closes but there is no reflex to shut down the motors. The motors keeps turning and you get an overload reading. There is a reflex for this and it stops the motors. Now the motors are stopped and the bump switch is still triggered.&lt;br /&gt;&lt;br /&gt;There would be a number of elements. Each sensor input on the Create could have an input element. Each actuator would have an output element. As indicated, the over current input element could be connected to an output element that stops the motors. &lt;span style="color:#3366ff;"&gt;Note - A point to consider that there might be output elements that don't directly connect to actuators but instead inhibit actuators. Continuing the thought, there might need to be backup, stop, and forward elements for the motors. &lt;/span&gt;&lt;span style="color:#000000;"&gt;In the situation described, these elements would have high levels of activity. Other elements, like a push button, would have no activity. The Cunningham model proposes that those elements with high activity are connected through a new memory element. The inputs to the input side of the memory and the outputs to the output side. What might happen is a connection is created between the bump switch, the over current and the motor stop elements through the new memory element. In the future, a bump switch closure would stop the motor. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I now recall one result from my work with the FORTRAN implementation. This is the need to have multiple elements to represent the state of input and output elements. My note above reflects this. For example, the bump switch needs two elements - open and closed. The motor needs forward, reverse and stopped. It may need even more indicating speed, although I would first try relating the element activity level with the speed.&lt;br /&gt;&lt;br /&gt;The activity level of an element decays if it is not triggered. So the bump switch closing triggers activity that decays over time. The motor activity decreases until the motor stops. An issue would be to keep the bump switch closed activity going long enough for the over current activity to shutdown the motor and get the new memory element built. &lt;span style="color:#3366ff;"&gt;Note: maybe an input triggers again after a period of time? &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;How do we get the bump switch open? The only way is by getting the motor to reverse. Infants in a situation like this flail. They randomly move. Sometimes they do this happily while cooing and sometimes angrily while crying. It appears to be a natural reaction to try something, anything to make things different. (A really ugl phenomena in an adult but you still see it. If not physically at least mentally. Ever had a boss whose reaction was, "Don't just stand there! Do SOMETHING.") I don't recall the model addressing this situation. (I did find used copies of the book and have one ordered so I can refresh my thinking.)&lt;br /&gt;&lt;br /&gt;Somehow some general level of activity has to increase which can generate activity at outputs. Sometimes this would be through inputs. For an infant this could be sound, pressure on skin, internal senses, and vision. I dislike simply generating random activity levels to cause something to happen. Maybe the general inputs of the Create - power levels, current readings, etc are sufficient to generate activity.&lt;br /&gt;&lt;br /&gt;Clearly, a dropping charge level in the battery could be tied to a "hunger" reaction which sends the robot searching for its charger. That brings in using the IR sensor to control the drive for the docking station. That probably requires external guidance to train the IR / motor control  coordination to execute the docking maneuver. That opens up an entirely different set of thoughts.&lt;br /&gt;&lt;br /&gt;Which is enough for today... No conclusion on trying to implement this. But no conclusion not to do so, either.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8561422555282976331-7950910703848265988?l=blog.mysticlakesoftware.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mysticlakesoftware.com/feeds/7950910703848265988/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.mysticlakesoftware.com/2010/01/blog-post_28.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/7950910703848265988'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/7950910703848265988'/><link rel='alternate' type='text/html' href='http://blog.mysticlakesoftware.com/2010/01/blog-post_28.html' title='Thinking Aloud - Long Ago Neural AI'/><author><name>Rud</name><uri>http://www.blogger.com/profile/05243211372637967124</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_dHdvnzWVL3Y/SlIHQ7QIyvI/AAAAAAAAACw/UgFpPAV8TSQ/S220/Rud+Cruise.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8561422555282976331.post-5549009828076508395</id><published>2010-01-27T22:18:00.005-06:00</published><updated>2010-01-27T22:39:43.737-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='robot software'/><category scheme='http://www.blogger.com/atom/ns#' term='subsumption'/><category scheme='http://www.blogger.com/atom/ns#' term='robot behavior'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Subsumption Architecture - Introduction II</title><content type='html'>The last post left off with me wondering why the Trapped behavior needed to be called even when a higher priority behavior was active. Here is why:&lt;br /&gt;&lt;br /&gt;Remember I ported the code from the Command Module (CM) version to the Windows on the Fit PC Slim? In Windows there is a clock and in the CM there isn't. In the newer version I can setup a timeout by taking the current clock time and adding a delay. Then when the clock exceeds the timeout the timer has expired. For Trapped this meant the robot had not moved for over 10 seconds, despite other activities trying to make it move.&lt;br /&gt;&lt;br /&gt;In the CM version, with no clock the Trapped needed to update the "clock" value to see if it exceeded the timeout value.&lt;br /&gt;&lt;br /&gt;I'd say this falls under checking your assumptions. In the CM the assumption was that no clock existed so Trapped had to maintain its own. I didn't catch that the assumption was no longer valid in the Windows version.&lt;br /&gt;&lt;br /&gt;I've been re-reading a lot of the papers on subsumption and the Jones book &lt;em&gt;Robot Programming&lt;/em&gt;. I find that my implementation isn't really subsumption as it was originally presented by Rodney Brooks. Brooks is credited with the concept of programming robots by behaviors. His technique for implementing behaviors was subsumption.&lt;br /&gt;&lt;br /&gt;My implementation is more in line with Jones, and also derives from David Anderson. David has an &lt;a href="http://www.dprg.org/articles/2007-03a/"&gt;article &lt;/a&gt;about two of his robots, SR04 and jBot, which are accessible from the &lt;a href="http://www.dprg.org/"&gt;Dallas Personal Robotic Group &lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I continue the discussion in a later post. I also want to take some time to reabsorb the subsumption and behavior programming concepts so I can elaborate on them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8561422555282976331-5549009828076508395?l=blog.mysticlakesoftware.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mysticlakesoftware.com/feeds/5549009828076508395/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.mysticlakesoftware.com/2010/01/subsumption-architecture-introduction.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/5549009828076508395'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/5549009828076508395'/><link rel='alternate' type='text/html' href='http://blog.mysticlakesoftware.com/2010/01/subsumption-architecture-introduction.html' title='Subsumption Architecture - Introduction II'/><author><name>Rud</name><uri>http://www.blogger.com/profile/05243211372637967124</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_dHdvnzWVL3Y/SlIHQ7QIyvI/AAAAAAAAACw/UgFpPAV8TSQ/S220/Rud+Cruise.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8561422555282976331.post-2822584911005393223</id><published>2010-01-26T13:04:00.002-06:00</published><updated>2010-01-26T13:59:47.103-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='robot software'/><category scheme='http://www.blogger.com/atom/ns#' term='subsumption'/><category scheme='http://www.blogger.com/atom/ns#' term='robot'/><title type='text'>Subsumption Architecture - Introduction</title><content type='html'>The brain of a robot is the software. The software has to take in the sensor data, interpret it, and generate commands to the actuators.&lt;br /&gt;&lt;br /&gt;One architecture for robot software is called &lt;em&gt;subsumption&lt;/em&gt;. It came out of MIT and Prof. Rodney Brooks who is a founder of iRobot who makes my Create robot. The idea is to break the robotos activities into small pieces. Let me build up the concept by example.&lt;br /&gt;&lt;br /&gt;A fundamental activity of a robot is to cruise around. If nothing is to be done just let the robot drive straight ahead. So we create an activity called Cruise. It simply actuates the motors to go straight at a safe speed. It is easy to write and test.&lt;br /&gt;&lt;br /&gt;After driving straight ahead for awhile the robot bumps into something. And continues to try to go straight ahead. This is not good for the robot or the cat or furniture it bumped into.&lt;br /&gt;&lt;br /&gt;So we write a Bump activity using the sensors on the robot - the Create has a right and a left bump sensor on the front that wrap around a bit toward the sides. So Bump determines if a bump sensor was triggered the robot should stop. So we write Bump.&lt;br /&gt;&lt;br /&gt;How to Bump and Drive get put together in the software? This is the subsumption architecture part. Initially its easy. First call Bump. If it doesn't activate, call Drive. If Bump does activate, don't call Drive.&lt;br /&gt;&lt;br /&gt;Let this run. The robot goes merrily off, bumps into a cat, and stops. The cat gets up, the robot continues straight ahead, hits a chair, stops, and stops and stops and stops. Not very interesting.&lt;br /&gt;&lt;br /&gt;What we'd like is for the robot to back up a little bit, turn, and then continue straight ahead. Hopefully that will clear the obstacle, and it will if the robot just brushed a wall. But even if it doesn't, repeating that behavior will eventually turn the robot toward an open area. (Well, many times it will. More later...)&lt;br /&gt;&lt;br /&gt;This new behavior is somewhat different from Bump and Drive because we want it to do the back and turn without interruption. The term used for this is a &lt;em&gt;ballistic&lt;/em&gt; behavior. Do we add this to Bump or Drive, or create a new behavior? The texts I've read added it to Bump. But based on my experience I create a new behavior called Flee.&lt;br /&gt;&lt;br /&gt;Flee works with what could be called an internal sensor. This internal sensor tells Flee thow much to back up and turn. So Bump sets this internal sensor to backup a little bit (40 mm) and turn a little (20 degrees). Since Bump can tell whether the left or right bump sensor (or both) was hit it also sets the direction of the turn so the robot will turn away from the bump.&lt;br /&gt;&lt;br /&gt;Now the activities are called in the order: Flee, Bump, Drive.&lt;br /&gt;&lt;br /&gt;Remember that if Flee is active the later activites aren't called. If Bump is active, Drive is not called.&lt;br /&gt;&lt;br /&gt;So the robot Drives ahead, Bumps into something, the internal flee sensor is set, and Flee backs up and turns the robot. Then with both Flee and Bump inactive, Drive engages and the robot moves ahead.&lt;br /&gt;&lt;br /&gt;Just for completeness, I have another activity called Trapped. It is added between Flee and Bump. Every time Trapped is called it records the time and distance moved. If the robot has not moved very far (80 mm) in a certain period of time (10 seconds) then Trapped sets the flee sensor to back a little bit and turn 180 degrees. The idea is that by turning 180 degrees the robot can get out of a bad situation. One such situation is the legs on a rolling desk chair, or a corner.&lt;br /&gt;&lt;br /&gt;With these behaviors my Create wanders around the house pretty well.&lt;br /&gt;&lt;br /&gt;The actual implementation needs a couple more details. Here is some psuedo code:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   preempt = false;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   preempt = Flee(preempt);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   preempt = Trapped(preempt);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   preempt = Bump(preempt);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   preempt = Drive(preempt);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;The variable &lt;em&gt;preempt&lt;/em&gt; is set to true by an activity if it is active. If Bump sense a bump then it sets preempt. When Drive sees preempt is set it does not activate, i.e. does not drive forward. If Bump sees preempt is set it does not bother checking the bump sensors, because presumably Flee is now handling the bump condition. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Why bother calling activities if they are preempted? Look back at how Trapped works. It is monitoring the distance traveled. If it is not called because Flee is active...&lt;br /&gt;&lt;br /&gt;And there I'm going to let it hang because I don't remember why. But I'm going to publish this now, leave it as is, and resume in another posting.&lt;br /&gt;&lt;br /&gt;This is software development as it is, folks. There are a few possibilities here:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I simply don't recall the reason so have to remember it or rethink it. That is why you should document things.&lt;/li&gt;&lt;li&gt;There was a valid reason that is no longer valid. Boy, that happens all the time in development. A good habit to develop is to revist assumpts regularly to see how they've changed.&lt;/li&gt;&lt;li&gt;I simply blew it when writing the code many months ago. &lt;/li&gt;&lt;li&gt;...or some totally different situation that I can't think of right now. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;That is the basics of subsumption, though. A good book on robot programming that covers subsumption is &lt;em&gt;Robot Programming - A Practical Guide to Behavior-Based Robotics"&lt;/em&gt; by Joseph L. Jones. &lt;/p&gt;&lt;p&gt;&lt;em&gt;...sine die&lt;/em&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8561422555282976331-2822584911005393223?l=blog.mysticlakesoftware.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mysticlakesoftware.com/feeds/2822584911005393223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.mysticlakesoftware.com/2010/01/blog-post.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/2822584911005393223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/2822584911005393223'/><link rel='alternate' type='text/html' href='http://blog.mysticlakesoftware.com/2010/01/blog-post.html' title='Subsumption Architecture - Introduction'/><author><name>Rud</name><uri>http://www.blogger.com/profile/05243211372637967124</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_dHdvnzWVL3Y/SlIHQ7QIyvI/AAAAAAAAACw/UgFpPAV8TSQ/S220/Rud+Cruise.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8561422555282976331.post-1300437721930901382</id><published>2010-01-25T14:53:00.005-06:00</published><updated>2010-01-25T17:43:20.985-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='robot hardware'/><category scheme='http://www.blogger.com/atom/ns#' term='robot'/><category scheme='http://www.blogger.com/atom/ns#' term='create'/><category scheme='http://www.blogger.com/atom/ns#' term='fit pc slim'/><title type='text'>Robot Components</title><content type='html'>Time to explain the components of the robot a bit more. The diagram provides an overview.&lt;br /&gt;&lt;br /&gt;The main platform is the iRobot Create. It is an autonmous robot by itself but provides control through a serial port connection using a protocol called the Open Interface (OI). The OI can read the sensors and control the actuators of the Create.&lt;br /&gt;&lt;br /&gt;The Fit PC Slim is a compact, low power PC with 3 USB ports and a Wifi, plus the usual PC components. It is powered from the Create through a voltage regulator on the Interface Board (IB). The IB also carries the USB interfaces for the serial port and I2C.&lt;br /&gt;&lt;p align="left"&gt;&lt;a href="http://3.bp.blogspot.com/_dHdvnzWVL3Y/S14E1BuWsxI/AAAAAAAAAXg/KSu7MLtXU2Q/s1600-h/Create+-+Slim+Components.PNG"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 400px; DISPLAY: block; HEIGHT: 307px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5430783509697835794" border="0" alt="" src="http://3.bp.blogspot.com/_dHdvnzWVL3Y/S14E1BuWsxI/AAAAAAAAAXg/KSu7MLtXU2Q/s400/Create+-+Slim+Components.PNG" /&gt;&lt;/a&gt;&lt;/p&gt;I2C is a standard 2 wire bus for controlling actuators and accessing sensor input. I'm not totally sure what is going to be on the bus. I expect a compass module, at least, to provide orientation. I have sonar and IR distance sensors working on I2C but am not sure which to use. These would be backup for detecting obstacles via vision processing. A main goal is for the robot to move around without bumping into obstacles. I also have a digital I/O board that could be used to provide LED indicators of what the robot is doing.&lt;br /&gt;&lt;br /&gt;The reasons for the Wifi on the Slim is to download software and allow monitoring from the desktop or laptop, especially in the field.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.roborealm.com/"&gt;RoboRealm &lt;/a&gt;(RR)is a software package whose main purpose is vision processing. It also has a lot of robot control capability, including a plug-in for the Create. I decided not to use that plug-in after some issues figuring out exactly how it worked. That may have been a mistake. My other concern was the latency of getting sensor information with it getting collected by RR and then collected from RR by the control program. RR will be used to handle the camera and vision processing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8561422555282976331-1300437721930901382?l=blog.mysticlakesoftware.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mysticlakesoftware.com/feeds/1300437721930901382/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.mysticlakesoftware.com/2010/01/time-to-explain-components-of-robot-bit.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/1300437721930901382'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/1300437721930901382'/><link rel='alternate' type='text/html' href='http://blog.mysticlakesoftware.com/2010/01/time-to-explain-components-of-robot-bit.html' title='Robot Components'/><author><name>Rud</name><uri>http://www.blogger.com/profile/05243211372637967124</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_dHdvnzWVL3Y/SlIHQ7QIyvI/AAAAAAAAACw/UgFpPAV8TSQ/S220/Rud+Cruise.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_dHdvnzWVL3Y/S14E1BuWsxI/AAAAAAAAAXg/KSu7MLtXU2Q/s72-c/Create+-+Slim+Components.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8561422555282976331.post-6490795100797808658</id><published>2010-01-25T13:45:00.003-06:00</published><updated>2010-01-25T14:31:08.271-06:00</updated><title type='text'>Create - Initialization Processing</title><content type='html'>Developing software is as much a research project as an engineering process. In part this is because a developer is not usually a domain knowledge expert, say, an accountant. The developer thus has to learn a fair amount about the domain in order to proceed. Still, some of the learning occurs as the project proceeds. You have to learn what you don't know.&lt;br /&gt;&lt;br /&gt;First lesson is that the Create doesn't provide unswitched power that is sufficient to run the Fit PC Slim. If the Create is turned on there is sufficient power. This means the Slim can't turn the Create power off because the Slim loses power, also.&lt;br /&gt;&lt;br /&gt;Ideally the Create can stay on all the time. It has a docking stations - its home base - for recharging. The built in processing can find the base and run onto it to charge, or my software could replicate that processing.&lt;br /&gt;&lt;br /&gt;First minor glitch is that the Create stops responding to the Slim commands when it docks. It turns out there is an undocumented  soft reset command (a '7') that puts it back into a mode where it will accept commands. Once back into this mode the Slim can monitor the charging process and determine when it is safe to leave the dock.&lt;br /&gt;&lt;br /&gt;When the Create is charging is a good time for doing work on the interface board or the Slim. What happens when you reconnect everything onto a charging Create?&lt;br /&gt;&lt;br /&gt;The (re)learned lesson is that startup and shutdown processing are often the most challenging parts of a software project. Once everything is up and running a software process is usually straightforward, albeit with a lot of details to chase. You just nibble away at them one at a time until they are all resolved. Then the process is just doing the same thing over and over again.&lt;br /&gt;&lt;br /&gt;Startup is a big discontinuity. What was the robot doing before it shutdown? What has changed since then? What is the current state now?&lt;br /&gt;&lt;br /&gt;This all was triggered when I realized the robot had to determine whether it was charging or in the wild when it started up. It takes different actions depending on where it is. If docked it continues until charged, backs off the dock, and switches to "wild" mode of operation.&lt;br /&gt;&lt;br /&gt;Okay, who said, "Rud, as an experienced developer you should have dealt with this already." Guilty as charged but this has been a casual, hobby project up until now. This was my wakeup to start applying a more formal approach and thinking through some of these issues. I'm still not going to go fully formal since I'm more interested in having fun. So don't expect a 6 week hiatus while I produce a formal analysis and design. I am going to do some of my thinking in blog posts, using it for my documentation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8561422555282976331-6490795100797808658?l=blog.mysticlakesoftware.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mysticlakesoftware.com/feeds/6490795100797808658/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.mysticlakesoftware.com/2010/01/create-initialization-processing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/6490795100797808658'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/6490795100797808658'/><link rel='alternate' type='text/html' href='http://blog.mysticlakesoftware.com/2010/01/create-initialization-processing.html' title='Create - Initialization Processing'/><author><name>Rud</name><uri>http://www.blogger.com/profile/05243211372637967124</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_dHdvnzWVL3Y/SlIHQ7QIyvI/AAAAAAAAACw/UgFpPAV8TSQ/S220/Rud+Cruise.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8561422555282976331.post-1868217052905028857</id><published>2010-01-25T13:41:00.003-06:00</published><updated>2010-01-25T13:45:00.720-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='galactic guardian'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Android - Not Abandoned</title><content type='html'>I'm not abandoning the Android work. I still want to get Galactic Guardian on the market in both a lite, free version, and a paid version. I'll just bounce between the robot and android projects as the spirit moves me.&lt;br /&gt;&lt;br /&gt;The report from the ADC2 was that 50% of the testers in phase one liked the game so it seems well worth the effort to submit it to the market.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8561422555282976331-1868217052905028857?l=blog.mysticlakesoftware.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mysticlakesoftware.com/feeds/1868217052905028857/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.mysticlakesoftware.com/2010/01/android-not-abandoned.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/1868217052905028857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/1868217052905028857'/><link rel='alternate' type='text/html' href='http://blog.mysticlakesoftware.com/2010/01/android-not-abandoned.html' title='Android - Not Abandoned'/><author><name>Rud</name><uri>http://www.blogger.com/profile/05243211372637967124</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_dHdvnzWVL3Y/SlIHQ7QIyvI/AAAAAAAAACw/UgFpPAV8TSQ/S220/Rud+Cruise.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8561422555282976331.post-1859608100427776916</id><published>2010-01-25T13:06:00.006-06:00</published><updated>2010-01-25T13:40:33.365-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='robot'/><category scheme='http://www.blogger.com/atom/ns#' term='create'/><category scheme='http://www.blogger.com/atom/ns#' term='fit pc slim'/><title type='text'>Shifting Gears - iRobot Create</title><content type='html'>I'm shifting gears to robotics. Awhile ago I got an iRobot Create. Its basically a Roomba vacuum cleaner with the guts removed  to make a cargo area. In this area is a 25-pin connector that provides power, TTL serial port, digital and analog I/O.&lt;br /&gt;&lt;br /&gt;I also got a Command Module (CM) which fits onto the connector. The CM is an Atmega 168 processor that adds some additional I/O. It can be programmed to control the Create. I did so and basically reproduced the wandering behavior of the Create. It move around, bumps into things and turns away from what it hit. I added some additional behaviors such as if it got trapped, i.e. caught in the same place for a period of 10 secs, it would move to extract itself.&lt;br /&gt;&lt;br /&gt;I want to do more with robots, such as entering in a &lt;a href="http://robogames.net/rules/magellan.shtml"&gt;RoboMagellan &lt;/a&gt;contest. That requires an outdoor capable robot that does a lot more than bump into things. A key component to me is vision. Maybe I could do that with the CM and another processor (like the &lt;a href="http://www.cs.cmu.edu/~cmucam/"&gt;CMUCam&lt;/a&gt;) but I really didn't want to learn YAPE (yet another programming environment).&lt;br /&gt;&lt;br /&gt;Around the time I got thinking seriously on this I looked at ITX boards. Then the Fit PC computers became available, specifically the &lt;a href="http://www.fit-pc.com/web/fit-pc2/other-products/"&gt;Fit PC Slim&lt;/a&gt;. The PC form and wireless sold me on trying to us it. The one drawback might be the processor speed when trying to do vision processing. That is acceptable because the Create with the Slim is a testbed for RoboMagellan where an entirely new, slightly larger platform will be used. By going with the PC as the base there are a large number of possibilities, including laptops and netbooks. If the processor is slow for vision the Create simply won't move as quickly or smoothly.&lt;br /&gt;&lt;br /&gt;I have the Slim hooked up to the Create, drawing power, and running most of the behaviors previoiusly implemented with the CM. Once I got the basic threading, serial communications, and Create interface working the behaviors started working within minutes since they ported easily from the CM versions. All the code is C++. Threading and serial port routines are all from previous projects so its all come together with a few days work.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8561422555282976331-1859608100427776916?l=blog.mysticlakesoftware.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mysticlakesoftware.com/feeds/1859608100427776916/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.mysticlakesoftware.com/2010/01/shifting-gears-irobot-create.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/1859608100427776916'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/1859608100427776916'/><link rel='alternate' type='text/html' href='http://blog.mysticlakesoftware.com/2010/01/shifting-gears-irobot-create.html' title='Shifting Gears - iRobot Create'/><author><name>Rud</name><uri>http://www.blogger.com/profile/05243211372637967124</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_dHdvnzWVL3Y/SlIHQ7QIyvI/AAAAAAAAACw/UgFpPAV8TSQ/S220/Rud+Cruise.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8561422555282976331.post-8667501193797278119</id><published>2009-09-03T05:08:00.005-05:00</published><updated>2009-09-03T05:17:31.281-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='galactic guardian'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><category scheme='http://www.blogger.com/atom/ns#' term='adc2'/><title type='text'>ADC2 - Package Name</title><content type='html'>&lt;p&gt;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. &lt;/p&gt;&lt;p&gt;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.&lt;/p&gt;&lt;p&gt;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. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8561422555282976331-8667501193797278119?l=blog.mysticlakesoftware.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mysticlakesoftware.com/feeds/8667501193797278119/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.mysticlakesoftware.com/2009/09/adc2-package-name.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/8667501193797278119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/8667501193797278119'/><link rel='alternate' type='text/html' href='http://blog.mysticlakesoftware.com/2009/09/adc2-package-name.html' title='ADC2 - Package Name'/><author><name>Rud</name><uri>http://www.blogger.com/profile/05243211372637967124</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_dHdvnzWVL3Y/SlIHQ7QIyvI/AAAAAAAAACw/UgFpPAV8TSQ/S220/Rud+Cruise.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8561422555282976331.post-2442171261802309100</id><published>2009-09-03T04:53:00.005-05:00</published><updated>2009-09-03T05:07:46.818-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='galactic guardian'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><category scheme='http://www.blogger.com/atom/ns#' term='adc2'/><title type='text'>Game Submitted to ADC2 - Galactic Guardian: Zap GPS</title><content type='html'>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!&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;You can see the material that appears in the game Info at &lt;a href="http://sites.google.com/site/mysticlakesoftware/"&gt;Mystic Lake Software&lt;/a&gt;. 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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8561422555282976331-2442171261802309100?l=blog.mysticlakesoftware.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mysticlakesoftware.com/feeds/2442171261802309100/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.mysticlakesoftware.com/2009/09/game-submitted-to-adc2-galactic.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/2442171261802309100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/2442171261802309100'/><link rel='alternate' type='text/html' href='http://blog.mysticlakesoftware.com/2009/09/game-submitted-to-adc2-galactic.html' title='Game Submitted to ADC2 - Galactic Guardian: Zap GPS'/><author><name>Rud</name><uri>http://www.blogger.com/profile/05243211372637967124</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_dHdvnzWVL3Y/SlIHQ7QIyvI/AAAAAAAAACw/UgFpPAV8TSQ/S220/Rud+Cruise.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8561422555282976331.post-3958454674182795345</id><published>2009-07-20T10:52:00.004-05:00</published><updated>2009-07-20T11:04:58.424-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='sensors'/><category scheme='http://www.blogger.com/atom/ns#' term='g1'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Sensor - Accelerometer &amp; Magnetics II</title><content type='html'>A quick update on the code I presented in the previous post.&lt;br /&gt;&lt;br /&gt;I'm not greatly experienced in Java having mainly worked with C++ for the last 15 plus years. I did have a company provided seminar on Java and have a half-dozen Java books on the shelf. But I'm still on the learning curve.&lt;br /&gt;&lt;br /&gt;In the code I obtained the magnetice, acclerometer, and orientation sensor arrays by simply assigning their &lt;em&gt;values&lt;/em&gt; to another array. I then used that array in subsequent calls to &lt;em&gt;onSensorChanged. &lt;/em&gt;Not the proper way of doing this. I should have cloned the arrays which makes a copy. For example:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;                case Sensor.TYPE_MAGNETIC_FIELD:&lt;br /&gt;                    mags = s_ev.values;&lt;br /&gt;                    isReady = true;&lt;br /&gt;                    break;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;should be:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;                case Sensor.TYPE_MAGNETIC_FIELD:&lt;br /&gt;                    mags = s_ev.values.clone();&lt;br /&gt;                    isReady = true;&lt;br /&gt;                    break;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I found this when I output all the values for the sensors to LogCat each time any one of them was updated. I noticed that the values for the accelerometer changed from its previous value when the orientation sensor was changed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8561422555282976331-3958454674182795345?l=blog.mysticlakesoftware.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mysticlakesoftware.com/feeds/3958454674182795345/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.mysticlakesoftware.com/2009/07/sensor-accelerometer-magnetics-ii.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/3958454674182795345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/3958454674182795345'/><link rel='alternate' type='text/html' href='http://blog.mysticlakesoftware.com/2009/07/sensor-accelerometer-magnetics-ii.html' title='Sensor - Accelerometer &amp; Magnetics II'/><author><name>Rud</name><uri>http://www.blogger.com/profile/05243211372637967124</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_dHdvnzWVL3Y/SlIHQ7QIyvI/AAAAAAAAACw/UgFpPAV8TSQ/S220/Rud+Cruise.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8561422555282976331.post-7175817776849915659</id><published>2009-07-13T15:38:00.014-05:00</published><updated>2009-09-03T04:52:53.365-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sensors'/><category scheme='http://www.blogger.com/atom/ns#' term='g1'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Sensor - Accelerometer &amp; Magnetics</title><content type='html'>Just as I was finishing my first look at the accelerometer and magnetic field sensors a couple of threads cropped up on the Android Developer's group:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://groups.google.com/group/android-developers/browse_frm/thread/1b42c48ce47cb1c9/720c6f4f8a40fc67#720c6f4f8a40fc67"&gt;http://groups.google.com/group/android-developers/browse_frm/thread/1b42c48ce47cb1c9/720c6f4f8a40fc67#720c6f4f8a40fc67&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://groups.google.com/group/android-developers/browse_frm/thread/2e14272d72b7ab4f"&gt;http://groups.google.com/group/android-developers/browse_frm/thread/2e14272d72b7ab4f&lt;/a&gt;#&lt;br /&gt;&lt;br /&gt;I had the basic code working so dug a little deeper into the rotation routines and the timing. I posted responses on the threads but want here to dig into the details more.&lt;br /&gt;&lt;br /&gt;First some observations applicable to my G1:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;The sensors report approximetly every 20, 40 and 220 msec for FAST, GAME, and NORMAL. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;A sample may be missed for a specific sensor but usually one of them will be generated - but sometimes all can be missed. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;The magnetic field sensor is most reliable with only a few drops. The other sensors are dropped considerably more often. &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p&gt;A caveat in all this is the way I setup the sensor handling may make a difference. I have a single routine for &lt;em&gt;onSensorChanged&lt;/em&gt; which handles all three sensors. It is possible that having three separate routines may produce different results. &lt;/p&gt;&lt;p&gt;One of the messages in the threads mentioned writing data to a file. I was concerned that writing to a file might cause delays in responding to the sensors. I collected my data by writing to the Log Cat. I then did a cut and paste to an editor, formatted the columns to CSV, and loaded the results into a spreadsheet for analysis. &lt;/p&gt;&lt;p&gt;Here is the code for capturing sensor information and peforming the rotations. &lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;span style="font-size:70;"&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    // ================================================================================================================&lt;br /&gt;    private class OrientationListner implements SensorEventListener {&lt;br /&gt;        final int matrix_size = 16;&lt;br /&gt;        float[] R = new float[matrix_size];&lt;br /&gt;        float[] outR = new float[matrix_size];&lt;br /&gt;        float[] I = new float[matrix_size];&lt;br /&gt;        float[] values = new float[3];&lt;br /&gt;        boolean isReady = false;&lt;br /&gt;&lt;br /&gt;        DigitalFilter[] filter =&lt;br /&gt;                                 { new DigitalFilter(), new DigitalFilter(), new DigitalFilter(), new DigitalFilter(),&lt;br /&gt;                                  new DigitalFilter(), new DigitalFilter() };&lt;br /&gt;        private long lastMagsTime;&lt;br /&gt;        private long lastAccelsTime;&lt;br /&gt;        private long lastOrientsTime;&lt;br /&gt;&lt;br /&gt;        // ------------------------------------------------------------------------------------------------------------&lt;br /&gt;        public void onSensorChanged(SensorEvent s_ev) {&lt;br /&gt;            Sensor sensor = s_ev.sensor;&lt;br /&gt;&lt;br /&gt;            int type = sensor.getType();&lt;br /&gt;&lt;br /&gt;            switch (type) {&lt;br /&gt;                case Sensor.TYPE_MAGNETIC_FIELD:&lt;br /&gt;                    mags = s_ev.values;&lt;br /&gt;                    isReady = true;&lt;br /&gt;                    break;&lt;br /&gt;                case Sensor.TYPE_ACCELEROMETER:&lt;br /&gt;                    accels = s_ev.values;&lt;br /&gt;                    break;&lt;br /&gt;                case Sensor.TYPE_ORIENTATION:&lt;br /&gt;                    orients = s_ev.values;&lt;br /&gt;                    Exp.mText04.setText("" + (int) orients[0]);&lt;br /&gt;                    Exp.mText05.setText("" + (int) orients[1]);&lt;br /&gt;                    Exp.mText06.setText("" + (int) orients[2]);&lt;br /&gt;                    break;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            if (mags != null &amp;amp;&amp;amp; accels != null &amp;amp;&amp;amp; isReady) {&lt;br /&gt;                isReady = false;&lt;br /&gt;&lt;br /&gt;                SensorManager.getRotationMatrix(R, I, accels, mags);&lt;br /&gt;&lt;br /&gt;                SensorManager.remapCoordinateSystem(R, SensorManager.AXIS_X, SensorManager.AXIS_Z, outR);&lt;br /&gt;                SensorManager.getOrientation(outR, values);&lt;br /&gt;                int[] v = new int[3];&lt;br /&gt;&lt;br /&gt;                v[0] = filter[0].average(values[0] * 100);&lt;br /&gt;                v[1] = filter[1].average(values[1] * 100);&lt;br /&gt;                v[2] = filter[2].average(values[2] * 100);&lt;br /&gt;&lt;br /&gt;                Exp.mText01.setText("" + v[0]);&lt;br /&gt;                Exp.mText02.setText("" + v[1]);&lt;br /&gt;                Exp.mText03.setText("" + v[2]);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        // ----------------------------------------------------------------------------------------------------------------&lt;br /&gt;        public void onAccuracyChanged(Sensor sensor, int accuracy) {&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Update&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;I had a couple of requests for the DigitalFilter class. It is below although it is called DigitalAverage. I took it from a later version of the code where I changed the name to better indicate its actual operation. I originally callsed it 'Filter' because I thought I might get more complex than an a simple average. &lt;/p&gt;&lt;p&gt;No, I'm not going to explain how to integrate the two pieces of code. That is left as an exercise for the reader. &lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;span style="font-size:75;"&gt;&lt;pre&gt;&lt;br /&gt;    // ================================================================================================================&lt;br /&gt;    private class DigitalAverage {&lt;br /&gt;&lt;br /&gt;        final int history_len = 4;&lt;br /&gt;        double[] mLocHistory = new double[history_len];&lt;br /&gt;        int mLocPos = 0;&lt;br /&gt;&lt;br /&gt;        // ------------------------------------------------------------------------------------------------------------&lt;br /&gt;        int average(double d) {&lt;br /&gt;            float avg = 0;&lt;br /&gt;&lt;br /&gt;            mLocHistory[mLocPos] = d;&lt;br /&gt;&lt;br /&gt;            mLocPos++;&lt;br /&gt;            if (mLocPos &gt; mLocHistory.length - 1) {&lt;br /&gt;                mLocPos = 0;&lt;br /&gt;            }&lt;br /&gt;            for (double h : mLocHistory) {&lt;br /&gt;                avg += h;&lt;br /&gt;            }&lt;br /&gt;            avg /= mLocHistory.length;&lt;br /&gt;&lt;br /&gt;            return (int) avg;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8561422555282976331-7175817776849915659?l=blog.mysticlakesoftware.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mysticlakesoftware.com/feeds/7175817776849915659/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.mysticlakesoftware.com/2009/07/sensor-accelerometer-magnetics.html#comment-form' title='18 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/7175817776849915659'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/7175817776849915659'/><link rel='alternate' type='text/html' href='http://blog.mysticlakesoftware.com/2009/07/sensor-accelerometer-magnetics.html' title='Sensor - Accelerometer &amp; Magnetics'/><author><name>Rud</name><uri>http://www.blogger.com/profile/05243211372637967124</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_dHdvnzWVL3Y/SlIHQ7QIyvI/AAAAAAAAACw/UgFpPAV8TSQ/S220/Rud+Cruise.JPG'/></author><thr:total>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8561422555282976331.post-2041453993423946233</id><published>2009-07-08T21:12:00.006-05:00</published><updated>2009-07-08T22:01:30.800-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sensor manager bug'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Differentiate Emulator from Device &amp; Unique IDs</title><content type='html'>I am working on a game which uses various of the sensors. There is a bug in the Cupcake 1.5 emulator (at least through r2) which causes the Sensor Manager to hang. The advice from the Google Developer Groups moderators is to debug on devices since you can't get sensor information from the emulator. (But look into OI Intents which has a sensor emulator for the emulator. I have not yet looked into it.)&lt;br /&gt;&lt;br /&gt;As a long time embedded systems developer this advice is absurd. There is all kinds of development work that can be accomplished without actual inputs, especially on a device with a GUI like the Android.&lt;br /&gt;&lt;br /&gt;Additionally, it just isn't convenient reaching over to my G1 to see what it is doing and to manipulate it to check orientation changes, etc. Hitting ctrl-F11 to change orientation on the emulator is much easier.&lt;br /&gt;&lt;br /&gt;I started wondering how to detect if the emulator or a device were running an application. This would allow skipping over the buggy Sensor Manager on the emulator to avoid the hang. Putting some conditional coding around sensor code might then allow development on the emulator.&lt;br /&gt;&lt;br /&gt;My investigation found two sets of information to differentiate the device and emulator. This information would also allow differentiating among devices so has some use in all applications.&lt;br /&gt;&lt;br /&gt;The first set of information is from the OS build. There are a number of fields available. All you need is the import and reading of the available fields. The comments after the code are from my emulator and the G1.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;import android.os.Build;&lt;br /&gt;// ...&lt;br /&gt;Log.d(TAG, "config" + "\n " + Build.BOARD + "\n " + Build.BRAND + "\n" + Build.DEVICE + "\n" + Build.DISPLAY + "\n" + Build.FINGERPRINT + "\n" + Build.HOST + "\n" + Build.ID + "\n" + Build.MODEL + "\n" + Build.PRODUCT + "\n" + Build.TAGS + "\n" + Build.TIME + "\n" + Build.TYPE + "\n" + Build.USER);&lt;br /&gt;&lt;br /&gt;// trout&lt;br /&gt;// tmobile&lt;br /&gt;// dream&lt;br /&gt;// CRB43&lt;br /&gt;// tmobile/kila/dream/trout:1.5/CRB43/148830:user/ota-rel-keys,release-keys&lt;br /&gt;// undroid11.mtv.corp.google.com&lt;br /&gt;// CRB43&lt;br /&gt;// T-Mobile G1&lt;br /&gt;// kila&lt;br /&gt;// ota-rel-keys,test-keys&lt;br /&gt;// 1242268990000&lt;br /&gt;// user&lt;br /&gt;// android-build &lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;// unknown&lt;br /&gt;// generic&lt;br /&gt;// generic&lt;br /&gt;// sdk-eng 1.5 CUPCAKE 148875 test-keys&lt;br /&gt;// generic/sdk/generic/:1.5/CUPCAKE/148875:eng/test-keys&lt;br /&gt;// e-honda.mtv.corp.google.com&lt;br /&gt;// CUPCAKE&lt;br /&gt;// sdk&lt;br /&gt;// sdk&lt;br /&gt;// test-keys&lt;br /&gt;// 1242347389000&lt;br /&gt;// eng&lt;br /&gt;// android-build&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;p&gt;The second differentiator is the Android ID which may be unique to each device. The emulator returns &lt;em&gt;null&lt;/em&gt; while the device returns a string. Again, after the code is my results, although I did corrupt my G1's ID since with proper permissions the value can be changed.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Log.d(TAG, "and id " + Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID));&lt;br /&gt;&lt;br /&gt;// G1: 200xxxxxd4cca5x&lt;br /&gt;// Emulator: null&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8561422555282976331-2041453993423946233?l=blog.mysticlakesoftware.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mysticlakesoftware.com/feeds/2041453993423946233/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.mysticlakesoftware.com/2009/07/differentiate-emulator-from-device.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/2041453993423946233'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/2041453993423946233'/><link rel='alternate' type='text/html' href='http://blog.mysticlakesoftware.com/2009/07/differentiate-emulator-from-device.html' title='Differentiate Emulator from Device &amp; Unique IDs'/><author><name>Rud</name><uri>http://www.blogger.com/profile/05243211372637967124</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_dHdvnzWVL3Y/SlIHQ7QIyvI/AAAAAAAAACw/UgFpPAV8TSQ/S220/Rud+Cruise.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8561422555282976331.post-4103771318127691500</id><published>2009-07-03T13:41:00.012-05:00</published><updated>2009-07-06T16:41:20.643-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Android Activity Analysis</title><content type='html'>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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;A number of discussions presented the life cycle as a &lt;a href="http://stuffthathappens.com/blog/2008/11/05/android-activity-lifecycle-updated/" target="_blank"&gt;state machine&lt;/a&gt;, as an alternative to the Google &lt;a href="http://developer.android.com/guide/topics/fundamentals.html#lcycles" target="_blank"&gt;flow chart&lt;/a&gt; (or &lt;a href="http://developer.android.com/reference/android/app/Activity.html" target="_blank"&gt;here&lt;/a&gt;). [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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;table style="WIDTH: auto"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://picasaweb.google.com/lh/photo/8NUIDvPYdFWYlNRC0-xErw?authkey=Gv1sRgCN_7kNHG9pGlAg&amp;amp;feat=embedwebsite"&gt;&lt;img src="http://lh5.ggpht.com/_dHdvnzWVL3Y/Sk5RWy8DQ9I/AAAAAAAAACE/_y4ZTpNl0Rg/s800/Android%20Activity%20%28Simple%29.png" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="FONT-SIZE: 11px; FONT-FAMILY: arial,sans-serif; TEXT-ALIGN: right"&gt;From &lt;a href="http://picasaweb.google.com/rudmerriam/MysticLakeSoftware?authkey=Gv1sRgCN_7kNHG9pGlAg&amp;amp;feat=embedwebsite"&gt;Mystic Lake Software&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;The file accompaning this page, &lt;a href="http://code.google.com/p/mysticlakesoftware/downloads/list"&gt;TemplateSurfaceView.zip&lt;/a&gt;, &lt;em&gt; &lt;/em&gt;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.&lt;br /&gt;&lt;br /&gt;In the TemplateSurvaceView (TSV), the Activity onXXX() routines are mimicked with corresponding doXXX() methods in the TSV class.&lt;br /&gt;&lt;br /&gt;doStart() - create thread&lt;br /&gt;doPause - pause thread&lt;br /&gt;doResume - resume thread&lt;br /&gt;doStop() - kill thread&lt;br /&gt;&lt;br /&gt;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().&lt;br /&gt;&lt;br /&gt;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 &lt;a href="http://java.sun.com/j2se/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html" target="_blank"&gt;Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated?&lt;/a&gt; for more information.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8561422555282976331-4103771318127691500?l=blog.mysticlakesoftware.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mysticlakesoftware.com/feeds/4103771318127691500/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.mysticlakesoftware.com/2009/07/android-activity-analysis.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/4103771318127691500'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/4103771318127691500'/><link rel='alternate' type='text/html' href='http://blog.mysticlakesoftware.com/2009/07/android-activity-analysis.html' title='Android Activity Analysis'/><author><name>Rud</name><uri>http://www.blogger.com/profile/05243211372637967124</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_dHdvnzWVL3Y/SlIHQ7QIyvI/AAAAAAAAACw/UgFpPAV8TSQ/S220/Rud+Cruise.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_dHdvnzWVL3Y/Sk5RWy8DQ9I/AAAAAAAAACE/_y4ZTpNl0Rg/s72-c/Android%20Activity%20%28Simple%29.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8561422555282976331.post-903308079454340310</id><published>2009-07-03T13:39:00.001-05:00</published><updated>2009-07-03T13:40:52.794-05:00</updated><title type='text'>Introduction</title><content type='html'>Actually a place holder for an introduction. I have an Android article I want to post but don't want it as the first blog entry.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8561422555282976331-903308079454340310?l=blog.mysticlakesoftware.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mysticlakesoftware.com/feeds/903308079454340310/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.mysticlakesoftware.com/2009/07/introduction.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/903308079454340310'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8561422555282976331/posts/default/903308079454340310'/><link rel='alternate' type='text/html' href='http://blog.mysticlakesoftware.com/2009/07/introduction.html' title='Introduction'/><author><name>Rud</name><uri>http://www.blogger.com/profile/05243211372637967124</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_dHdvnzWVL3Y/SlIHQ7QIyvI/AAAAAAAAACw/UgFpPAV8TSQ/S220/Rud+Cruise.JPG'/></author><thr:total>0</thr:total></entry></feed>
