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 | 蓝鲸

posted @ 2019-08-19 00:07  红豆の布丁  阅读(598)  评论(0编辑  收藏  举报