/ 开发  

RosJava环境搭建

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 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文件中添加


最后的AndroidManifest.xml文件如下

<?xml version=”1.0” encoding=”utf-8”?>






            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>


此时项目已经可以成功编译了。

  1. 写一个简单的消息发布程序
    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通讯成功。