Ich werde die Tutorial-Anwendung für die Pub-Sub-Kommunikation von ROS (Robot Operating System) auf Android erklären. Die Android ROS App wurde mit Rosjava entwickelt, aber ich habe einen Artikel erstellt, da die Informationsmenge auf Japanisch weniger oder älter ist als bei roscpp und rospy.
Grundsätzlich verweise ich auf das ROS.org-Tutorial http://wiki.ros.org/android.
Unter der Annahme, dass ROS Master auf dem ROS-PC ausgeführt wird, überprüfen Sie hier den Vorgang des Abonnierens der veröffentlichten Nachricht auf dem Smartphone auf dem ROS-PC (+ Smartphone selbst).
** Smartphone **
** App-Entwicklungs-PC ** Wird für die Entwicklung von Android-Apps verwendet.
ROS PC Es wird verwendet, um die Pub-Sub-Kommunikation zwischen Terminals zu überprüfen. Sie können den Betrieb nur mit dem Smartphone überprüfen.
Das detaillierte Verfahren für jedes Element wird weggelassen, da es auf anderen Websites eingeführt wird.
** App-Entwicklungs-PC ** Es scheint, dass es zuvor notwendig war, eine ROS-Umgebung auf dem Anwendungsentwicklungs-PC zu erstellen, aber jetzt kann sie nur mit Android Studio entwickelt werden.
Installieren Sie Android Studio
Installieren Sie den Nexus 5X USB-Treiber
Installieren Sie das SDK mit API 15 oder höher
ROS PC
Installieren Sie ROS Kinetic
** Netzwerk ** Verbinden Sie Ihr Smartphone und Ihren ROS-PC mit demselben Netzwerk. In meiner Umgebung lautet die IP-Adresse wie folgt.
Smartphone: 192.168.0.14
** Erstelle eine App mit Neu-> Neues Projekt in Android Studio ** --Wählen Sie API 15 oder höher für "Android-Zielgeräte" in "Telefon und Tablet". -Wählen Sie "Leere Aktivität" für "Aktivität zum Handy hinzufügen".
Sonst ist es standardmäßig in Ordnung
** build.gradle bearbeiten (oberste Ebene) **
build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
// 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"
}
}
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
Hier im Original-Tutorial
Edit the top-level build.gradle file and replace this part:
with this:
Es gibt eine Anweisung (ich habe den Schwerpunkt auf Ersetzen hinzugefügt), aber in meiner Umgebung ist beim Löschen des ersten Buildskripts ein Fehler aufgetreten, sodass ich ihn unverändert gelassen habe.
build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "goodclues.example.myrosapplication"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'org.ros.android_core:android_15:[0.3,0.4)'
}
Die letzte "Implementierung" ist zu Hause "kompilieren", scheint aber jetzt veraltet zu sein. ~~ Ändern wir auch die 15-Anzahl von "android_15" entsprechend der API-Ebene. ~~ (← Bitte weisen Sie in den Kommentaren darauf hin, dass die Anzahl und die API-Ebene nicht miteinander zusammenhängen. Außerdem scheint sich die Beschreibungsmethode jetzt geändert zu haben. Überprüfen Sie daher das Tutorial auf die neuesten Informationen.)
<uses-permission android:name="android.permission.INTERNET" />
Erlaubnis zur Nutzung des Netzwerks.
<activity android:name="org.ros.android.MasterChooser" />
Master Chooser ist eine Aktivität zum Festlegen der URI von ROS Master. Wenn Sie dies beschreiben, wird der Einstellungsbildschirm automatisch angezeigt, wenn die Anwendung gestartet wird. Die Master-URI kann auch fest codiert sein. Informationen dazu finden Sie im Original-Tutorial.
<application xmlns:tools="http://schemas.android.com/tools"
tools:replace="android:icon"
...(Fortsetzung unten)
Ich bin mir nicht sicher warum, aber ohne es bekomme ich einen Fehler. Die endgültige Manifestdatei sieht folgendermaßen aus:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="goodclues.example.myrosapplication">
<uses-permission android:name="android.permission.INTERNET" />
<application xmlns:tools="http://schemas.android.com/tools"
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"
tools:replace="android:icon">
<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" />
</application>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<org.ros.android.view.RosTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:id="@+id/text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
Um ROS zu verwenden, erstellen Sie eine Aktivität, die RosActivity erweitert. Das folgende Beispiel enthält eine Klasse namens Talker, die eine / chatter-Nachricht veröffentlicht, und eine Ansicht, die ein Chatter-Thema namens RosTextView abonniert.
Die Talker-Klasse veröffentlicht intern eine Zahl, die jede Sekunde erhöht wird.
MainActivity.java
/*
* Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package goodclues.example.myrosapplication;
import android.os.Bundle;
import org.ros.android.MessageCallable;
import org.ros.android.RosActivity;
import org.ros.android.view.RosTextView;
import org.ros.node.NodeConfiguration;
import org.ros.node.NodeMainExecutor;
/**
* @author [email protected] (Damon Kohler)
*/
public class MainActivity extends RosActivity {
private RosTextView<std_msgs.String> rosTextView;
private Talker talker;
public MainActivity() {
// The RosActivity constructor configures the notification title and ticker
// messages.
super("Pubsub Tutorial", "Pubsub Tutorial");
}
@SuppressWarnings("unchecked")
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rosTextView = (RosTextView<std_msgs.String>) findViewById(R.id.text);
rosTextView.setTopicName("chatter");
rosTextView.setMessageType(std_msgs.String._TYPE);
rosTextView.setMessageToStringCallable(new MessageCallable<String, std_msgs.String>() {
@Override
public String call(std_msgs.String message) {
return message.getData();
}
});
}
@Override
protected void init(NodeMainExecutor nodeMainExecutor) {
talker = new Talker();
// At this point, the user has already been prompted to either enter the URI
// of a master to use or to start a master locally.
// The user can easily use the selected ROS Hostname in the master chooser
// activity.
NodeConfiguration nodeConfiguration = NodeConfiguration.newPublic(getRosHostname());
nodeConfiguration.setMasterUri(getMasterUri());
nodeMainExecutor.execute(talker, nodeConfiguration);
// The RosTextView is also a NodeMain that must be executed in order to
// start displaying incoming messages.
nodeMainExecutor.execute(rosTextView, nodeConfiguration);
}
}
Ich leihe mir die Probe fast so aus, wie sie ist. Allerdings an der Oberfamilie
import org.ros.rosjava_tutorial_pubsub.Talker;
In meiner Umgebung ist jedoch ein Fehler aufgetreten. Daher habe ich die folgende Quelle kopiert und in meinem Projekt eine Talker-Klasse erstellt. http://docs.ros.org/hydro/api/rosjava_core/html/Talker_8java_source.html
Starten Sie roscore auf dem ROS-PC.
$ roscore
Wenn Sie die App starten, wird der folgende Bildschirm zur Einstellung der ROS Master-Verbindung angezeigt. (Wenn Sie Erweiterte Optionen anzeigen aktivieren, wird eine Schaltfläche zum Festlegen detaillierter Netzwerkeinstellungen und das Smartphone selbst als ROS-Master angezeigt. Ich werde sie hier jedoch weglassen, da dies nicht erforderlich ist.)
Geben Sie den ROS-Master-URI unter "Master-URI" ein. Es ist in Ordnung, wenn Sie die Stelle, an der sich "localhost" befindet, in "192.168.0.15" ändern. Tippen Sie anschließend auf VERBINDEN. Wenn die Verbindung erfolgreich hergestellt wurde, wechselt sie zur Hauptaktivität.
Die Nummer rechts neben Hello world! Ist die Nachricht, die Sie abonnieren (von Ihnen selbst veröffentlicht).
Lassen Sie uns nun prüfen, ob Sie ROS PC abonnieren können. Am Terminal
$ rostopic echo /chatter
data: "Hello world! X"
Recommended Posts