ROS (Robot Operating System) 是在2010年发布的开源机器人操作系统。
RosJava 是用 Java实现的 ROS,它提供了一个客户端库用于快速调用 ROS的 Topics, Services 和Parameters,我们可以用它在 Android 上进行 RosJava的开发。
资料分享: Ros官网: http://wiki.ros.org/
RosJava官方文档: http://wiki.ros.org/rosjava
1.ROS环境搭建
ROS Kinetic支持 Xenial (16.04)和 Wily(15.10),其它 Linux 系统需要安装其它的 ROS版本。
下面开始在 Ubuntu 16.0.4上搭建 ROS Kinetic开发环境。
参考资料: http://wiki.ros.org/kinetic
http://wiki.ros.org/kinetic/Installation/Ubuntu
使用下面命令:
~$ sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
2.2 设置keys
~$ sudo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key 0xB01FA116
2.3 安装
~$ sudo apt-get update
~$ sudo apt-get install ros-kinetic-desktop-full
安装功能包:
~$ sudo apt-get install ros-kinetic-slam-gmapping
查找在kinetic中可以使用的功能包:
~$ apt-cache search ros-kinetic
2.4 初始化
~$ sudo rosdep init
~$ rosdep update
2.5 环境配置
~$ echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc
~$ source ~/.bashrc
注意当安装多个ROS发行版,使用kinetic需要用到下面命令:
~$ source /opt/ros/kinetic/setup.bash
2.6 安装rosinstall
~$ sudo apt-get install python-rosinstall
2.7 测试roscore
~$ roscore
安装ROS成功后,在Beginner Tutorials中有一个简单的示例程序.
在Terminal中运行以下命令:
$ roscore
新开一个terminal,运行以下命令,打开小乌龟窗口:
$ rosrun turtlesim turtlesim_node
新开一个terminal,运行以下命令,打开乌龟控制窗口,可使用方向键控制乌龟运动:
$ rosrun turtlesim turtle_teleop_key
选中控制窗口,按方向键,可看到小乌龟窗口中乌龟在运动。
新开一个terminal,运行以下命令,可以看到ROS的图形化界面,展示结点的关系:
$ rosrun rqt_graph rqt_graph
至此,测试完成,ROS成功
2.RosJava环境搭建
在 Ros环境搭建完成后搭建 RosJava 环境。
参考资料: http://wiki.ros.org/rosjava/Tutorials/kinetic/Source%20Installation
https://blog.csdn.net/F_season/article/details/9166133
使用下面命令:
1.安装依赖
$ sudo apt-get install ros-kinetic-catkin ros-kinetic-rospack python-wstool openjdk-8-jdk
2.核心功能
$ mkdir -p ~/rosjava/src
$ wstool init -j4 ~/rosjava/src https://raw.githubusercontent.com/rosjava/rosjava/kinetic/rosjava.rosinstall
$ source /opt/ros/kinetic/setup.bash
$ cd ~/rosjava
$ rosdep update
$ rosdep install –from-paths src -i -y
$ catkin_make
3.配置 .bashrc文件
在.bashrc 文件里设置 Ros的环境变量,不设置的话 ROS和 RosJava Android
间的通讯不能连通。
Linux系统里打开终端,输入命令:
$ gedit ~/.bashrc
在最后一行添加三个 export语句
export ROS_HOSTNAME=192.168.199.141
export ROS_IP=192.168.199.141
export ROS_MASTER_URL=http://192.168.199.141:11311
把IP地址改成自己本机连接网络的IP地址,之后手机和安装Linux的ROS系统需要连接在同一个网络
3.在 Android中使用ROS
在Mac上搭建好 Android开发环境,安装好Android Studio,配置好翻墙网络。
通过给Android App添加上ROS的依赖库,可以在没有ROS环境的Mac上开发ROS客户端。
参考资料:
http://community.bwbot.org/topic/627/%E5%9C%A8android%E4%B8%AD%E4%BD%BF%E7%94%A8ros
1.创建一个 Android App项目
然后点击Finish
等待项目同步完成。一般这里出问题就是网络没有配置好,需要开翻墙软件。
2.修改 build.gradle文件
项目同步完成之后,在项目左侧的文件列表内会有两个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’
Do not place your applica
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:
compile ‘org.ros.android_core:android_10:[0.3,0.4)’
}
…
同时把dependencies 中的 全部implementation修改为compile。注意修改时的大小写。
把文件中的compileSdkVersion版本设置为25
targetSdkVersion也设置为25
把 com.android.support:appcompat-v7:27.1.1也修改成25的版本
最后修改完成的文件如下面所示
apply plugin: ‘com.android.application’
android {
compileSdkVersion 25
defaultConfig {
applicationId “org.bwbot.rostest”
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName “1.0”
testInstrumentationRunner “android.support.test.runner.AndroidJUnitRunner”
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile(‘proguard-android.txt’), ‘proguard-rules.pro’
}
}
}
dependencies {
compile fileTree(dir: ‘libs’, include: [‘*.jar’])
compile ‘com.android.support:appcompat-v7:25.4.0’
compile ‘com.android.support.constraint:constraint-layout:1.1.3’
testCompile ‘junit:junit:4.12’
androidTestCompile ‘com.android.support.test:runner:1.0.2’
androidTestCompile ‘com.android.support.test.espresso:espresso-core:3.0.2’
compile ‘org.ros.android_core:android_10:[0.3,0.4)’
}
3.修改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
此时需要修改AndroidManifest.xml文件在application项目中做如下修改
<application xmlns:tools=”http://schemas.android.com/tools"
tools:replace=”android:icon”
…
为了能够正常使用还需要给app添加网络权限。在AndroidManifest.xml文件中添加
最后的AndroidManifest.xml文件如下
<?xml version=”1.0” encoding=”utf-8”?>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
此时项目已经可以成功编译了。
- 写一个简单的消息发布程序
MainActivity.java内容如下
package org.bwbot.rostest;
import android.support.v7.app.AppCompatActivity;
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.net.URI;
import std_msgs.String;
public class MainActivity extends RosActivity {
protected MainActivity() {
super("ros_test", "ros_test", URI.create("http://192.168.0.23:11311")); // 这里是ROS_MASTER_URI
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void init(NodeMainExecutor nodeMainExecutor) {
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);
}
}
编译后,在手机上运行App,在运行的ROS的主机上打印/test话题。
手机要和Linux机器连接在同一个 Wi-Fi下,Linux上已修改 .bashrc文件,添加本机 IP。
Android程序中已配置ROS_MASTER_URL 地址。
在 Linux 上新开一个 Terminal中运行以下命令:
$ roscore
新开一个terminal,cd 到 rosjava文件夹中,运行命令:
$ ros topic echo /test
可以看到消息已经成功发送出来了。
到这Anroid端和Linux端的ROS通讯成功。