Isaac Sim × Modbus TCP:OnRobot 2FG7グリッパーをTMFlowからリモート制御する
はじめに
「シミュレーションで検証したプログラムをそのまま実機に持っていける」——これがロボット開発における理想です。
本記事では、Modbus TCPプロトコルを使ってISAAC Sim上のOnRobot 2FG7グリッパーをTMFlowから制御するシステムの構築方法を紹介します。実機の2FG7と全く同じModbusレジスタマップを実装しているため、TMFlowで組んだグリッパー制御プログラムをシミュレーション→実機でそのまま使えます。
注意: 本記事のコードは概念実証(PoC)用の簡略版です。実運用では適切なエラーハンドリング・セキュリティ対策・ロギングを追加してください。
システム概要
構成要素
このシステムは以下の3つの主要コンポーネントで構成されています:
-
Modbus TCPサーバー(Isaac Sim内で動作)
- グリッパーコマンドを受信
- シミュレーション内のグリッパーを制御
- ステータス情報を返信
-
Isaac Simシミュレーション環境
- TM5ロボットアーム + 2FG7グリッパーの物理シミュレーション
- リアルタイム物理演算
-
クライアント(TMFlowまたはテストクライアント)
- Modbusコマンドを送信
- グリッパーの開閉制御
アーキテクチャ図
┌─────────────────┐ Modbus TCP ┌─────────────────┐
│ │ (Port 5020) │ │
│ TMFlow │◄──────────────────────────────┤ Modbus Server │
│ (Robot PC) │ │ (Isaac Sim) │
│ │───────────────────────────────►│ │
└─────────────────┘ Commands / Status └────────┬────────┘
│
│ Control
▼
┌─────────────────┐
│ 2FG7 Gripper │
│ Simulation │
└─────────────────┘
Modbusプロトコルについて
Modbusとは
Modbusは産業用機器の通信プロトコルとして広く使用されている標準規格です。シンプルで信頼性が高く、PLCやロボットコントローラーとの統合が容易なため、工場自動化(FA)分野で普及しています。
レジスタマッピング
本システムでは、OnRobot 2FG7の実機仕様に合わせて以下のレジスタマップを実装しています:
出力レジスタ(コマンド用)
| アドレス | 名称 | 説明 | 範囲 |
|---|---|---|---|
| 0 | rGFR | 把持力 | 0-255 (0-100N) |
| 1 | rGWD | グリッパー幅 | 0-1600 (0-160.0mm) |
| 2 | rCTR | 制御コマンド | 16=実行, 0=停止 |
入力レジスタ(ステータス用)
| アドレス | 名称 | 説明 |
|---|---|---|
| 258 | gOBJ | 物体検出状態 |
| 259 | gSTA | ステータス |
| 260 | gGTO | 動作状態 |
| 261-275 | - | その他ステータス情報 |
実装の詳細
Python + pymodbus
サーバー側はPythonで実装し、pymodbusライブラリを使用してModbus TCPサーバーを構築しています。
バージョン注意: 以下のコードはpymodbus v2.x系の記法です。v3.x以降はインポートパスが変更されています(
pymodbus.server.sync→pymodbus.server)。使用中のバージョンに合わせて読み替えてください。
# Modbusサーバーの初期化(簡略化)
from pymodbus.server.sync import StartTcpServer
from pymodbus.datastore import ModbusSequentialDataBlock
# レジスタブロックの作成
output_block = ModbusSequentialDataBlock(1, [0]*3) # コマンド用
input_block = ModbusSequentialDataBlock(259, [0]*18) # ステータス用
# サーバーを起動
StartTcpServer(context=server_context, address=("0.0.0.0", 5020))
Isaac Simとの統合
Isaac SimのArticulation APIを使用して、グリッパーの関節を直接制御します:
# グリッパー幅からジョイント位置への変換
def width_to_joint_position(width_mm):
return (width_mm / 1000.0) / 2.0 # 両側の指を半分ずつ動かす
# ジョイント位置の設定
positions = gripper.get_joint_positions()
positions[left_joint_idx] = target_position
positions[right_joint_idx] = target_position
gripper.set_joint_positions(positions)
マルチスレッド処理
PhysXの制約により、物理演算スレッドと制御スレッドの同期が重要です。本システムでは:
- Modbusサーバー: バックグラウンドスレッド
- 制御ループ: 50Hz(20ms周期)でコマンドをポーリング
- 物理演算: Isaac SimのTimelineが自動管理
# デーモンスレッドで非同期実行
modbus_thread = threading.Thread(target=modbus_server.start, daemon=True)
control_thread = threading.Thread(target=control_loop, daemon=True)
再初期化メカニズム
シミュレーションの停止・再開時に物理ビューが無効化される問題に対処するため、自動再初期化機能を実装:
def _check_physics_ready():
if simulation_playing and physics_view_invalid:
gripper.initialize() # 物理ビューを再作成
return retry_command()
使用方法
1. サーバーの起動
Isaac SimのScript Editorでサーバースクリプトを実行:
Window → Script Editor → Open → fg7_isaac_sim_modbus_control.py → Run
起動成功メッセージ:
✓ Control loop running in background
Server listening on 0.0.0.0:5020
Ready to receive gripper commands!
2. TMFlowからの制御
Modbusデバイスの設定
- Settings → Communication → Modbus
- TCP Clientを追加
- IPアドレスとポート5020を設定
グリッパーコマンド
閉じる:
Set Node (Modbus)
Register Type: Holding Register
Address: 0
Values: [100, 0, 16]
開く (160mm):
Set Node (Modbus)
Register Type: Holding Register
Address: 0
Values: [100, 1600, 16]
カスタム幅 (80mm):
Set Node (Modbus)
Register Type: Holding Register
Address: 0
Values: [100, 800, 16]
3. ピック&プレースの例
TMFlowでの典型的なワークフロー:
[Start]
↓
[PTP] ホーム位置へ移動
↓
[Modbus Write] グリッパーを開く [100, 1600, 16]
↓
[Delay] 1000ms (グリッパーの動作待ち)
↓
[PTP] ピック位置の上へ移動
↓
[Line] ピック位置へ降下
↓
[Modbus Write] グリッパーを閉じる [100, 0, 16]
↓
[Delay] 1000ms (把持待ち)
↓
[Modbus Read] ステータス確認 (Address: 258)
↓
[If] 物体把持成功?
↓
[Line] 持ち上げ
↓
[PTP] プレース位置へ移動
↓
[Modbus Write] グリッパーを開く [100, 1600, 16]
↓
[Delay] 500ms
↓
[PTP] ホーム位置へ戻る
↓
[End]
技術的な課題と解決策
1. PhysXスレッド競合
問題: バックグラウンドスレッドからの物理演算APIの呼び出しが競合を引き起こす
解決策:
- コマンド受信時のみジョイント位置を更新
- 連続的な更新を避ける
- 物理準備状態のチェックとリトライ機構
2. 物理ビューの無効化
問題: シミュレーション再開時にArticulationの物理ビューが無効化される
解決策:
- 物理状態の監視
- 自動再初期化メカニズム
- ペンディングコマンドのキューイング
3. Modbusアドレッシング
問題: pymodbusは1ベースのアドレッシングを使用
解決策:
# Modbusアドレス0 = データブロックインデックス1
output_block = ModbusSequentialDataBlock(1, [0]*3)
# Modbusアドレス258 = データブロックインデックス259
input_block = ModbusSequentialDataBlock(259, [0]*18)
パフォーマンス
- レイテンシ: ~20-50ms(ネットワーク遅延含む)
- 更新レート: 50Hz(制御ループ)
- CPU使用率: 低(デーモンスレッド使用)
- ネットワーク: TCP/IP、イーサネット経由
このアプローチのメリット
実機との互換性
実際のOnRobot 2FG7グリッパーと同じModbusプロトコルを使用するため、シミュレーションでテストしたプログラムをそのまま実機に展開できます。開発→検証→実機投入のサイクルが大幅に短縮されます。
リモート制御
ネットワーク経由で制御できるため、複数のPCから同時にアクセスしたり、物理的に離れた場所からシミュレーションを操作できます。
TMFlowとの統合
TMロボットの標準開発環境であるTMFlowから直接制御でき、追加のツールや学習が不要です。
標準プロトコル
Modbusは産業標準のため、PLC、SCADA、HMIなど多様なシステムとの統合に応用できます。
応用例
- バーチャルコミッショニング: 実機投入前にロボットプログラムを検証し、サイクルタイムや干渉を事前チェック
- オペレータートレーニング: 安全な仮想環境でロボット操作を訓練
- アルゴリズム開発: ビジョンシステムやパスプランニングのアルゴリズムをシミュレーションで高速検証
- デジタルツイン: 実機とシミュレーションを並行稼働させ、動作を比較・検証
システム要件
- OS: Ubuntu 24.04(推奨)
- Python: 3.10以上
- Isaac Sim: 4.x / 5.x
- pymodbus: 2.5.3以上(v3.x の場合はインポートパスを変更)
- ネットワーク: TCP/IP、ポート5020(カスタマイズ可能)
まとめ
Modbus TCPを使ったIsaac Simグリッパー制御システムにより、シミュレーションと実機の間のギャップを効果的に埋められます。TMFlowで組んだプログラムをそのまま実機に持っていける点は、実際の現場で大きなメリットになります。
Isaac Simを使ったロボット検証やPoC構築を業務で検討されている方は、ロボティクスシミュレーションサービスのページもご参考にどうぞ。
