4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ARラジコンをOculusQuest2で操作する

Posted at

以前作成したラジコンでは、OculusGoでカメラ画像表示、Nintendo Switchのプロコンで操作をしていましたが、Oculus Quest 2を手に入れたので、画像表示・操作をOculus Quest 2でできるようにしました。

環境

  • Oculus Quest 2
    • Unity 2019.4.15f1 LTS
    • ROS# 1.6
  • Raspberry Pi 4
    • ROS melodic

実装

今回、以前作成したソースコードに変更を加えました。
全てをこの記事内で説明すると長くなるので、変更部分だけを説明しています。
全体については、元記事をご参照ください。

Oculus Quest 2側の実装

別の記事「Oculus Quest 2でROS Sharpを使う」にまとめました。
この記事内で、ROSから受信したカメラ画像の表示・ROSへのヘッドセットの向き出力・ROSへのコントローラの出力を説明しているので、ご参照ください。ざっくりとは以下になります。

ソースコードはこのGitHubで公開しています。

  • カメラ画像表示
    • ROS#の「ImageReceiver」を使用
    • 受信topic名を「/image_raw/compressed」に設定
  • ヘッドセットの向き出力
    • 「CenterEyeAnchor」のTransformを出力
    • ROS#の「PoseStampedPublisher」を使用
    • 出力topic名を「/oculus/head_set/pose」に設定
  • コントローラ出力
    • 左右のJoyスティックを出力
    • ROS#の「JoyPublisher」を使用
    • 出力topic名を「/oculus/controller」に設定

Rasphberry Piの実装

カメラ表示

Oculus GoにRaspiのカメラ画像を表示する&姿勢を取得する」と変更はありません。
ROSのuvc_cameraパッケージとimage_transportパッケージをそのまま使用しています。

カメラ向き操作

Oculus Goの姿勢を使ってサーボモーターをコントロールする」で作成したcamera_controllerパッケージに変更を加えました。
ヘッドセットの向きの正負が以前と逆になったようなので、正負を逆にする処理を追加しました。

camera_controller.cpp
void publishRPY(const std_msgs::Header &header, const double r, const double p, const double y) {
    car_control_msgs::CameraControl msg;
    msg.header = header;
    msg.roll = r;
    msg.pitch = p;
    msg.yaw = y;
    // 追加ここから
    if (type == HeadSetType::OculusQuest2) {
      msg.roll = -msg.roll;
    }
    // 追加ここまで
    ROS_DEBUG("publish :  seq = [%d], r = %f, p = %f, y = %f", msg.header.seq, msg.roll, msg.pitch, msg.yaw);
    publisher.publish(msg);
}

その他は受信するデバイス種別にOculusQuest2という定義を追加したことと、デバイス種別に応じて受信するtopic名を切り替えるようにしました(差分)。
ソースコードはこちらのGitHubです。

ラジコン操作

Raspberry Pi, Arduinoでタミヤラジコンを制御する」で作成したcar_controllerパッケージに変更を加えました。
ジョイスティックの左右の正負が、Nintendo Switchのプロコンと逆(OculusQuest2は右が正だが、プロコンは左が正)なので、OculusQuest2のときは正負を逆にしました。

car_contlloer.cpp

void joyCallback(const sensor_msgs::Joy& msg) {
  car_control_msgs::RcCarControl control;
  switch (type) {
  case ControllerType::ProCon:
    control.steer = msg.axes[0];
    control.speed = msg.axes[3];
    break;
  case ControllerType::PS3:
    control.steer = msg.axes[0];
    control.speed = msg.axes[4];
    break;
  // 追加ここから
  case ControllerType::OculusQuest2:
    control.steer = -msg.axes[0];
    control.speed = msg.axes[3];
    break;
  // 追加ここまで
  default:
    control.steer = msg.axes[0];
    control.speed = msg.axes[3];
    break;
  }
  ROS_DEBUG("axis 0 = [%.3f], 4 = [%.3f]", control.steer, control.speed);
  publishCarControl(control);
}

その他はカメラ向き操作と同じように、受信するデバイス種別にOculusQuest2という定義を追加したことと、デバイス種別に応じて受信するtopic名を切り替えるようにしました(差分)。
ソースコードはこちらのGitHubです。

ビルド

$ cd {ROS Workspace}
$ catkin_make --pkg camera_contlloer
$ catkin_make --pkg car_contlloer

実行

ROS側は以下のlaunchファイルを作成し、実行しました。

.xml
<launch>
  <include file="$(find rosbridge_server)/launch/rosbridge_websocket.launch" /> 
  <param name="rosbridge_websocket/address" value="192.168.4.8"/>
  <node name="uvc_camera" pkg="uvc_camera" type="uvc_camera_node">
    <param name="width" type="int" value="1280"/>
    <param name="height" type="int" value="720"/>
  </node>
  <node name="camera_controller" pkg="camera_controller" type="camera_controller_node">
    <param name="headset_type" value="OculusQuest2" type="string" />
  </node>
  <node name="car_controller" pkg="car_controller" type="car_controller_node">
    <param name="controller_type" value="OculusQuest2" type="string" />
  </node>
  <node name="arduino_controller" pkg="rosserial_python" type="serial_node.py">
    <param name="port" value="/dev/ttyACM0" />
  </node>
</launch>

参考

記事内でもリンクを貼った、ARラジコンを作成する記事です

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?