| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431 | 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml">  <head>    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />        <title>Getting started — android_core 0.0.0-SNAPSHOT documentation</title>        <link rel="stylesheet" href="_static/haiku.css" type="text/css" />    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />    <link rel="stylesheet" href="_static/print.css" type="text/css" />        <script type="text/javascript">      var DOCUMENTATION_OPTIONS = {        URL_ROOT:    '',        VERSION:     '0.0.0-SNAPSHOT',        COLLAPSE_INDEX: false,        FILE_SUFFIX: '.html',        HAS_SOURCE:  true      };    </script>    <script type="text/javascript" src="_static/jquery.js"></script>    <script type="text/javascript" src="_static/underscore.js"></script>    <script type="text/javascript" src="_static/doctools.js"></script>    <script type="text/javascript" src="_static/theme_extras.js"></script>    <link rel="top" title="android_core 0.0.0-SNAPSHOT documentation" href="index.html" />    <link rel="prev" title="Building android_core" href="building.html" />   </head>  <body>      <div class="header"><h1 class="heading"><a href="index.html">          <span>android_core 0.0.0-SNAPSHOT documentation</span></a></h1>        <h2 class="heading"><span>Getting started</span></h2>      </div>      <div class="topnav">              <p>        «  <a href="building.html">Building android_core</a>          ::          <a class="uplink" href="index.html">Contents</a>        </p>      </div>      <div class="content">                  <div class="section" id="getting-started"><span id="id1"></span><h1>Getting started<a class="headerlink" href="#getting-started" title="Permalink to this headline">¶</a></h1><p>Before diving into ROS enabled Android application development, you should befamiliar with <em class="xref std std-ref">rosjava</em> and <a class="reference external" href="http://developer.android.com/training/index.html">Androidapplication development</a> in general.</p><div class="section" id="creating-a-new-android-application"><h2>Creating a new Android application<a class="headerlink" href="#creating-a-new-android-application" title="Permalink to this headline">¶</a></h2><div class="admonition note"><p class="first admonition-title">Note</p><p class="last">This is still a work in progress. There are many obvious limitationsand the process will be improved in the near future.</p></div><p>Currently, the easiest way to create a new application is to create your ownpackage in the android_core stack by copying one of the tutorial packages (e.g.android_tutorial_pubsub).</p><div class="highlight-bash"><div class="highlight"><pre>roscd android_corecp -a android_tutorial_pubsub my_package</pre></div></div><p>After that, modify android_core/settings.gradle to include your new package.</p><div class="highlight-bash"><div class="highlight"><pre>rosed android_core/settings.gradle./gradlew my_package:clean my_package:debug</pre></div></div><p>At this point, you may interact with your Android projects as described in the<a class="reference external" href="http://developer.android.com/guide/developing/building/building-cmdline.html">Android documentation</a>. Please start there if the following quick startinstructions are insufficient for you.</p><p>Use <a class="reference external" href="http://ant.apache.org/">Apache Ant</a> to install your new Android application:</p><div class="highlight-bash"><div class="highlight"><pre>roscd my_packageant installd</pre></div></div><p>You can also use ant to build the application. However, if you add, remove, ormodify a dependency in the build.gradle file, you will need to execute the<a class="reference external" href="http://gradle.org/docs/current/userguide/gradle_wrapper.html">gradle wrapper</a> as described above in order to update the Androidapplication’s external dependencies (located in the <tt class="docutils literal"><span class="pre">my_package/libs</span></tt>directory).</p><div class="admonition note"><p class="first admonition-title">Note</p><p class="last">You may also build and run your application from Eclipse. For moreinformation, see <a class="reference internal" href="building.html"><em>Building android_core</em></a>.</p></div></div><div class="section" id="using-rosactivity"><span id="life-of-a-rosactivity"></span><h2>Using RosActivity<a class="headerlink" href="#using-rosactivity" title="Permalink to this headline">¶</a></h2><p>The <a class="reference external" href="javadoc/org/ros/android/RosActivity.html#">RosActivity</a> class is the base class for all ofyour ROS enabled Android applications. Let’s consider the following examplefrom the android_tutorial_pubsub package. In this example, we create a<a class="reference external" href="javadoc/org/ros/node/topic/Publisher.html#">Publisher</a> and a<a class="reference external" href="javadoc/org/ros/node/topic/Subscriber.html#">Subscriber</a> that will exchange “Hello, World”messages.</p><div class="highlight-java"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829303132333435363738394041424344454647484950515253</pre></div></td><td class="code"><div class="highlight"><pre><span class="kn">package</span> <span class="n">org</span><span class="o">.</span><span class="na">ros</span><span class="o">.</span><span class="na">android</span><span class="o">.</span><span class="na">android_tutorial_pubsub</span><span class="o">;</span><span class="kn">import</span> <span class="nn">android.os.Bundle</span><span class="o">;</span><span class="kn">import</span> <span class="nn">org.ros.android.MessageCallable</span><span class="o">;</span><span class="kn">import</span> <span class="nn">org.ros.android.RosActivity</span><span class="o">;</span><span class="kn">import</span> <span class="nn">org.ros.android.view.RosTextView</span><span class="o">;</span><span class="kn">import</span> <span class="nn">org.ros.node.NodeConfiguration</span><span class="o">;</span><span class="kn">import</span> <span class="nn">org.ros.node.NodeMainExecutor</span><span class="o">;</span><span class="kn">import</span> <span class="nn">org.ros.rosjava_tutorial_pubsub.Talker</span><span class="o">;</span><span class="cm">/**</span><span class="cm"> * @author damonkohler@google.com (Damon Kohler)</span><span class="cm"> */</span><span class="hll"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">MainActivity</span> <span class="kd">extends</span> <span class="n">RosActivity</span> <span class="o">{</span></span>  <span class="kd">private</span> <span class="n">RosTextView</span><span class="o"><</span><span class="n">std_msgs</span><span class="o">.</span><span class="na">String</span><span class="o">></span> <span class="n">rosTextView</span><span class="o">;</span>  <span class="kd">private</span> <span class="n">Talker</span> <span class="n">talker</span><span class="o">;</span>  <span class="kd">public</span> <span class="nf">MainActivity</span><span class="o">()</span> <span class="o">{</span>    <span class="c1">// The RosActivity constructor configures the notification title and ticker</span>    <span class="c1">// messages.</span><span class="hll">    <span class="kd">super</span><span class="o">(</span><span class="s">"Pubsub Tutorial"</span><span class="o">,</span> <span class="s">"Pubsub Tutorial"</span><span class="o">);</span></span>  <span class="o">}</span>  <span class="nd">@SuppressWarnings</span><span class="o">(</span><span class="s">"unchecked"</span><span class="o">)</span>  <span class="nd">@Override</span>  <span class="kd">public</span> <span class="kt">void</span> <span class="nf">onCreate</span><span class="o">(</span><span class="n">Bundle</span> <span class="n">savedInstanceState</span><span class="o">)</span> <span class="o">{</span><span class="hll">    <span class="kd">super</span><span class="o">.</span><span class="na">onCreate</span><span class="o">(</span><span class="n">savedInstanceState</span><span class="o">);</span></span><span class="hll">    <span class="n">setContentView</span><span class="o">(</span><span class="n">R</span><span class="o">.</span><span class="na">layout</span><span class="o">.</span><span class="na">main</span><span class="o">);</span></span><span class="hll">    <span class="n">rosTextView</span> <span class="o">=</span> <span class="o">(</span><span class="n">RosTextView</span><span class="o"><</span><span class="n">std_msgs</span><span class="o">.</span><span class="na">String</span><span class="o">>)</span> <span class="n">findViewById</span><span class="o">(</span><span class="n">R</span><span class="o">.</span><span class="na">id</span><span class="o">.</span><span class="na">text</span><span class="o">);</span></span>    <span class="n">rosTextView</span><span class="o">.</span><span class="na">setTopicName</span><span class="o">(</span><span class="s">"chatter"</span><span class="o">);</span>    <span class="n">rosTextView</span><span class="o">.</span><span class="na">setMessageType</span><span class="o">(</span><span class="n">std_msgs</span><span class="o">.</span><span class="na">String</span><span class="o">.</span><span class="na">_TYPE</span><span class="o">);</span>    <span class="n">rosTextView</span><span class="o">.</span><span class="na">setMessageToStringCallable</span><span class="o">(</span><span class="k">new</span> <span class="n">MessageCallable</span><span class="o"><</span><span class="n">String</span><span class="o">,</span> <span class="n">std_msgs</span><span class="o">.</span><span class="na">String</span><span class="o">>()</span> <span class="o">{</span>      <span class="nd">@Override</span>      <span class="kd">public</span> <span class="n">String</span> <span class="nf">call</span><span class="o">(</span><span class="n">std_msgs</span><span class="o">.</span><span class="na">String</span> <span class="n">message</span><span class="o">)</span> <span class="o">{</span>        <span class="k">return</span> <span class="n">message</span><span class="o">.</span><span class="na">getData</span><span class="o">();</span>      <span class="o">}</span>    <span class="o">});</span>  <span class="o">}</span>  <span class="nd">@Override</span><span class="hll">  <span class="kd">protected</span> <span class="kt">void</span> <span class="nf">init</span><span class="o">(</span><span class="n">NodeMainExecutor</span> <span class="n">nodeMainExecutor</span><span class="o">)</span> <span class="o">{</span></span>    <span class="n">talker</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Talker</span><span class="o">();</span>    <span class="n">NodeConfiguration</span> <span class="n">nodeConfiguration</span> <span class="o">=</span> <span class="n">NodeConfiguration</span><span class="o">.</span><span class="na">newPrivate</span><span class="o">();</span>    <span class="c1">// At this point, the user has already been prompted to either enter the URI</span>    <span class="c1">// of a master to use or to start a master locally.</span>    <span class="n">nodeConfiguration</span><span class="o">.</span><span class="na">setMasterUri</span><span class="o">(</span><span class="n">getMasterUri</span><span class="o">());</span>    <span class="n">nodeMainExecutor</span><span class="o">.</span><span class="na">execute</span><span class="o">(</span><span class="n">talker</span><span class="o">,</span> <span class="n">nodeConfiguration</span><span class="o">);</span>    <span class="c1">// The RosTextView is also a NodeMain that must be executed in order to</span>    <span class="c1">// start displaying incoming messages.</span>    <span class="n">nodeMainExecutor</span><span class="o">.</span><span class="na">execute</span><span class="o">(</span><span class="n">rosTextView</span><span class="o">,</span> <span class="n">nodeConfiguration</span><span class="o">);</span>  <span class="o">}</span><span class="o">}</span></pre></div></td></tr></table></div><p>On line 14, we extend <a class="reference external" href="javadoc/org/ros/android/RosActivity.html#">RosActivity</a>.  When our<a class="reference external" href="http://developer.android.com/reference/android/app/Activity.html">activity</a> starts, the <a class="reference external" href="javadoc/org/ros/android/RosActivity.html#">RosActivity</a> super class will:</p><ul class="simple"><li>start the <a class="reference external" href="javadoc/org/ros/android/NodeMainExecutorService.html#">NodeMainExecutorService</a> as a <a class="reference external" href="http://developer.android.com/reference/android/app/Service.html">service</a>in the <a class="reference external" href="http://developer.android.com/reference/android/app/Service.html#startForeground(int,android.app.Notification)">foreground</a>,</li><li>launch the <a class="reference external" href="javadoc/org/ros/android/MasterChooser.html#">MasterChooser</a> activity to prompt theuser to configure a master URI,</li><li>and display an ongoing <a class="reference external" href="http://developer.android.com/reference/android/app/Notification.html">notification</a> informing the user that ROS nodes arerunning in the background.</li></ul><p>On line 22 we call the super constructor with two strings that become the titleand ticker message of an Android <a class="reference external" href="http://developer.android.com/reference/android/app/Notification.html">notification</a>. The user may tap on thenotification to shut down all ROS nodes associated with the application.</p><p>Lines 28-30 should look familiar to Android developers. We load the <a class="reference external" href="http://developer.android.com/reference/android/app/Activity.html">activity</a>layout and get a reference to our<a class="reference external" href="javadoc/org/ros/android/view/RosTextView.html#">RosTextView</a> (more on that later).</p><p>On line 42 we define the abstract method<a class="reference external" href="javadoc/org/ros/android/RosActivity.html#init(org.ros.node.NodeMainExecutor)">RosActivity.init</a>.This is where we kick off our <a class="reference external" href="javadoc/org/ros/node/NodeMain.html#">NodeMain</a>s and otherbusiness logic.</p><p>And that’s it. <a class="reference external" href="javadoc/org/ros/android/RosActivity.html#">RosActivity</a> handles the rest of theapplication’s lifecycle management including:</p><ul class="simple"><li>acquiring and releasing <a class="reference external" href="http://developer.android.com/reference/android/os/PowerManager.WakeLock.html">WakeLocks</a> and <a class="reference external" href="http://developer.android.com/reference/android/net/wifi/WifiManager.WifiLock.html">WifiLocks</a>,</li><li>binding and unbinding the <a class="reference external" href="javadoc/org/ros/android/NodeMainExecutorService.html#">NodeMainExecutorService</a>,</li><li>and shutting down <a class="reference external" href="javadoc/org/ros/node/NodeMain.html#">NodeMain</a>s when the application exits.</li></ul></div><div class="section" id="nodes-and-views"><h2>Nodes and Views<a class="headerlink" href="#nodes-and-views" title="Permalink to this headline">¶</a></h2><p>The android_core stack provides a number of Android <a class="reference external" href="http://developer.android.com/reference/android/view/View.html">Views</a> which implement<a class="reference external" href="javadoc/org/ros/node/NodeMain.html#">NodeMain</a>. For example, let’s look at the implementationof <a class="reference external" href="javadoc/org/ros/android/view/RosTextView.html#">RosTextView</a>. The intent of this view isto display the textual representation of published messages.</p><div class="highlight-java"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1 2 3 4 5 6 7 8 910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576</pre></div></td><td class="code"><div class="highlight"><pre><span class="kn">package</span> <span class="n">org</span><span class="o">.</span><span class="na">ros</span><span class="o">.</span><span class="na">android</span><span class="o">.</span><span class="na">view</span><span class="o">;</span><span class="kn">import</span> <span class="nn">android.content.Context</span><span class="o">;</span><span class="kn">import</span> <span class="nn">android.util.AttributeSet</span><span class="o">;</span><span class="kn">import</span> <span class="nn">android.widget.TextView</span><span class="o">;</span><span class="kn">import</span> <span class="nn">org.ros.android.MessageCallable</span><span class="o">;</span><span class="kn">import</span> <span class="nn">org.ros.message.MessageListener</span><span class="o">;</span><span class="kn">import</span> <span class="nn">org.ros.namespace.GraphName</span><span class="o">;</span><span class="kn">import</span> <span class="nn">org.ros.node.ConnectedNode</span><span class="o">;</span><span class="kn">import</span> <span class="nn">org.ros.node.Node</span><span class="o">;</span><span class="kn">import</span> <span class="nn">org.ros.node.NodeMain</span><span class="o">;</span><span class="kn">import</span> <span class="nn">org.ros.node.topic.Subscriber</span><span class="o">;</span><span class="cm">/**</span><span class="cm"> * @author damonkohler@google.com (Damon Kohler)</span><span class="cm"> */</span><span class="kd">public</span> <span class="kd">class</span> <span class="nc">RosTextView</span><span class="o"><</span><span class="n">T</span><span class="o">></span> <span class="kd">extends</span> <span class="n">TextView</span> <span class="kd">implements</span> <span class="n">NodeMain</span> <span class="o">{</span>  <span class="kd">private</span> <span class="n">String</span> <span class="n">topicName</span><span class="o">;</span>  <span class="kd">private</span> <span class="n">String</span> <span class="n">messageType</span><span class="o">;</span>  <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setTopicName</span><span class="o">(</span><span class="n">String</span> <span class="n">topicName</span><span class="o">)</span> <span class="o">{</span>    <span class="k">this</span><span class="o">.</span><span class="na">topicName</span> <span class="o">=</span> <span class="n">topicName</span><span class="o">;</span>  <span class="o">}</span>  <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setMessageType</span><span class="o">(</span><span class="n">String</span> <span class="n">messageType</span><span class="o">)</span> <span class="o">{</span>    <span class="k">this</span><span class="o">.</span><span class="na">messageType</span> <span class="o">=</span> <span class="n">messageType</span><span class="o">;</span>  <span class="o">}</span>  <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setMessageToStringCallable</span><span class="o">(</span><span class="n">MessageCallable</span><span class="o"><</span><span class="n">String</span><span class="o">,</span> <span class="n">T</span><span class="o">></span> <span class="n">callable</span><span class="o">)</span> <span class="o">{</span>    <span class="k">this</span><span class="o">.</span><span class="na">callable</span> <span class="o">=</span> <span class="n">callable</span><span class="o">;</span>  <span class="o">}</span>  <span class="nd">@Override</span>  <span class="kd">public</span> <span class="n">GraphName</span> <span class="nf">getDefaultNodeName</span><span class="o">()</span> <span class="o">{</span>    <span class="k">return</span> <span class="k">new</span> <span class="nf">GraphName</span><span class="o">(</span><span class="s">"android_gingerbread/ros_text_view"</span><span class="o">);</span>  <span class="o">}</span>  <span class="nd">@Override</span><span class="hll">  <span class="kd">public</span> <span class="kt">void</span> <span class="nf">onStart</span><span class="o">(</span><span class="n">ConnectedNode</span> <span class="n">connectedNode</span><span class="o">)</span> <span class="o">{</span></span>    <span class="n">Subscriber</span><span class="o"><</span><span class="n">T</span><span class="o">></span> <span class="n">subscriber</span> <span class="o">=</span> <span class="n">connectedNode</span><span class="o">.</span><span class="na">newSubscriber</span><span class="o">(</span><span class="n">topicName</span><span class="o">,</span> <span class="n">messageType</span><span class="o">);</span>    <span class="n">subscriber</span><span class="o">.</span><span class="na">addMessageListener</span><span class="o">(</span><span class="k">new</span> <span class="n">MessageListener</span><span class="o"><</span><span class="n">T</span><span class="o">>()</span> <span class="o">{</span>      <span class="nd">@Override</span>      <span class="kd">public</span> <span class="kt">void</span> <span class="nf">onNewMessage</span><span class="o">(</span><span class="kd">final</span> <span class="n">T</span> <span class="n">message</span><span class="o">)</span> <span class="o">{</span>        <span class="k">if</span> <span class="o">(</span><span class="n">callable</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>          <span class="n">post</span><span class="o">(</span><span class="k">new</span> <span class="n">Runnable</span><span class="o">()</span> <span class="o">{</span>            <span class="nd">@Override</span>            <span class="kd">public</span> <span class="kt">void</span> <span class="nf">run</span><span class="o">()</span> <span class="o">{</span><span class="hll">              <span class="n">setText</span><span class="o">(</span><span class="n">callable</span><span class="o">.</span><span class="na">call</span><span class="o">(</span><span class="n">message</span><span class="o">));</span></span>            <span class="o">}</span>          <span class="o">});</span>        <span class="o">}</span> <span class="k">else</span> <span class="o">{</span>          <span class="n">post</span><span class="o">(</span><span class="k">new</span> <span class="n">Runnable</span><span class="o">()</span> <span class="o">{</span>            <span class="nd">@Override</span>            <span class="kd">public</span> <span class="kt">void</span> <span class="nf">run</span><span class="o">()</span> <span class="o">{</span><span class="hll">              <span class="n">setText</span><span class="o">(</span><span class="n">message</span><span class="o">.</span><span class="na">toString</span><span class="o">());</span></span>            <span class="o">}</span>          <span class="o">});</span>        <span class="o">}</span>        <span class="n">postInvalidate</span><span class="o">();</span>      <span class="o">}</span>    <span class="o">});</span>  <span class="o">}</span>  <span class="nd">@Override</span>  <span class="kd">public</span> <span class="kt">void</span> <span class="nf">onShutdown</span><span class="o">(</span><span class="n">Node</span> <span class="n">node</span><span class="o">)</span> <span class="o">{</span>  <span class="o">}</span>  <span class="nd">@Override</span>  <span class="kd">public</span> <span class="kt">void</span> <span class="nf">onShutdownComplete</span><span class="o">(</span><span class="n">Node</span> <span class="n">node</span><span class="o">)</span> <span class="o">{</span>  <span class="o">}</span>  <span class="nd">@Override</span>  <span class="kd">public</span> <span class="kt">void</span> <span class="nf">onError</span><span class="o">(</span><span class="n">Node</span> <span class="n">node</span><span class="o">,</span> <span class="n">Throwable</span> <span class="n">throwable</span><span class="o">)</span> <span class="o">{</span>  <span class="o">}</span><span class="o">}</span></pre></div></td></tr></table></div><p>The view is configured with a topic name, message type, and a<a class="reference external" href="javadoc/org/ros/android/MessageCallable.html#">MessageCallable</a>. On line 40, in the<a class="reference external" href="javadoc/org/ros/node/NodeMain.html#onStart(Node)">NodeMain.onStart</a> method, we create a new<a class="reference external" href="javadoc/org/ros/node/topic/Subscriber.html#">Subscriber</a> for the configured topic and messagetype.</p><p>When a new message arrives, we either use the configured callable to transformthe incoming message to a string (line 49), or we use the default<tt class="docutils literal"><span class="pre">toString()</span></tt> method if no callable was configured (line 56). We then set thetext of the view to the string representation of the incoming message.</p><p>As with any other <a class="reference external" href="javadoc/org/ros/node/NodeMain.html#">NodeMain</a>, the<a class="reference external" href="javadoc/org/ros/android/view/RosTextView.html#">RosTextView</a> must be executed by the<a class="reference external" href="javadoc/org/ros/node/NodeMainExecutor.html#">NodeMainExecutor</a>. In the <a class="reference internal" href="#life-of-a-rosactivity"><em>Using RosActivity</em></a>example, we execute it in<a class="reference external" href="javadoc/org/ros/android/RosActivity.html#init(NodeMainExecutor)">RosActivity.init</a> and use the it todisplay incoming messages from the<a class="reference external" href="javadoc/org/ros/rosjava_tutorial_pubsub/Talker.html#">Talker</a> node.</p></div></div>      </div>      <div class="bottomnav">              <p>        «  <a href="building.html">Building android_core</a>          ::          <a class="uplink" href="index.html">Contents</a>        </p>      </div>    <div class="footer">        © Copyright 2012, Google, Inc..      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.    </div>  </body></html>
 |