Rossum--Android上ROS开发——android_core创建一个android应用

From:http://blog.csdn.net/f_season/article/details/9177931

前面已经讲了很多android_core,rosjava的介绍,如果你配置好了android_core,接下来就可以开发rosjava-android程序了。

首先在eclipse下创建一个android程序,然后使用RosActivity,下面给出官方范例详细介绍。

RosActivity是所有ROS Android应用的基本类,我们给出android_tutorial_pubsub来介绍如何写最基本ROS的Publisher和Subscriber。当学会Publisher和Subscriber也就相当于学会ROSjava一大半了,因为ROS机器人的所有行为都是建立在信息的发送与订阅的基础上。

原始地址来自:http://docs.rosjava.googlecode.com/hg/android_core/html/getting_started.html

[java]  view plain copy
  1. package org.ros.android.android_tutorial_pubsub;  
  2.   
  3. import android.os.Bundle;  
  4. import org.ros.android.MessageCallable;  
  5. import org.ros.android.RosActivity;  
  6. import org.ros.android.view.RosTextView;  
  7. import org.ros.node.NodeConfiguration;  
  8. import org.ros.node.NodeMainExecutor;  
  9. import org.ros.rosjava_tutorial_pubsub.Talker;  
  10.   
  11. /** 
  12.  * @author damonkohler@google.com (Damon Kohler) 
  13.  */  
  14. public class MainActivity extends RosActivity {  
  15.   
  16.   private RosTextView<std_msgs.String> rosTextView;  
  17.   private Talker talker;  
  18.   
  19.   public MainActivity() {  
  20.     // The RosActivity constructor configures the notification title and ticker  
  21.     // messages.  
  22.     super("Pubsub Tutorial""Pubsub Tutorial");  
  23.   }  
  24.   
  25.   @SuppressWarnings("unchecked")  
  26.   @Override  
  27.   public void onCreate(Bundle savedInstanceState) {  
  28.     super.onCreate(savedInstanceState);  
  29.     setContentView(R.layout.main);  
  30.     rosTextView = (RosTextView<std_msgs.String>) findViewById(R.id.text);  
  31.     rosTextView.setTopicName("chatter");  
  32.     rosTextView.setMessageType(std_msgs.String._TYPE);  
  33.     rosTextView.setMessageToStringCallable(new MessageCallable<String, std_msgs.String>() {  
  34.       @Override  
  35.       public String call(std_msgs.String message) {  
  36.         return message.getData();  
  37.       }  
  38.     });  
  39.   }  
  40.   
  41.   @Override  
  42.   protected void init(NodeMainExecutor nodeMainExecutor) {  
  43.     talker = new Talker();  
  44.     NodeConfiguration nodeConfiguration = NodeConfiguration.newPrivate();  
  45.     // At this point, the user has already been prompted to either enter the URI  
  46.     // of a master to use or to start a master locally.  
  47.     nodeConfiguration.setMasterUri(getMasterUri());  
  48.     nodeMainExecutor.execute(talker, nodeConfiguration);  
  49.     // The RosTextView is also a NodeMain that must be executed in order to  
  50.     // start displaying incoming messages.  
  51.     nodeMainExecutor.execute(rosTextView, nodeConfiguration);  
  52.   }  
  53. }  
在第14行,我们需要extends RosActivity。这样当activity启动时:

1.在前台启动NodeMainExecutorService

2.开始一个 MasterChooser activity来提示用户填写master URI,并且显示正在进行的通告信息通知用户ROS节点正在后台运行。

第22行的超构造函数中,两个字符串是Android通告的标题和断续器信息。用户只需要关闭这个通告就可以关闭与该应用联系的所有ROS节点。

第28-30行,android开发者都熟悉。

第42行我们定义抽象函数 RosActivity.init,这里我们开始了 NodeMain。与用户填写的masterURI建立连接,执行talker发布信息,执行rosTextView显示输入信息。而且这里RosAcitivity操纵着其他应用的生命周期的管理,包括:

1.获取和释放WakeLocksWifiLocks

2.捆绑或者松绑NodeMainExecutorService

3.当应用关闭时结束NodeMain

看完上面的代码,其实我们应该明白具体怎么发送信息关键在于Talker类,下面就来段代码解释下

[java]  view plain copy
  1. package rosjava.wtf.pocketsphinx.version1;  
  2.   
  3. import org.ros.concurrent.CancellableLoop;  
  4. import org.ros.namespace.GraphName;  
  5. import org.ros.node.AbstractNodeMain;  
  6. import org.ros.node.ConnectedNode;  
  7. import org.ros.node.topic.Publisher;  
  8.   
  9. public class Talker extends AbstractNodeMain {  
  10.   
  11.         
  12.   @Override  
  13.   public GraphName getDefaultNodeName() {  
  14.     return GraphName.of("rosjava_tutorial_pubsub/talker");  
  15.   }  
  16.   
  17.   @Override  
  18.   public void onStart(final ConnectedNode connectedNode) {  
  19.     final Publisher<std_msgs.String> publisher =  
  20.         connectedNode.newPublisher("recognizer/output", std_msgs.String._TYPE);  
  21.     // This CancellableLoop will be canceled automatically when the node shuts  
  22.     // down.  
  23.     connectedNode.executeCancellableLoop(new CancellableLoop() {  
  24.           
  25.       @Override  
  26.       protected void setup() {  
  27.       }  
  28.   
  29.       @Override  
  30.       public void loop() throws InterruptedException {  
  31.           std_msgs.String str = publisher.newMessage();  
  32.         str.setData( TalkParam.tmpstring );  
  33.         publisher.publish(str);  
  34.        Thread.sleep(250);  
  35.       }  
  36.     });  
  37.   }  
  38. }  
第9行,需要extends AbstractNodeMain。第19-20行,我们设置信息格式为std_msgs.String._TYPE,这个是发送字符串信息,发送给recognizer/output主题,这两点是publisher的关键。

后面就是进入loop()循环发送信息。补充下,控制电机的信息选用geometry_msgs/Twist格式,控制舵机的选用sensor_msgs/JointState格式,后续文章会详细提到。

接下来描述下subscribe。这个android_core堆提供了许多Android实现NodeMain的视图方法。例如,我们接下来要看的RosTextView的实现。这个视图的目的就是用文本表示发布的消息并显示。

[java]  view plain copy
  1. package org.ros.android.view;  
  2.   
  3. import android.content.Context;  
  4. import android.util.AttributeSet;  
  5. import android.widget.TextView;  
  6. import org.ros.android.MessageCallable;  
  7. import org.ros.message.MessageListener;  
  8. import org.ros.namespace.GraphName;  
  9. import org.ros.node.ConnectedNode;  
  10. import org.ros.node.Node;  
  11. import org.ros.node.NodeMain;  
  12. import org.ros.node.topic.Subscriber;  
  13.   
  14. /** 
  15.  * @author damonkohler@google.com (Damon Kohler) 
  16.  */  
  17. public class RosTextView<T> extends TextView implements NodeMain {  
  18.   
  19.   private String topicName;  
  20.   private String messageType;  
  21.   
  22.   public void setTopicName(String topicName) {  
  23.     this.topicName = topicName;  
  24.   }  
  25.   
  26.   public void setMessageType(String messageType) {  
  27.     this.messageType = messageType;  
  28.   }  
  29.   
  30.   public void setMessageToStringCallable(MessageCallable<String, T> callable) {  
  31.     this.callable = callable;  
  32.   }  
  33.   
  34.   @Override  
  35.   public GraphName getDefaultNodeName() {  
  36.     return new GraphName("android_gingerbread/ros_text_view");  
  37.   }  
  38.   
  39.   @Override  
  40.   public void onStart(ConnectedNode connectedNode) {  
  41.     Subscriber<T> subscriber = connectedNode.newSubscriber(topicName, messageType);  
  42.     subscriber.addMessageListener(new MessageListener<T>() {  
  43.       @Override  
  44.       public void onNewMessage(final T message) {  
  45.         if (callable != null) {  
  46.           post(new Runnable() {  
  47.             @Override  
  48.             public void run() {  
  49.               setText(callable.call(message));  
  50.             }  
  51.           });  
  52.         } else {  
  53.           post(new Runnable() {  
  54.             @Override  
  55.             public void run() {  
  56.               setText(message.toString());  
  57.             }  
  58.           });  
  59.         }  
  60.         postInvalidate();  
  61.       }  
  62.     });  
  63.   }  
  64.   
  65.   @Override  
  66.   public void onShutdown(Node node) {  
  67.   }  
  68.   
  69.   @Override  
  70.   public void onShutdownComplete(Node node) {  
  71.   }  
  72.   
  73.   @Override  
  74.   public void onError(Node node, Throwable throwable) {  
  75.   }  
  76. }  
这个视图已经配置了主 题topicName和信息格式messageType以及MessageCallable 在40行的   NodeMain.onStart 类函数中,我们创建一个Subscriber来订阅已经配置的主题和信息格式。

在49行我们将新接收到的信息转变成一个字符串。如果没有收到信息,就像56行,我们就使用默认的toString(),然后发送文本到视图上来显示收到的信息。

就像其他NodeMain一样,RosTextView被NodeMainExecutor执行。在上述RosActivity示例中,我们在RosActivity.init中执行了它,并且使用它在Talker节点中显示传入的消息。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值