GUI付きのロボットのコントローラ
ROSで動くロボットを作ったときに下記のようなコントローラ作りたくなることがあると思います。
今回はROS2で使えるAndroid用のコントローラアプリをUnityで作る方法を紹介します
これまでのROS+Android
Android端末でROSを動かす
こちらはAndroid端末にターミナルアプリを入れてUbuntuを動かす方法です
UbuntuPCで作業する時と同様にターミナルにコマンドを打ち込んでノードを起動したりrvizを起動したりします
- Android携帯でROSを動かすだって!? (ROS1)
- Android端末でROS1/ROS2を動かす(Rvizもあるよ!) (ROS1/ROS2)
Android端末をROSノード化する
こちらはAndroidアプリを使ったり作ったりしてROSと通信するための方法です
ロボットのコントローラを作るのはこっちのほうが近い
-
ROS TeleopでAndroid-PC間を無線通信してみよう (ROS1)
Playストアで公開されてるROS Teleopを使う -
AndroidでROSアプリ開発 (ROS1)
rcljavaを用いてAndroid Studioでアプリを作成する -
ROS講座124 Unityアプリを整える・androidで使う
RosSharpを用いてUnityでアプリを作成する - Unity Robotics Hubを使用する方法 (ROS1/ROS2)
具体的に挙げられる記事を見つけることができませんでしたがUnityが公式対応したUnity Robotics Hubを用いると自分の環境ではAndroid端末でもROS2と(おそらくROS1でも)通信することができました。
ROS側でROS TCP EndpointというUnity側と通信するためのノードを実行する必要があります。
(Unity Robotics Hub参考記事) Unity Robotics Hubの使い方
ROS2+Unityの選択肢
Android上で動かすことを考えなかったときにros2-for-unityというUnity用のパッケージが存在します。
これは先に紹介したUnity Robotics Hubと比べてUbuntu・Android端末間で余計なデータ変換が入らず高パフォーマンスで通信が可能です。
詳しくは下記の記事で紹介されています。
ros2-for-unityはRobotec.aiによって開発されたUnityとROS2間の通信を行うライブラリです。
ROS2 C#クライアントライブラリをネイティブライブラリとしてUnity Projectに取り込み、DDSのプロトコルで他のROS2アプリケーションと通信します。
OSはWindowsとUbuntuをサポートしています。
無駄な変換が一切挟まっていないため、これより早いプロセス間通信の方法は存在しないと言えます。
ros2-for-unityはかなり整備されていてhumbleでもしっかり動くため、これがそのままAndroid端末でも動けば嬉しいなと思って動くようにしました。
動作確認がhumbleでしかできていませんがリポジトリを以下に公開しました
Releasesからunitypackageをダウンロードできます
ジョイスティックのアプリを作ってTurtlesimを動かす例
-
Unityでプロジェクトを作成する
Input Systemを使用するので導入します
(見づらいのでMain Camera -> Camera -> Clear FlagsをSolid Color
にしました)
-
https://github.com/Kotakku/ros2-for-unity-android-package からunitypackageをimportする
-
ジョイスティックになるImageを追加してOn-Screen Stickを追加する
Source Image
はKnob
にしました
サイズ、Movement Range
、Control Path
は適当に設定してください
今回はControl Path
をLeft Stick[Gamepad]
に設定しました -
スクリプトを書く
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.InputSystem; using ROS2; public class TwistPub : MonoBehaviour { private ROS2UnityComponent ros2Unity; private ROS2Node ros2Node; private IPublisher<geometry_msgs.msg.Twist> twist_pub; // Start is called before the first frame update void Start() { #if UNITY_ANDROID && !UNITY_EDITOR // ROS_DOMAIN_IDを使う場合はこの行で設定する Environment.SetEnvironmentVariable("ROS_DOMAIN_ID", "1"); #endif TryGetComponent(out ros2Unity); } // Update is called once per frame void Update() { if (ros2Unity.Ok()) { if (ros2Node == null) { ros2Node = ros2Unity.CreateNode("ROS2UnityTalkerNode"); twist_pub = ros2Node.CreatePublisher<geometry_msgs.msg.Twist>("/turtle1/cmd_vel"); } geometry_msgs.msg.Twist msg = new geometry_msgs.msg.Twist(); var current = Gamepad.current; var input_vec = current.leftStick.ReadValue(); msg.Linear.X = input_vec.x; msg.Linear.Y = input_vec.y; twist_pub.Publish(msg); } } }
-
ROS2UnityComponent.csと作ったスクリプトを貼り付ける
ここまで来るとUnity editer上で動作確認ができます。
Turtlesimを起動しますros2 run turtlesim turtlesim_node
-
ビルド用の設定をする
PlatformをAndroidに変更します
Player Settings...
からScripting Backend
をIL2CPP
に変更します
これでROS2用のAndroidアプリを作ることができました