クワマイでもできる

クワマイでもわかる

キーボードでロボット操作 - teleop_twist_keyboard

Image from Gyazo

前回rostopicコマンドで速度指令値をPublishしてロボットを動かした。毎回コマンドを打つのは面倒なので、ゲームみたいにキーボードで動かせるteleop_twist_keyboardを使ってみる。

動作環境

  • Ubuntu16.04
  • ROS Kinetic Kame
  • GAZEBO 7.0.0

今回動かすロボットは、GAZEBOシミュレータ上で動くもの。Twist型のMessageを受け取って動くロボットならなんでも良い。

使用するPackage

今回使用するPackageはteleop_twist_keyboard。キーボードでロボットの移動方向を操作できる。この記事の内容はほぼ下記Wikiの日本語訳みたいなもの。

Packageのインストール

下記コマンドでインストールする。

$ sudo apt-get install ros-kinetic-teleop-twist-keyboard

使い方

起動

下記コマンドでteleop_twist_keyboardを起動する。cmd_vel:=/以下は適宜操作するロボットに合わせて変更すること。

$ rosrun teleop_twist_keyboard teleop_twist_keyboard.py cmd_vel:=/mabot/diff_drive_controller/cmd_vel

操作方法

親切なことに操作方法は起動時に出てくる。

Reading from the keyboard  and Publishing to Twist!
---------------------------
Moving around:
   u    i    o
   j    k    l
   m    ,    .

For Holonomic mode (strafing), hold down the shift key:
---------------------------
   U    I    O
   J    K    L
   M    <    >

t : up (+z)
b : down (-z)

anything else : stop

q/z : increase/decrease max speeds by 10%
w/x : increase/decrease only linear speed by 10%
e/c : increase/decrease only angular speed by 10%

CTRL-C to quit

currently:  speed 0.5   turn 1.0 

いくつかピックアップするとこんな感じ。

  • i: 前進
  • ,: 後進
  • j: 左旋回
  • l: 右旋回
  • q: スピードアップ
  • z: スピードダウン
  • currently: 現在のスピード

これでTwistを直に書くよりも楽に操作することができた。

Image from Gyazo

xacroでロボットを書く[3] - ロボットをGAZEBOに置く

f:id:kuwamai:20190507205934p:plain 前回は動力と摩擦係数の設定をして、走らせる準備をした。

今回は動力へ速度指令を送るControl packageと、GAZEBOシミュレータを起動するGazebo packageを作成する。

動作環境

  • Ubuntu16.04
  • ROS Kinetic Kame
  • GAZEBO 7.0.0

練習の記録

今回やってることはこちらのリポジトリに公開してます。

下記手順はnavigation_practiceディレクトリで行う前提で話を進める。

Control packageの作成

速度指令値を受け取り、ロボットの車輪を制御するPackageを作成する。

$ catkin_create_pkg mabot_control controller_manager actionlib actionlib_msgs control_msgs sensor_msgs robot_state_publisher

今回作成する対向二輪型ロボットは、受け取った速度指令値を左右のタイヤの角速度に変換する必要がある。幸いその計算を勝手にしてくれるControllerがあるのでありがたく使わせていただく。

$ mkdir mabot_control/config
$ vim mabot_control/config/controller.yaml
mabot:
  joint_state_controller:
    type: joint_state_controller/JointStateController
    publish_rate: 50

  diff_drive_controller:
    type        : "diff_drive_controller/DiffDriveController"
    left_wheel  : 'left_wheel_joint'
    right_wheel : 'right_wheel_joint'
    publish_rate: 50               # default: 50
    pose_covariance_diagonal : [0.001, 0.001, 1000000.0, 1000000.0, 1000000.0, 1000.0]
    twist_covariance_diagonal: [0.001, 0.001, 1000000.0, 1000000.0, 1000000.0, 1000.0]
    
    # Wheel separation and diameter. These are both optional.
    # diff_drive_controller will attempt to read either one or both from the
    # URDF if not specified as a parameter
    wheel_separation : 0.34
    wheel_radius : 0.1
    
    # Wheel separation and radius multipliers
    wheel_separation_multiplier: 1.0 # default: 1.0
    wheel_radius_multiplier: 1.0 #default: 1.0

Controllerを起動するlaunchファイルを作成する。

$ mkdir mabot_control/launch
$ vim mabot_control/launch/mabot_control.launch
<?xml version="1.0"?>
<launch>
  <!-- Load joint controller configurations from YAML file to parameter server -->
  <rosparam file="$(find mabot_control)/config/controller.yaml" command="load"/>

  <!-- load the controllers -->
  <node name="controller_spawner" pkg="controller_manager"
    type="spawner" ns="mabot" output="screen" 
    args="joint_state_controller diff_drive_controller" />

  <!-- convert joint states to TF transforms for rviz, etc -->
  <node name="robot_state_publisher" pkg="robot_state_publisher"
    type="robot_state_publisher"
    respawn="false" output="screen" ns="/mabot"/>
</launch>

Gazebo packageの作成

GAZEBO上にWorldを作成し、ロボットを置くPackageを作成する。

$ catkin_create_pkg mabot_gazebo

Worldは様々な種類があるし自分でも作れるが、とりあえず何もないemptyworldを生成してロボットを置くlaunchファイルを作成する。

$ mkdir mabot_gazebo/launch
$ vim mabot_gazebo/launch/mabot_with_emptyworld.launch
<?xml version="1.0"?>
<launch>
  <!-- these are the arguments you can pass this launch file, for example paused:=true -->
  <arg name="model" default="$(find mabot_description)/robots/mabot.urdf.xacro" />
  <arg name="paused" default="false" />
  <arg name="use_sim_time" default="true" />
  <arg name="gui" default="true" />
  <arg name="headless" default="false" />
  <arg name="debug" default="false" />

  <!-- We resume the logic in empty_world.launch, changing only the name of the world to be launched -->
  <include file="$(find gazebo_ros)/launch/empty_world.launch">
    <arg name="debug" value="$(arg debug)" />
    <arg name="gui" value="$(arg gui)" />
    <arg name="paused" value="$(arg paused)" />
    <arg name="use_sim_time" value="$(arg use_sim_time)" />
    <arg name="headless" value="$(arg headless)" />
  </include>

  <!-- Load the URDF into the ROS Parameter Server -->
  <param name="mabot/robot_description" command="$(find xacro)/xacro --inorder '$(arg model)'" />
  
  <!-- Run a python script to the send a service call to gazebo_ros to spawn a URDF robot -->
  <node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen" args="-urdf -model mabot -param mabot/robot_description" />

  <!-- ros_control motoman launch file -->
  <include file="$(find mabot_control)/launch/mabot_control.launch" />
</launch>

GAZEBOの起動

作成したlaunchファイルを実行するとGAZEBOが起動する。

$ roslaunch mabot_gazebo mabot_with_emptyworld.launch

f:id:kuwamai:20190507205934p:plain

動作確認

実際に速度指令値を送ってロボットが動作するか確認する。速度指令値は/mabot/diff_drive_controller/cmd_vel topicにgeometry_msgs/Twist形式でmessageを送る。

下記コマンドを実行するとロボットが前進する。x軸がロボットにとって前後方向になる。ちなみに対向二輪型なので左右方向(y軸)や上下方向(z軸)には進まない。

$ rostopic pub -1 /mabot/diff_drive_controller/cmd_vel geometry_msgs/Twist '{linear:  {x: 1.0, y: 0.0, z: 0.0}, angular: {x: 0.0,y: 0.0,z: 0.0}}'

f:id:kuwamai:20190508010012g:plain

また、このように入力すると旋回する。z軸が左右旋回方向になる。

$ rostopic pub -1 /mabot/diff_drive_controller/cmd_vel geometry_msgs/Twist '{linear:  {x: 0.0, y: 0.0, z: 0.0}, angular: {x: 0.0,y: 0.0,z: 1.0}}'

f:id:kuwamai:20190508005703g:plain

こんな感じで速度指令値をdiff_drive_controllerに送るだけで勝手に左右の車輪をいい感じに動かしてくれる。台車が無事にできたので、センサーを載せたり制御したり色々できるようになった。

はてなブログのコードブロックが改行されるときの設定

f:id:kuwamai:20190501171625p:plain

今使ってるはてなブログのテーマはコードブロックが改行されるのでインデントとかわかりにくい。改行されずにスクロールバーで横スクロールしたい。ちなみに解決前までこんな感じだった↑

対処方法

調べたところこちらの記事が見つかりました。CSSを1行ずつ解説されていて大変わかりやすかったです。

けど、僕のブログだと変わらず改行されてしまった。もう少し頑張って調べたらこちらの記事が見つかりました。デザインCSSの設定で変わらない場合は詳細設定で変えられるらしい。

設定を開いて

f:id:kuwamai:20190501173541p:plain

詳細設定タブ開いて

f:id:kuwamai:20190501173602p:plain

検索エンジン最適化/headに要素を追加の欄に下記CSSを追加。

f:id:kuwamai:20190501173802p:plain

<style>
  pre{
    white-space: pre;
  }

  .entry-content pre{
    word-wrap: normal;
  }
</style>

するとこんな感じでめでたくスクロールできるようになった。

f:id:kuwamai:20190501174150p:plain

ついでにデザインCSSで黒い背景に設定した。色付きの文字は黒い背景の方が見やすい気がする。

.entry-content pre.code {
    background-color: #3F3F3F;
    color: #DCDCDC;
}

ということでこんな感じになった。

  <!--省略-->
  <!-- ===========  Transmission ============ -->
  <xacro:wheel_trans prefix="right" interface="hardware_interface/VelocityJointInterface" />
  <xacro:wheel_trans prefix="left" interface="hardware_interface/VelocityJointInterface" />
</robot>

xacroでロボットを書く[2] - transmissionとgazebo

f:id:kuwamai:20190331203442p:plain 前回は対向二輪型ロボットのモデルをxacroで書いた。

今回はGAZEBOで走らせるために動力と摩擦係数の設定をする。具体的にはTransmission elementでホイールを速度制御できるように設定し、Gazebo elementでロボットの摩擦係数を設定する。

動作環境

  • Ubuntu16.04
  • ROS Kinetic Kame
  • GAZEBO 7.0.0

練習の記録

今回やってることはこちらのリポジトリに公開してます。

下記手順はnavigation_practiceディレクトリで行う前提で話を進める。

Transmission element

ホイールが回転するように動力の設定をwheel.transmission.xacroに記述する。
Transmission elementの記述方法について詳しくはこちら。

$ vim mabot_description/urdf/wheel/wheel.transmission.xacro
<?xml version="1.0"?>
<robot xmlns:xacro="http://ros.org/wiki/xacro">
  <xacro:macro name="wheel_trans" params="prefix interface">
    <transmission name="${prefix}_wheel_trans">
      <type>transmission_interface/SimpleTransmission</type>

      <joint name="${prefix}_wheel_joint">
        <hardwareInterface>${interface}</hardwareInterface>
      </joint>
      
      <actuator name="${prefix}_wheel_motor">
        <hardwareInterface>${interface}</hardwareInterface>
      </actuator>
    </transmission>
  </xacro:macro>
</robot>

wheel.urdf.xacrowheel.transmission.xacroを読み込ませるよう書き加える。

$ vim mabot_description/urdf/wheel/wheel.urdf.xacro
<?xml version="1.0"?>
<robot xmlns:xacro="http://ros.org/wiki/xacro">
  <xacro:include filename="$(find mabot_description)/urdf/wheel/wheel.transmission.xacro" />
<!--省略-->

書いたTransmissionをmabot.urdf.xacroの最後の方に書き加える。
今回はホイールの速度を制御したいのでVelocityJointInterfaceを使った。
他には力制御をするEffortJointInterface、位置制御をするPositionJointInterfaceがある。

$ vim mabot_description/robots/mabot.urdf.xacro
  <!--省略-->
  <!-- ===========  Transmission ============ -->
  <xacro:wheel_trans prefix="right" interface="hardware_interface/VelocityJointInterface" />
  <xacro:wheel_trans prefix="left" interface="hardware_interface/VelocityJointInterface" />
</robot>

Gazebo element

Pluginのインストール

下記のコマンドで必要なPluginをインストールする。

$ sudo apt-get install ros-kinetic-gazebo-ros-control
$ sudo apt-get install ros-kinetic-ros-control ros-kinetic-ros-controllers

Gazebo elementの記述

さっきインストールしたPluginをmabot.urdf.xacroの最後の方に書き加える。

$ vim mabot_description/robots/mabot.urdf.xacro
  <!--省略-->
  <!-- =============== Gazebo =============== -->
  <gazebo>
    <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
      <robotNamespace>mabot</robotNamespace>
    </plugin>
  </gazebo>
</robot>

物体の性質を記述

Gazebo elementでは物体の摩擦係数、硬さ、色とか設定できる。今回はwheelが滑らないように摩擦係数を大きめに、casterはよく滑るように摩擦係数を0にした。摩擦係数はmu1mu2で設定する。
その他の要素は下記リンクに詳しく書いてある。

$ vim mabot_description/urdf/body/body.gazebo.xacro
<?xml version="1.0"?>
<robot xmlns:xacro="http://ros.org/wiki/xacro">
  <xacro:macro name="base_gazebo">
    <gazebo reference="base_link">
      <mu1>0.05</mu1>
      <mu2>0.05</mu2>
    </gazebo>
  </xacro:macro>
</robot>
$ vim mabot_description/urdf/caster/caster.gazebo.xacro
<?xml version="1.0"?>
<robot xmlns:xacro="http://ros.org/wiki/xacro">
  <xacro:macro name="caster_gazebo">
    <gazebo reference="caster_link">
      <mu1>0.0</mu1>
      <mu2>0.0</mu2>
    </gazebo>
  </xacro:macro>
</robot>
$ vim mabot_description/urdf/wheel/wheel.gazebo.xacro
<?xml version="1.0"?>
<robot xmlns:xacro="http://ros.org/wiki/xacro">
  <xacro:macro name="wheel_gazebo" params="prefix">
    <gazebo reference="${prefix}_wheel">
      <mu1>1.0</mu1>
      <mu2>1.0</mu2>
    </gazebo>
  </xacro:macro>
</robot>

各部品にGazebo elementの設定を読み込ませるように書き加える。

$ vim mabot_description/urdf/body/body.urdf.xacro
<?xml version="1.0"?>
<robot xmlns:xacro="http://ros.org/wiki/xacro">
  <xacro:include filename="$(find mabot_description)/urdf/body/body.gazebo.xacro" />
<!--省略-->
$ vim mabot_description/urdf/caster/caster.urdf.xacro
<?xml version="1.0"?>
<robot xmlns:xacro="http://ros.org/wiki/xacro">
  <xacro:include filename="$(find mabot_description)/urdf/caster/caster.gazebo.xacro" />
<!--省略-->
$ vim mabot_description/urdf/wheel/wheel.urdf.xacro
<?xml version="1.0"?>
<robot xmlns:xacro="http://ros.org/wiki/xacro">
  <xacro:include filename="$(find mabot_description)/urdf/wheel/wheel.gazebo.xacro" />
<!--省略-->

mabot.urdf.xacroの最後の方に書き加えることでロボットにGazebo要素が追加される。

$ vim mabot_description/robots/mabot.urdf.xacro
  <!--省略-->
  <xacro:base_gazebo/>
  <xacro:wheel_gazebo prefix="right" />
  <xacro:wheel_gazebo prefix="left" />
  <xacro:caster_gazebo/>
</robot>

これでロボットがシミュレータ上で走るために必要な設定が終わった。今度はシミュレータ上で走らせる。

xacroでロボットを書く[1] - jointとlink

f:id:kuwamai:20190331203442p:plain

GAZEBOでロボットをシミュレーションさせるには、ロボットの形とか質量とか色々定義する必要がある。 以前URDF(Unified Robot Description Format)で三輪車みたいな対向二輪型ロボットを書いたけど、めちゃくちゃ長くて人間が書くものじゃない。 今回マクロを使ってURDFが書けるxacro(XML macro)を使ってみたのでメモ。最後に参考にしたサイトをペタペタ貼ってるので、そっちを見たほうが理解が深まるはず。

動作環境

  • Ubuntu16.04
  • ROS Kinetic Kame
  • GAZEBO 7.0.0

練習の記録

今回やってることはこちらのリポジトリに公開してます。

作業用ディレクトリの作成

役割ごとに複数のパッケージに分けるのが主流らしい。 workspaceにそれらをまとめるディレクトリを作成する。 僕は最終的にナビゲーションをしてみたいので、今回はnavigation_practiceという名前にした。

$ cd ~/catkin_ws/src
$ mkdir navigation_practice
$ cd navigation_practice

Description packageの作成

xacroでロボットを定義するパッケージを作る。 大抵*_descriptionという名前が使われるらしい。 ロボットの名前が全然思いつかないので適当にmabot命名した。 これ見て作業をするなら適宜自分のロボットの名前に読み替えてください。

$ catkin_create_pkg mabot_description

部品を作る

今回作る対向二輪型ロボットは、body、wheel、casterで構成される。xacroは複数に分割して記述できるので、ロボットの部品ごとにファイルを分けて書くことにする。
まずは部品を入れておくディレクトリを作成。

$ mkdir mabot_description/urdf

追記: これからxacroやURDFを書いてはモデルが思ったとおりにできてるか確認することを繰り返すのだけど、VSCodeプラグインを使うと書きながら常に確認しながら書けるのでおすすめ。使い方は下記記事に書いた。

部品の構成

部品はjointlinkによって構成される。

  • joint
    jointlink同士を結合させる要素。いくつか種類があって、単にlink同士を固定するものや回転、スライドさせるものもある。
    詳しくはこちら。
  • link
    部品の見た目や形、質量や慣性モーメントなどを設定する要素。
    詳しくはこちら。

bodyの作成

まずはbodyを作る。 これにタイヤとかセンサーとかくっつける予定。 今回は単純に四角いモデルにしてみた。

$ mkdir mabot_description/urdf/body
$ vim mabot_description/urdf/body/body.urdf.xacro
<?xml version="1.0"?>
<robot xmlns:xacro="http://ros.org/wiki/xacro">
  <xacro:macro name="base" params="parent *joint_origin">
    <joint name="base_joint" type="fixed">
      <xacro:insert_block name="joint_origin"/>
      <parent link="${parent}"/>
      <child link="base_link"/>
    </joint>

    <link name="base_link">
      <visual>
        <geometry>
          <box size="0.400 0.200 0.100"/>
        </geometry>
      </visual>

      <collision>
        <geometry>
          <box size="0.400 0.200 0.100"/>
        </geometry>
      </collision>

      <inertial>
        <origin xyz="0 0 0"/>
        <mass value="0.6"/>
        <inertia ixx="1e-3" ixy="0" ixz="0" iyy="1e-3" iyz="0" izz="1e-3"/>
      </inertial>
    </link>
  </xacro:macro>
</robot>

wheel作成

次にwheelを作成する。今回は円柱で作成した。

$ mkdir mabot_description/urdf/wheel
$ vim mabot_description/urdf/body/wheel.urdf.xacro
<?xml version="1.0"?>
<robot xmlns:xacro="http://ros.org/wiki/xacro">
  <xacro:macro name="wheel" params="prefix parent *joint_origin *joint_axis">
    <joint name="${prefix}_wheel_joint" type="continuous">
      <xacro:insert_block name="joint_origin" />
      <xacro:insert_block name="joint_axis" />
      <parent link="${parent}" />
      <child link="${prefix}_wheel" />
    </joint>
    
    <link name="${prefix}_wheel">
      <visual>
        <geometry>
          <cylinder radius="0.1" length="0.05"/>
        </geometry>
      </visual>
      
      <collision>
        <geometry>
          <cylinder radius="0.1" length="0.05"/>
        </geometry>
      </collision>
      
      <inertial>
        <origin xyz="0.0 0.0 0.0" />
        <mass value="0.500"/>
        <inertia ixx="0.0013541667" ixy="0" ixz="0" iyy="0.0013541667" iyz="0" izz="0.0025"/>
      </inertial>
    </link>
  </xacro:macro>
</robot>

caster作成

次にcasterを作成する。今回は球で作成した。

$ mkdir mabot_description/urdf/caster
$ vim mabot_description/urdf/body/caster.urdf.xacro
<?xml version="1.0"?>
<robot xmlns:xacro="http://ros.org/wiki/xacro">
  <xacro:macro name="caster" params="parent *joint_origin">
    <joint name="$caster_joint" type="fixed">
      <xacro:insert_block name="joint_origin" />
      <parent link="${parent}" />
      <child link="caster_link" />
    </joint>

    <link name="caster_link">
      <visual>
        <geometry>
          <sphere radius="0.05"/>
        </geometry>
      </visual>

      <collision>
        <geometry>
          <sphere radius="0.05"/>
        </geometry>
      </collision>

      <inertial>
        <origin xyz="0.0 0 0.0" />
        <mass value="0.50" />
        <inertia ixx="0.0025" ixy="0.0" iyy="0.0025" ixz="0.0" iyz="0.0" izz="0.0025" />
      </inertial>
    </link>
  </xacro:macro>
</robot>

部品を組み立てる

それぞれ別のxacroファイルに書いた部品を読み込み、配置を決めるxacroファイルを書く。

$ mkdir mabot_description/robots
$ vim mabot_description/robots/mabot.urdf.xacro
<?xml version="1.0"?>
<robot name="mabot" xmlns:xacro="http://ros.org/wiki/xacro">
  <xacro:include filename="$(find mabot_description)/urdf/body/body.urdf.xacro"/>
  <xacro:include filename="$(find mabot_description)/urdf/wheel/wheel.urdf.xacro"/>
  <xacro:include filename="$(find mabot_description)/urdf/caster/caster.urdf.xacro"/>
  <link name="base_footprint"/>

  <xacro:base parent="base_footprint">
    <origin xyz="0 0 0"/>
  </xacro:base>

  <xacro:wheel prefix="right" parent="base_link">
    <origin xyz="0.1 -0.17 0.0" rpy="1.57 0 0" />
    <axis xyz="0 0 -1" />
  </xacro:wheel>
  
  <xacro:wheel prefix="left" parent="base_link">
    <origin xyz="0.1 0.17 0.0" rpy="-1.57 0 0" />
    <axis xyz="0 0 1" />
  </xacro:wheel>

  <xacro:caster parent="base_link">
    <origin xyz="-0.15 0 -0.05"/>
  </xacro:caster>
</robot>

rvizでモデルを確認する

2019/10/06 追記


VSCodeのExtensionsでURDFをプレビューできるものがあったので、あれこれ試すならこれが楽かも。


無事にxacroファイルを作ることができたか確認してみる。 作ったモデルの外観をrvizで表示するlaunchファイルを書く。 ついでにrvizの表示設定を保存するために、configディレクトリも作成しておく。

$ mkdir -p mabot_description/launch/config
$ vim mabot_description/launch/display.launch
<launch>
<!-- arguments -->
<arg name="model" default="$(find mabot_description)/robots/mabot.urdf.xacro"/>
<arg name="gui" default="True" />
<!-- prameters -->
<param name="robot_description" command="$(find xacro)/xacro --inorder $(arg model)"/>
<param name="use_gui" value="$(arg gui)"/>
<!-- nodes -->
<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
<node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
<!-- rviz -->
<node name="rviz" pkg="rviz" type="rviz" args="-d $(find mabot_description)/launch/config/urdf.rviz" required="true" />
</launch>

作成したlaunchファイルを実行する。

$ roslaunch mabot_description display.launch

するとrvizが起動する。作成したロボットのモデルを表示するために、左下のAddボタンを押す。

f:id:kuwamai:20190331202900p:plain

表示する要素を選ぶ。今回はRobotModelを選択する。

f:id:kuwamai:20190331202943p:plain

FixedFrameをbese_footprintにする。

f:id:kuwamai:20190331203023p:plain

無事にロボットが表示されていることを確認する。
これをGAZEBO上で走らせるのはまた今度。

f:id:kuwamai:20190331203109p:plain

続き

動力と摩擦係数を設定して走らせる準備をした。

参考

ZED miniでAR動画を撮影する

f:id:kuwamai:20190307144753p:plain

ステレオカメラのZED miniを使ってAR動画を撮影する手順をメモ。バーチャルな映像とリアルの映像を混ぜつつリアルの寝室にボールをぶちまける映像が撮れた。

ZED miniについて

Stereolabsが販売しているステレオカメラ。HMDに取り付ければStereo pass-through機能で現実世界が立体視できる。
他にも現実世界を3DスキャンするSpatial mapping機能や、映像からカメラ位置姿勢を推定するInside-out tracking機能、深度推定によるOcclusion機能とか色々ある。とりあえず公式動画。

VR機器2台も用いて卓球とはなんとも贅沢である。

できた映像

こんな感じ。

動作環境

  • Windows 10
  • Unity 2017.3.1f
  • ZED SDK 2.5
  • ZEDUnityPlugin v2.5
  • HTC VIVE

追記(2020/5/10)

下記環境でも同様の設定で動きました。微妙にパラメータの名称が記事中のスクショと異なりますが見ればすぐわかる程度の違いでほぼ変わりないです。

  • Unity 2018.4.20f1
  • ZED SDK v3.1.2
  • ZED Plugin v3.1.0

ZED miniの3Dモデル

今回の記事では使わなくてもいいけど、ZED miniを何かしらに取り付けたいときはここに公開されてる3Dモデルが役に立つ。例えばトラッカーやコントローラに固定するマウンタを作ってみたり、ロボットに載せてみたり。なぜかQ&Aコーナーにしか載ってないので少し不便。

作成手順

セットアップ

下記のサイトからZED SDKをインストールする。

Unity向けのPluginは下記のサイトに公開されているのでパッケージをインポート。

HMDを使う際はOculus Rift CV1とHTC VIVEに対応しているのでそれぞれのPluginをAsset storeからインポートしておく。

HMDへのZED miniの取り付け方は下記のサイトで説明されている。付属のガイドに合わせてカメラホルダーを粘着テープで貼り付ける方式。
テープが強力でHMDとカメラホルダーの付け外しがしんどいので、僕は貼り付け前に頑張って剥がして違うテープにした。ZED miniを使わないときもカメラホルダーが邪魔に感じない人は付属のテープで問題ないと思う。

Camera prefabの追加

Asset/ZED/PrefabsZED_Rig_StereoZED_Rig_Monoがある。HMDによる立体視(Stereo pass-through)をする際はStereoの方を、そうでない場合はMonoをHierarchieに追加する。
今回はZED_Rig_Stereoを追加した。もうこれだけで実行するとカメラが起動してカメラ映像が見れるし、Occlusionもされる。親切。

f:id:kuwamai:20190228191408p:plain

  • 公式ドキュメント

カメラ設定

ZED_Rig_StereoZED Managerがアタッチされており、カメラ映像に関する設定がいろいろできる。

f:id:kuwamai:20190228220456p:plain

さらに下にあるOpen Camera Controlをクリックするとウィンドウが開き、ホワイトバランスや彩度等が設定できる。

カメラ位置の設定

ZED miniは単体でもPosition trackingができるけど、OculusやVIVEデバイスとの位置関係は分かっていない。例えばTrackerの位置に3Dオブジェクトを表示させても、ZED miniの映像と3Dオブジェクトの位置がずれてしまう。 そのためControllerやTrackerにZED miniを固定し、どのデバイスに固定したのか設定する必要がある。今回はHMDに取り付ける設定をする。

ZED_Rig_StereoZED Controller Trackerをアタッチし、Device To Trackの項目にHMDを設定する。 また、Latency Compensationによって、映像とデバイス位置の遅延を調整することができる。

f:id:kuwamai:20190228221507p:plain

ZED_Rig_Stereoの子オブジェクトであるCamera_eyesZED Offset Controllerをアタッチする。これでZED miniのPosition trackingとHMDのPosition trackingが一致するようになる。

f:id:kuwamai:20190228222627p:plain

  • 公式ドキュメント

  • 追記(2020/5/10)
    厳密にどのバージョン以降か確認できてませんが、ZED Plugin v3.1.0ではこの方法が使えなかったので上記のドキュメントを見てください。

Controller, Trackerの設定

ControllerやTrackerの位置に合わせたオブジェクトを表示したい場合はカメラと同様、オブジェクトにZED Controller Trackerをアタッチする。

f:id:kuwamai:20190228233551p:plain

  • 公式ドキュメント

Spatial mapping

Spatial mapping機能を用いて現実の床や壁、家具などのオブジェクトとバーチャルなオブジェクトの衝突判定を行うことができる。ZED_Rig_Stereoの子オブジェクトにAssets/ZED/Examples/SpatialMapping/PrefabsZED_Spatial_Mappingを追加する。

f:id:kuwamai:20190228233931p:plain

実行時にZED Spatial Mapping ManagerStart Spatial Mappingボタンを押すことでSpatial mappingが始まり、Stop Spatial Mappingを押してSpatial mappingを終了することができる。

f:id:kuwamai:20190228234350p:plain

  • 公式ドキュメント

ROS#:カメラ映像をSubscribe

UnityとROSを通信させるのに便利なROS#(ros sharp)には、ROSでPublishしたカメラ映像をUnityでSubscribeするスクリプトが用意されている。ROS#v1.2c以前とv1.3ではちょっと使い方が違うのでメモ。

動作環境

  • Unity動作用PC
  • ROS動作用PC
    • Ubuntu16.04
    • ROS Kinetic Kame

ROS#のセットアップ

セットアップ方法は以前書いた。今回はセットアップ済みの状態から始める。

kuwamai.hatenablog.com

カメラ映像のSubscribe

Planeの配置

Hierarchie windowを右クリックして3D Object/Pleneを選択。
このObjectにカメラ映像が表示されるので、お好みのObjectで。

f:id:kuwamai:20181212005224p:plain

Image Subscriber

RosConnectorがアタッチされたGameObjectにAssets/RosSharp/Scripts/RosBridgeClient/RosCommuncation/ImageSubscriber.csをアタッチする。

TopicにSubscribeしたいカメラ映像のTopic名を書いて、Mesh Rendererに先ほど作成したPlaneをドラッグ&ドロップ。Time Stepは…よくわかんないけどTopicが来てから何ms更新しない的なやつかな。 大きいほど映像の更新がゆっくりになります。
なんかコメントが書いてある。

the rate(in ms in between messages) at which to throttle the topics

f:id:kuwamai:20181212005743p:plain

カメラ映像のPublishは以前作成したシミュレーター上のカメラ映像を使ってみる。リンク先のREADMEの通りにコマンドを実行していけば、上記スクショと同じTopic名の映像がPublishされる。
これは例なので、自分で作ったロボットがあれば適宜Topic名を合わせてください。

カメラ映像の確認

UnityとROSの接続はセットアップ編を参照。

kuwamai.hatenablog.com

無事に接続したら、Planeにカメラ映像が表示される。

f:id:kuwamai:20181212012711p:plain

ちなみにシミュレーターの外観はこんな感じ。明るいグレーがシミュレーター上の空、暗いグレーが地面、白いのがロボット本体。

f:id:kuwamai:20180711172137p:plain

参考

ROSのセットアップはこちら。