mechArm 270デジタルツインを実用へ|Unity × ROS 2で次に挑む3つの実験的ステップ
Mac上のROS 2からUnity内のmechArmを動かすことに成功しました。しかし、手動でコマンドを打つのはあくまで疎通確認に過ぎません。今日からは、このデジタルツインをより高度な研究や開発に耐えうる実用的なシミュレーターへ引き上げるための実験を開始します。
※本プロジェクトの目的:実機「mechArm 270 M5」の制御を通じて、AIの判断をいかに物理的な動きへ変換するか。そのロボット制御の仕組みを理解するプロセスを記録・検証するものです。
実験1:Pythonによるシーケンス制御(自動化の第一歩)
これまではターミナルから1行ずつ命令を打ち込んでいましたが、実用化には一連の動作を自動で行うプログラムが不可欠です。
実験内容: 複数のポーズ(座標データ)を配列として持ち、一定時間ごとに次のポーズへ遷移するPythonスクリプトを作成します。
実用化へのメリット:
単純なお辞儀や旋回をルーチン化できる。
将来的なAI(強化学習など)による自動操作の土台となる。
技術の肝: LOG28で作成した
/arm_jointsトピックとJointStateSubscriberをそのまま活用し、送信側を人間からプログラムに置き換えます。
実験2:双方向同期(Unity ➔ ROS 2 の状態フィードバック)
現在はROSからUnityへの一方通行です。しかし、本物のデジタルツインには、シミュレーション空間で起きたことをROS側に知らせる逆方向の通信が必要です。
実験内容: Unity側に関節角度を読み取るPublisherを実装し、Unity内でロボットがどう動いているかをROSのターミナルに表示させます。
実用化へのメリット:
Unity内の仮想センサー(接触センサーなど)の情報をROSで解析できる。
現実のロボットとUnityのロボットが同じ動きをしているか監視するシステムに発展できる。
実験3:リアルタイム・テレオペレーション(直感的な操作)
コマンド入力ではなく、キーボードやゲームパッドを使ってロボットを直感的に操る実験です。
実験内容: ROS 2の標準的な操作パッケージ(teleop)を使用し、Macのキーボード入力でmechArmをラジコンのように操作します。
実用化へのメリット:
複雑な経路をプログラムなしで試しに動かしてみることが容易になる。
遠隔地からVRゴーグルなどを使ってロボットを操作するアバターロボットの基礎技術になる。
実際に「実験1」をやってみる。
これまではターミナルに長いコマンドを打ち込んでいましたが、今回は Python スクリプト robot_dance.py を作成しました。この小さなプログラムには、右にお辞儀をし、左にお辞儀をし、中央に戻るという 3 つのポーズが配列として刻まれています。
トピック名:
/arm_jointsメッセージ型:
sensor_msgs/msg/JointState制御間隔: 2.0秒おきに次のポーズを自動配信
開発の裏側にあった「小さな壁」
スムーズに進んだように見えて、実はプログラムを保存するだけでも数々の学びがありました。
フォーマットの罠: Mac のテキストエディットは標準でリッチテキスト(.rtf)になりますが、これではプログラムは動きません。標準テキストにする という操作の重要性を学びました。
拡張子の厳格さ:
.py.txtという二重拡張子を避け、正確に.pyとして保存することで、Mac が Python ファイルとして認識してくれるようになりました。環境の儀式:
conda activate ros_envとsourceコマンド。この 2 つを唱えることで、初めて Mac と ROS 2 が深いレベルで同期します。
成功の瞬間:デジタルツインが躍動する

ターミナルで python3 robot_dance.py と打ち込んだ瞬間、世界が変わりました。
ターミナルに ダンス開始! の文字が躍り、Unity 画面内の mechArm が、まるで生き物のように滑らかに、左右へとリズムを刻み始めたのです。HUD に表示された青い ROS2 IP: 127.0.0.1 は、もはや単なる接続表示ではなく、デジタルツインの生命維持装置のように見えました。
2倍速設定と6軸フル駆動の衝撃
前回のお辞儀は、主に関節の根元だけを動かす緩やかなものでした。今回のキレキレ版では、制御の密度と複雑さを大幅に強化しています。
スピードの倍増: ポーズ間の待機時間を 2.0秒から1.0秒へ短縮。
全6軸の連動: 関節1〜3だけでなく、先端の関節4〜6にも大きな回転角を指示。
ダイナミックな振付: 天を仰ぐポーズや深いお辞儀など、ロボットアームの可動域をフルに活かした 5 パターンのシーケンスを実装しました。
開発トラブルを乗り越えて:上書き保存の知恵
新バージョンの実行時、No such file or directory というエラーに直面しました。原因は、新しくファイルを作るのではなく、既存の robot_dance.py を上書きして保存していたことによるファイル名の不一致でした。
しかし、これこそが開発のリアルです。「プログラムの中身を書き換えれば、同じ実行コマンドでも動きが劇的に変わる」 という当たり前で、かつ強力な自動制御の仕組みを身をもって体験することができました。
実験結果:シミュレーションが「現実」に肉薄する
コマンドを実行した瞬間、Unity 内の mechArm は文字通りキレキレの動きを見せました。
2倍の速さで送られるデータに対しても、Unity 側の Articulation Body は一切の遅延なく反応。HUD の ROS2 IP: 127.0.0.1 は安定して青く輝き続け、高速通信下でもシステムが破綻しないことが証明されました。
「実験2」をやってみる。
実験1では、Mac(ROS 2)からUnityへ命令を送る一方通行の制御を確立しました。実験2の目的は、Unity内のロボットが自分の現在の関節角度をROS 2側へ報告するフィードバック・ループの構築です。
ロボットに「発信機」を付ける:C#スクリプトの実装
Unity内のロボットが自分の状態を語り始めるためのプログラムを作成しました。
プログラム名:
JointStatePublisher.cs役割: ロボットの各関節(Articulation Body)から現在の角度をリアルタイムで読み取り、ROS 2の標準的なメッセージ形式(
JointState)に変換して送信します。設定: 1秒間に10回(10Hz)の頻度でデータをパブリッシュ(配信)するように設計しました。
デジタルとデータの「配線」:Inspectorでの設定
作成したプログラムを、Unity内の3Dモデルと物理的に紐付けました。
アタッチ:
firefighter(ロボット本体)にスクリプトを追加。紐付け:
Joint Bodies配列を「Size: 6」に設定し、link1からlink6までの関節をドラッグ&ドロップで登録しました。トピック名: 報告用の宛先として、ロボット開発の標準である
/joint_statesを指定しました。
実験結果:Macの画面に流れ始めた「生データ」
Unityを再生し、Macのターミナルでデータを受信した結果、完璧な同期が確認できました。
実行コマンド:
ros2 topic echo /joint_states観測データ: ターミナル上に
link1〜link6の名前と共に、-0.296...といった非常に精緻な関節角度(ラジアン)が次々と表示されました。感動のポイント: 実験1のダンススクリプトを動かすと、ロボットが動くのと完全に連動してターミナルの数値が激しく変化し、デジタルと現実の境界が消える瞬間を体験しました。
実験2の総括:双方向同期がもたらす価値
今回の成功により、単に動かすだけでなく、ロボットが今どうなっているかをMac側で常に監視できるようになりました。
実験3の前に角度データを使ってロボットの動きをリアルタイムでグラフ化するツールを先に作ります。その理由は、実験2でデータの受信に成功した今、そのデータがどれくらい正確で、どれくらい遅延(ラグ)があるのかを視覚的に把握しておくことが、実験3(テレオペレーション)の成功率をグッと高めるからです。
