ROSJava安装和在Android中使用ROS
这里写自定义目录标题
1.ROSJava 安装
Debs安装
这里以ROS Kinetic为例,其他版本类比
sudo apt-get install ros-kinetic-rosjava*
sudo apt-get install ros-indigo-genjava
创建工作区
mkdir -p ~/myjava/src
cd ~/myjava/src
source /opt/ros/kinetic/setup.bash
catkin_init_workspace
cd ~/myjava
catkin_make
在非Java工作区中禁用GenJava
为了节省编译时间,您可能希望在其他工作区禁用rosjava消息工件生成。为此,在这些工作区的setup.bash中添加以下一行:
echo "export ROS_LANG_DISABLE=genjava" >> ~/nojava/devel/setup.bash
有关详细信息,请参阅 ROS_LANG_DISABLE
2.在Android中使用ROS
创建Android App项目
首先在Android Studio中创建一个普通的Android App
修改build.gradle文件
项目Sync完成之后,在项目左侧的文件列表内会有两个build.gradle文件。其中一个是Project的,另一个是Module的。
首先修改 Project 的build.gradle文件
把文件中的
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
修改为
buildscript {
apply from: "https://github.com/rosjava/android_core/raw/kinetic/buildscript.gradle"
}
然后在该文件中继续添加
subprojects {
apply plugin: 'ros-android'
afterEvaluate { project ->
android {
// Exclude a few files that are duplicated across our dependencies and
// prevent packaging Android applications.
packagingOptions {
exclude "META-INF/LICENSE.txt"
exclude "META-INF/NOTICE.txt"
}
}
}
}
最后修改 Module 的build.gradle,在dependencies 中添加ros依赖
...
dependencies {
...
// You now now add any rosjava dependencies, like so:
implementation 'org.ros.android_core:android_core_components:0.4.0'
implementation 'org.ros.rosjava_bootstrap:message_generation:[0.3, 0.4)'
implementation 'org.ros.rosjava_messages:std_msgs:0.5.11'
}
...
修改AndroidManifest.xml文件
Manifest merger failed : Attribute application@icon value=(@mipmap/ic_launcher) from AndroidManifest.xml:7:9-43
is also present at [org.ros.android_core:android_10:0.3.3] AndroidManifest.xml:19:9-36 value=(@mipmap/icon).
Suggestion: add 'tools:replace="android:icon"' to <application> element at AndroidManifest.xml:5:5-19:19 to override.
此时需要修改AndroidManifest.xml文件在application项目中做如下修改
<application xmlns:tools="http://schemas.android.com/tools"
tools:replace="android:icon"
为了能够正常使用还需要给app添加网络权限。在AndroidManifest.xml文件中添加
<uses-permission android:name="android.permission.INTERNET"/>
<activity android:name="org.ros.android.MasterChooser" />
<service android:name="org.ros.android.NodeMainExecutorService" >
<intent-filter>
<action android:name="org.ros.android.NodeMainExecutorService" />
</intent-filter>
</service>
最后的AndroidManifest.xml文件如下
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.bwbot.rostest">
<uses-permission android:name="android.permission.INTERNET"/>
<application
xmlns:tools="http://schemas.android.com/tools"
tools:replace="android:icon"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="org.ros.android.MasterChooser" />
<service android:name="org.ros.android.NodeMainExecutorService" >
<intent-filter>
<action android:name="org.ros.android.NodeMainExecutorService" />
</intent-filter>
</service>
</application>
</manifest>
MainActivity.java
package com.charles.rosserver;
import android.os.Bundle;
import org.ros.android.RosActivity;
import org.ros.concurrent.CancellableLoop;
import org.ros.namespace.GraphName;
import org.ros.node.ConnectedNode;
import org.ros.node.Node;
import org.ros.node.NodeConfiguration;
import org.ros.node.NodeMain;
import org.ros.node.NodeMainExecutor;
import org.ros.node.topic.Publisher;
import java.io.IOException;
import std_msgs.String;
public class MainActivity extends RosActivity {
public MainActivity() {
//super("ros_test", "ros_test", URI.create("http://192.168.0.23:11311")); // 这里是ROS_MASTER_URI
super("ros_test", "ros_test");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void init(NodeMainExecutor nodeMainExecutor) {
try {
java.net.Socket socket = new java.net.Socket(getMasterUri().getHost(), getMasterUri().getPort());
//java.net.InetAddress local_network_address = socket.getLocalAddress();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
NodeConfiguration nodeConfiguration = NodeConfiguration.newPublic(getRosHostname());
nodeConfiguration.setMasterUri(getMasterUri());
nodeMainExecutor.execute(new NodeMain() {
@Override
public GraphName getDefaultNodeName() {
return GraphName.of("ros_test");
}
@Override
public void onStart(ConnectedNode connectedNode) {
final Publisher<std_msgs.String> pub = connectedNode.newPublisher("/test", String._TYPE);
connectedNode.executeCancellableLoop(new CancellableLoop() {
@Override
protected void loop() throws InterruptedException {
std_msgs.String msg = pub.newMessage();
msg.setData("hello world");
pub.publish(msg);
Thread.sleep(1000);
}
});
}
@Override
public void onShutdown(Node node) {
}
@Override
public void onShutdownComplete(Node node) {
}
@Override
public void onError(Node node, Throwable throwable) {
}
}, nodeConfiguration);
}
}
参考文章:在Android中使用ROS | 蓝鲸