ROS 2 連携
ハードウェア・ソフトウェア統合
wuji_hand2_driver を介してデバイスを接続すると、関節およびセンサーの状態の読み取り、RViz でのモデル表示、関節指令とサービスによるデバイス制御が可能になります。
インストール
x86_64 または aarch64 上で、ROS 2 Lyrical をインストールした Ubuntu 26.04(resolute)を使用してください。以下のコマンドでは、ソースの取得、ROS の読み込み、依存関係と Hand 2 の記述パッケージのインストール、ワークスペースのビルドを行います。ビルド時には、ホストのアーキテクチャに対応した Wuji SDK C パッケージがダウンロードされ、検証されます。
# ソースを取得し、ROS 2 を読み込む
git clone https://github.com/wuji-technology/wuji-ros2.git "$HOME/wuji-ros2"
cd "$HOME/wuji-ros2"
source /opt/ros/lyrical/setup.bash
# ビルドツールと依存関係をインストールする
sudo apt-get update
sudo apt-get install -y ros-dev-tools
rosdep update
# Hand 2 の記述パッケージとワークスペースの依存関係をインストールする
scripts/install_hand2_descriptions.sh
rosdep install --from-paths . --ignore-src -r -y
# ワークスペースをビルドする。SDK C パッケージは自動的にダウンロード・検証される
colcon build --cmake-args -DBUILD_TESTING=OFF
# ビルドしたワークスペースを読み込む
source install/setup.bash -
記述パッケージのインストーラーには
/etc/apt/sources.list.d/ros2.sourcesが必要です。存在しない場合は、ROS 2 公式のインストール手順に従って Lyrical のパッケージソースを設定してから、スクリプトを再実行してください。 -
そのコンピューターで rosdep を一度も初期化していない場合は、
rosdep updateの前にsudo rosdep initを一度実行してください。sudoコマンドには管理者権限が必要です。 -
SDK のダウンロードに失敗した場合は、Wuji SDK v2026.10.12 から、ホストのアーキテクチャに合わせて
wuji-sdk-c-2026.10.12-x86_64-linux-gnu.tar.gzまたはwuji-sdk-c-2026.10.12-aarch64-linux-gnu.tar.gzをダウンロードして展開してください。展開したディレクトリにinclude/wuji_sdk.h、lib/libwuji_sdk_c.so、LICENSEが含まれていることを確認します。/path/to/sdkをそのディレクトリの絶対パスに置き換え、デフォルトのビルドコマンドの代わりに、wuji-ros2で次のコマンドを実行してください。colcon build --cmake-args -DBUILD_TESTING=OFF -DWUJI_SDK_ROOT=/path/to/sdk -
WUJI_SDK_ROOTを設定した場合、CMake は SDK のバージョンを検証しません。上記で指定したリリースパッケージを使用してください。
新しいターミナルを開くたびに、ワークスペースに移動し、ROS とビルド済みパッケージを読み込んでください。
cd "$HOME/wuji-ros2"
source /opt/ros/lyrical/setup.bash
source install/setup.bash デバイスの選択
機械的統合でデバイスの取り付けを、電気・ネットワーク統合で電源とネットワークの設定を完了してください。ご使用上の注意に記載の動作要件を満たしていることを確認したうえで、次のコマンドを実行してデバイスをスキャンします。
ros2 run wuji_tools wuji_list 対象デバイスの必須項目である serial_number と hand_side を記録してください。アドレスで接続する場合は、任意項目の endpoint も記録します。
| パラメーター | 用途 |
|---|---|
serial_number | デバイスを選択します。endpoint が設定されている場合は、デバイスの識別情報を検証します |
hand_side | 左手または右手のモデルを選択し、デバイスの左右を検証します |
endpoint | デバイスの IP:port ネットワークアドレスに直接接続します |
モデルと状態の表示
検証の実行
1. ドライバーを起動してモデルを表示する
HAND_SERIAL_NUMBER と HAND_SIDE を、デバイスの選択で記録したシリアル番号と左右の情報に置き換えてください。
ビルドした wuji_bringup パッケージの hand2_view.launch.py を実行し、ドライバー、robot_state_publisher、RViz を起動します。
ros2 launch wuji_bringup hand2_view.launch.py \
serial_number:=HAND_SERIAL_NUMBER hand_side:=HAND_SIDE \
model_revision:=2 namespace:=hand スキャン結果に表示された endpoint で接続する場合は、HAND_ENDPOINT をその IP:port アドレスに置き換え、次のコマンドを使用します。
ros2 launch wuji_bringup hand2_view.launch.py \
serial_number:=HAND_SERIAL_NUMBER hand_side:=HAND_SIDE \
endpoint:=HAND_ENDPOINT model_revision:=2 namespace:=hand ドライバーは、デフォルトでデバイスの接続を最大 10 秒間待機します。起動コマンドに connect_timeout:=20.0 を追加すると、接続待機時間を 20 秒に延長できます。起動引数は起動時にのみ読み込まれます。ブール型の引数は小文字の true / false のみ受け付けます。
この launch ファイルでは serial_number が必須で、auto_enable は false に固定されています。起動時に関節を有効化することはなく、すでに有効化されているハンドを無効化することもありません。launch を停止すると、ドライバーは全関節に対して無効化 API を呼び出します。呼び出しに失敗した場合は警告をログに出力し、そのまま終了処理を続行します。デバイスが実際に停止したことを確認してください。
model_revision:=2 を指定すると wuji_hand2_2_description が選択されます。モデルのルートは、左手では l_mount、右手では r_mount で、RViz はこのルートフレームを使用します。モデルアセットとルートリンクについては、モデルアセットと読み込みを参照してください。マウントからロボットまたはワールドフレームへの変換は、上位のアプリケーション側で提供する必要があります。
2. 状態データを確認する
launch は実行したままにしてください。新しいターミナルを開き、ワークスペースに移動して ROS とビルド済みパッケージを読み込んでから、状態データを確認します。
cd "$HOME/wuji-ros2"
source /opt/ros/lyrical/setup.bash
source install/setup.bash
ros2 run wuji_bringup hand2_status_demo --ros-args -r __ns:=/hand このサンプルは、デフォルトで 10 秒間 joint_states、joint_diagnostics、imu を監視し、フレーム数と平均受信レートを報告します。20 個の位置を含む関節状態を 1 件以上、20 エントリを含む関節診断メッセージを 1 件以上、IMU メッセージを 1 件以上受信すると成功となります。このチェックでは、動作制御やすべてのセンサーの検証は行いません。
デモは、監視期間がすべて終了した後に PASS/FAIL を報告します。30 秒間監視するには、次のコマンドを実行します。
ros2 run wuji_bringup hand2_status_demo --ros-args -r __ns:=/hand -p duration:=30.0 ドライバーは接続されているのに RViz に No tf data と表示される場合、またはステータスのサンプルがデータを受信しない場合は、まず各ターミナル間で名前空間、ROS_DOMAIN_ID、QoS を確認してください。問題が解決しない場合は、別の ROS 2 ミドルウェアを試してください。Cyclone DDS をインストールします。
sudo apt-get install ros-lyrical-rmw-cyclonedds-cpp現在の launch を停止します。手順 1 と 2 で使用する各ターミナルで、次のコマンドを実行します。
export RMW_IMPLEMENTATION=rmw_cyclonedds_cppその後、手順 1 と 2 のコマンドを再実行してください。後から新しいターミナルを開いた場合も、同じ ROS 2 ミドルウェアを設定してください。
状態およびセンサーのトピック
ドライバーは、関節状態、関節診断、IMU データを以下のトピックに配信します。記載のメッセージ型でサブスクライブしてください。トピック名は相対名です。namespace:=hand の場合、joint_states は /hand/joint_states に解決されます。
| トピック | メッセージ型 | 内容 |
|---|---|---|
joint_states | sensor_msgs/msg/JointState | 有効な関節の位置(rad)、速度(rad/s)、電流(A)。effort は電流値であり、トルクの実測値ではありません。関節は name で識別します |
joint_diagnostics | wuji_msgs/msg/JointDiagnosticsArray | オンラインの関節について、SDK の生のステータスワード、フォルトコード、電流、電圧、温度、通信統計を提供します。標準の ROS /diagnostics インターフェースではありません |
imu | sensor_msgs/msg/Imu | 角速度と線形加速度。姿勢推定値は含まれず、orientation_covariance[0] = -1 となります |
フィールドの定義については、wuji-ros2 リポジトリ内の wuji_msgs/msg/JointDiagnosticsArray.msg および wuji_msgs/msg/JointDiagnostics.msg、ならびに ROS 2 の JointState.msg と Imu.msg の定義を参照してください。ワークスペースを読み込んだ後、ros2 interface show wuji_msgs/msg/JointDiagnosticsArray を実行すると、カスタムメッセージとそのネストされたフィールドを確認できます。
デバイスの制御
ドライバーは、制御モードを切り替えることなく、位置、速度、電流代替値の目標値を送信します。動作は、デバイスの現在の制御モードとパラメーターに依存します。
関節指令の送信
1. ドライバーを起動する
1. ドライバーを起動してモデルを表示するで起動した表示用の launch を停止します。無負荷のハンドを固定し、可動部の周囲に人が近づかないようにしてください。同じシリアル番号と左右の指定で制御を開始します。
ros2 launch wuji_bringup hand2.launch.py \
serial_number:=HAND_SERIAL_NUMBER hand_side:=HAND_SIDE \
model_revision:=2 namespace:=hand auto_enable:=true auto_enable:=true を指定すると、起動後に全関節が有効化されます。この時点ではまだ動作目標値は送信されません。
2. 現在の位置を確認する
ドライバーは実行したままにしてください。新しいターミナルを開きます。
ドライバーで Cyclone DDS を使用している場合は、このターミナルでも同じ ROS 2 ミドルウェアを設定してください。
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp次のコマンドを実行して ROS を読み込み、関節位置を読み取ります。
cd "$HOME/wuji-ros2"
source /opt/ros/lyrical/setup.bash
source install/setup.bash
ros2 topic echo /hand/joint_states sensor_msgs/msg/JointState --once --timeout 20 --field position ウェーブデモは、起動直後にゼロの目標値を送信します。実行前に、現在位置からゼロ位置までの経路が安全であることを確認してください。関節がゼロ位置に向かって高速に動く可能性があります。
3. ウェーブデモを実行する
ROS 環境を読み込んだターミナルで、次のコマンドを実行します。
ros2 run wuji_bringup hand2_wave_demo --ros-args -r __ns:=/hand ウェーブデモは、/hand/joint_commands にゼロの目標値を 1 秒間配信した後、100 Hz でウェーブ指令を配信します。親指と外転の目標値は 0 rad のまま維持されます。その他の 4 本の指は、0.5 Hz のコサイン波で 0~1.0 rad の範囲を動きます。ハンドの動きと関節位置の変化を観察してください。
4. 停止して無効化する
Ctrl+C を押してウェーブデモを停止し、全関節を無効化します。
ros2 service call /hand/set_enabled wuji_msgs/srv/SetEnabled \
'{enabled: false, mask: [true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true]}' ドライバーの launch を停止する前に、応答に success: true が含まれていることを確認し、ハンドが停止したことを確認してください。
ドライバーには指令のウォッチドッグ機能がありません。パブリッシャーを停止しても、ゼロ値の送信、非常停止の作動、ハンドの無効化は行われません。launch を停止すると、ドライバーは全関節に対して無効化 API を呼び出します。呼び出しに失敗した場合は警告をログに出力し、そのまま終了処理を続行します。デバイスが実際に停止したことを確認してください。無効化要求が失敗した場合、launch の終了や接続の切断によってハンドが無効化されたとはみなさないでください。
関節指令の形式
sensor_msgs/msg/JointState メッセージを joint_commands に配信します。name、position、velocity、effort の各フィールドはパブリッシャー側で設定します。これらは起動引数ではありません。
名前付き指令:パブリッシャーを作成する際は、joint_states で配信される関節名を name に設定し、position の値を同じ順序で指定します。関節は一部のみを任意の順序で指定できます。指定されていない関節の目標値はドライバーによってゼロで埋められるため、目標値を維持したい関節は明示的に含めてください。
固定順序の指令:name を空にし、position の値 20 個すべてを以下の順序で指定します。上記のウェーブデモはこの形式を使用しています。記載の関節名には、選択したハンドに応じて l_ または r_ の接頭辞を付けてください。固定長のサービスも同じ順序を使用します。
| インデックス | 関節名の本体(順序どおり) |
|---|---|
| 0–3 | thumb_cmc_flex, thumb_cmc_abd, thumb_mcp, thumb_ip |
| 4–7 | index_finger_mcp_flex, index_finger_mcp_abd, index_finger_pip, index_finger_dip |
| 8–11 | middle_finger_mcp_flex, middle_finger_mcp_abd, middle_finger_pip, middle_finger_dip |
| 12–15 | ring_finger_mcp_flex, ring_finger_mcp_abd, ring_finger_pip, ring_finger_dip |
| 16–19 | pinky_mcp_flex, pinky_mcp_abd, pinky_pip, pinky_dip |
いずれの形式でも、空の velocity および effort 配列はゼロで埋められます。空でない配列は、指令対象の関節数と一致している必要があります。不明な名前、重複した名前、反対側の手の名前、不正な長さ、有限でない値、float32 の範囲外の値が含まれている場合は、指令全体が拒否されます。
制御サービスの呼び出し
サービスは信頼性の高い(reliable)QoS と同じ名前空間を使用します。応答の成功フラグとエラー情報の両方を確認してください。
| サービス | 型 | 動作 |
|---|---|---|
set_enabled | wuji_msgs/srv/SetEnabled | 20 エントリのマスクで選択した関節を有効化または無効化します |
clear_faults | wuji_msgs/srv/ClearFaults | 20 エントリのマスクで選択した関節のフォルトをクリアします |
set_effort_limit | wuji_msgs/srv/SetEffortLimit | 全関節に共通の電流制限値を A 単位で 1 つ設定します |
set_effort_limits | wuji_msgs/srv/SetEffortLimits | 20 個の電流制限値を A 単位で固定順序に従って設定します |
set_mit_params | wuji_msgs/srv/SetMitParams | 20 個の kp および kd の値を固定順序に従って設定します |
emergency_stop | std_srvs/srv/Trigger | SDK のハンド全体の非常停止を呼び出します |
すべて false のマスクでは、どの関節も変更されません。固定長のサービスには 20 エントリすべてが必要で、関節名や部分的な配列は受け付けません。電流制限値、kp、kd は有限かつ非負である必要があります。kp と kd は SDK での定義をそのまま保持し、追加の物理単位はありません。
拒否された関節指令は、ドライバーのターミナルにレート制限付きの ERROR ログとして出力され、結果を通知するトピックはありません。失敗したサービス呼び出しは、success: false とエラー情報を返します。ドライバーは動作を継続します。
非常停止を要求するには、次のように呼び出します。
ros2 service call /hand/emergency_stop std_srvs/srv/Trigger '{}' ドライバーは非常停止状態をラッチしません。呼び出し後は、制御側のアプリケーションが関節指令の配信を停止する必要があります。停止しない場合、その後の指令が反映される可能性があります。
ドキュメント