matlab-model-robot-kinematics について
マニピュレータのモデル構築と順・逆運動学の検証を支援する MATLAB 向けスキルです。ロボット開発者向けに、グリッパー設定や IK 解の確認手順も扱います。
主な機能
- 01モデルの読み込み、インポート、構築
- 02表示・衝突ジオメトリの設定
- 03グリッパーと接触フレームの追加
- 04IK と制約付き GIK の選択
- 05解と関節連続性の検証
活用シーン
- 01MATLAB で特定のマニピュレータをモデル化
- 02把持タスク向けにロボットを設定
- 03エンドエフェクター姿勢と IK 結果を確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ matlab/ matlab-agentic-toolkit --skill matlab-model-robot-kinematicsインストール後、Claude Code で/matlab-model-robot-kinematicsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
manifest.yamlreferences/ee-frame-alignment.mdgik-constraints.mdgripper-models.mdimport-mesh-handling.mdparallel-robot-guidance.md詳細
ロボットのモデリングとキネマティクス
マニピュレータモデルを正しく構築し、すべてのキネマティクス解を検証します。
使用する場面
- MATLAB でロボットモデルが必要なタスク(目標が後続の処理であるアニメーション、ピックアンドプレース、軌道、モーションプランニングの場合も含む)
- ユーザーが特定のマニピュレータ名(UR5e、KUKA iiwa14、Panda、Kinova Gen3 など)を挙げた場合
- ロボットモデルの読み込み、構築、インポート
- マニピュレータのシミュレーション、アニメーション、可視化
- 持ち上げる、手を伸ばす、拾う、置く、つかむことを伴うタスク
- ビジュアルメッシュまたは衝突形状の追加
- マニピュレータへのグリッパーの取り付け
inverseKinematicsとgeneralizedInverseKinematicsの選択- IK/GIK 解の検証(終了フラグ、位置誤差、関節の連続性)
使用しない場面
- 衝突のないモーションプランニング(RRT、CHOMP、パスプランニング)— モーションプランニングのスキルを使用してください
- 軌道生成(
contopptraj、cubicpolytraj、trapveltraj)— 軌道のスキルを使用してください - 閉ループ並列機構(デルタ、Stewart)—
references/parallel-robot-guidance.mdを参照してください - 移動ロボットのナビゲーションや車輪付きプラットフォーム — ここでは扱いません
- 動力学シミュレーション(
inverseDynamics、forwardDynamics)— 別の分野です
ワークフロー
ステップ 1:モデルのソースを決定する
利用可能なソースのうち、最も忠実度の高いものを選択します。
| 優先度 | ソース | 使用する場面 | 理由 |
|---|---|---|---|
| 1 | loadrobot | ロボットがライブラリにある場合 | 衝突メッシュ、慣性、ビジュアルを含みます |
| 2 | importrobot | ユーザーが URDF/Xacro/SDF ファイルを持っている場合 | メッシュ参照を保持します |
| 3 | DH から構築 | DH パラメーターしかない場合 | 手動で追加しない限り、衝突メッシュはありません |
重要: 衝突メッシュのないロボットでは、後続のモーションプランニングで、実際には衝突する経路が「衝突なし」と誤って報告される可能性があります。常にメッシュを含むソースを優先してください。
ユーザーが「ロボットを構築する」と言っていても、既知のロボット(UR5e、KUKA iiwa、Panda など)の名前を挙げている場合は、まず loadrobot を提案してください。
URDF、Simscape、または CAD からインポートした後: 衝突メッシュが存在するか確認してください。Simscape Multibody モデルや多くの URDF/CAD エクスポートには、ビジュアル形状しかなく、衝突メッシュがない場合があります。衝突メッシュがない場合は、ビジュアルから生成する方法を判断するフローチャートがある references/import-mesh-handling.md を参照してください。
ステップ 2:モデルを読み込む、または構築する
常に DataFormat="row" を設定してください。これはプランニングと動力学のワークフローで必須です。
オプション A — loadrobot:
robot = loadrobot("universalUR5e", DataFormat="row");
オプション B — importrobot(URDF/Xacro/SDF):
robot = importrobot("myRobot.urdf", DataFormat="row");
URDF にビジュアル形状しかない(<collision> タグがない)場合は、インポート時に VHACD 衝突分解を追加します。
opts = vhacdOptions("RigidBodyTree");
opts.SourceMesh = "VisualGeometry";
robot = importrobot("myRobot.urdf", DataFormat="row", ...
MeshPath="path/to/meshes", CollisionDecomposition=opts);
オプション C — DH パラメーターから構築:
robot = rigidBodyTree(DataFormat="row");
body = rigidBody("link1");
jnt = rigidBodyJoint("joint1", "revolute");
setFixedTransform(jnt, [a alpha d 0], "dh");
jnt.PositionLimits = [-pi, pi];
body.Joint = jnt;
addVisual(body, "Cylinder", [0.04, 0.3]);
addCollision(body, "Cylinder", [0.05, 0.3]);
addBody(robot, body, "base");
ステップ 3:Z 軸が外向きの tool0 があることを確認する
グリッパーを取り付ける前に、ロボットにはローカル Z 軸がアームの外向き(手首から離れる方向)を向いた tool0 ボディが必ず必要です。ほとんどの loadrobot モデルはすでにこの条件を満たしますが、KUKA iiwa モデルは満たしません。
互換性の一覧表と診断手順の詳細については、references/ee-frame-alignment.md を確認してください。
ロボットに Z 軸が外向きの tool0 がすでにある場合(UR、ABB、Techman、FANUC、Kinova、Yaskawa 全機種):そのままグリッパーの取り付けに進みます。
ロボットに tool0 がない場合、または EE の Z 軸がずれている場合(KUKA iiwa 7/14):補正用の tool0 フレームを追加します。
% KUKA iiwa: iiwa_link_ee Z is perpendicular to arm — fix with Ry(90°)
tool0 = rigidBody("tool0");
tool0Joint = rigidBodyJoint("tool0_joint", "fixed");
R_correction = [0 0 1; 0 1 0; -1 0 0]; % Ry(90°)
setFixedTransform(tool0Joint, rotm2tform(R_correction));
tool0.Joint = tool0Joint;
addBody(robot, tool0, "iiwa_link_ee");
未知のロボット(URDF インポート)の場合: 何かを取り付ける前に、references/ee-frame-alignment.md の診断チェックを実行して、位置合わせを確認してください。
ステップ 4:モデルを設定する
ビジュアルとコリジョンは目的が異なり、どちらも必要です:
| 機能 | 目的 | 使用箇所 |
|---|---|---|
addVisual(body, shape, dims) | 表示上の外観 | 可視化のための show |
addCollision(body, shape, dims) | 計画用ジオメトリ | checkCollision、モーションプランナー |
ビジュアルに色を付けるには、addVisual(body, "Mesh", stlFile, tform, FaceColor=[1 0.8 0]) を使います。
loadrobot で読み込んだロボットには、すでに両方が含まれています。スクラッチから構築する場合は、両方を明示的に追加してください。
グリッパーを取り付ける(操作タスクでは必須):
タスクに物体とのインタラクション(ピッキング、配置、持ち上げ、把持、操作)が含まれる場合、グリッパーが必要です。この手順を省略しないでください。物体との接触を伴わない、純粋な可視化や到達可能性の調査の場合のみ省略できます。
カスタムグリッパーを作成する前に、必ず references/gripper-models.md を読んでください。 利用可能なモデルには、平行ジョーグリッパー(robotiq2F85、開口幅 85mm)と、吸着グリッパー(大型または平面の物体向けの robotiqEPick バリアント)の両方があります。robotiq2F85 だけが選択肢だと決めつけないでください。
references/gripper-models.mdを読む- そのファイルの判断ツリーに従う(互換性を確認 → 物体のサイズを確認 → 把持戦略を選択)
- 提供されているモデルが適合しない場合に限り、カスタムグリッパーを作成する(マニピュレーターとの互換性がなく、かつ物体が吸着に適さない場合)
gripper = loadrobot("robotiq2F85", DataFormat="row");
addSubtree(robot, "tool0", gripper, ReplaceBase=false);
重要:必ず ReplaceBase=false を使用してください。 デフォルト値(true)では、グリッパーのベースリンクが親ボディに統合され、ベースのビジュアルメッシュ(グリッパーのハウジング/カップリング)が気づかないうちに破棄されます。提供されているすべてのグリッパーにはベースビジュアルがあり、このフラグを指定しないと失われます。
グリッパーを取り付けたら、グリッパーの接触点に接触フレームを追加し(固定ジョイントなので DOF は追加されません)、そのフレームに対して IK を解きます。これにより、先端フレームの向きの混乱や、オフセットを手作業で計算する手間を避けられます。グリッパーごとのオフセットと全体的な手順については、references/gripper-models.md を参照してください。
contactFrame = rigidBody("contact_point");
contactJoint = rigidBodyJoint("contact_joint", "fixed");
setFixedTransform(contactJoint, trvec2tform([0, 0, gripperOffset]));
contactFrame.Joint = contactJoint;
addBody(robot, contactFrame, "tool0");
カスタムのエンドエフェクターフレームを追加する(グリッパーを取り付けていない場合、または特定のオフセットが必要な場合):
ee = rigidBody("tool_tip");
eeJoint = rigidBodyJoint("tool_tip_joint", "fixed");
setFixedTransform(eeJoint, trvec2tform([0.1, 0, 0]));
ee.Joint = eeJoint;
addBody(robot, ee, "tool0");
ステップ 5:キネマティクスでモデルを検証する
FK と IK を使ってモデルが正しく構築されていることを確認します。リンク長、ジョイント軸、リミット、エンドエフェクターフレームの配置が正しいかを検証してください。
FK で検証する: 既知のコンフィギュレーションに移動し、エンドエフェクターが期待どおりの位置に到達することを確認します。
q = homeConfiguration(robot);
tform = getTransform(robot, q, "tool0");
fprintf("Home position: [%.3f, %.3f, %.3f] m\n", tform(1:3,4));
ポーズが妥当であることを視覚的に確認します:
figure;
show(robot, q, Frames="off");
axis auto;
title("Home configuration");
IK で検証する: 到達可能だと分かっているターゲットを選び、ソルバーが収束することを確認します。
判断 — IK と GIK のどちらを使うか:
| 用途 | 使用する条件 |
|---|---|
inverseKinematics | 単一の目標ポーズで、追加の制約がない場合 |
generalizedInverseKinematics | 複数の制約がある場合(位置+照準、ジョイントの範囲、向きなど) |
利用可能な GIK 制約タイプについては、references/gik-constraints.md を参照してください。
ik = inverseKinematics(RigidBodyTree=robot);
weights = [0.25 0.25 0.25 1 1 1];
targetPose = trvec2tform([0.4, 0.1, 0.3]) * eul2tform([0 pi 0], "ZYX");
[qSol, solnInfo] = ik("tool0", targetPose, weights, homeConfiguration(robot));
ステップ 6:すべての IK/GIK ソリューションを検証する(必須)
この手順を省略しないでください。 エージェントは検証を省略して、失敗に気づかないままソリューションを提出することがよくあります。
inverseKinematics の後:
if solnInfo.ExitFlag <= 0
warning("IK did not converge. ExitFlag: %d, Status: %s", ...
solnInfo.ExitFlag, solnInfo.Status);
end
tformActual = getTransform(robot, qSol, "tool0");
posError = norm(tformActual(1:3,4)' - targetPose(1:3,4)');
if posError > 1e-3
warning("IK position error %.4f m exceeds threshold.", posError);
end
generalizedInverseKinematics の後:
if solInfo.ExitFlag <= 0
warning("GIK did not converge. ExitFlag: %d, Status: %s", ...
solInfo.ExitFlag, solInfo.Status);
end
for i = 1:numel(solInfo.ConstraintViolations)
cv = solInfo.ConstraintViolations(i);
if cv.Violation > 1e-3
warning("Constraint %d (%s) violated: %.4f", i, cv.Type, cv.Violation);
end
end
連続するウェイポイントの場合 — ジョイントの連続性を確認する:
for i = 2:size(qAll, 1)
maxJump = max(abs(qAll(i,:) - qAll(i-1,:)));
if maxJump > deg2rad(30)
warning("Joint jump of %.1f deg between waypoints %d and %d.", ...
rad2deg(maxJump), i-1, i);
end
end
主な機能
| 機能 | 目的 | ツールボックス | 利用可能なバージョン |
|---|---|---|---|
loadrobot | メッシュ付きの組み込みロボットを読み込みます | Robotics System Toolbox | R2019b |
importrobot | URDF/Xacro/SDF/Simscape からインポートします | Robotics System Toolbox | R2017a |
rigidBodyTree | 空のロボットモデルを作成します | Robotics System Toolbox | R2016b |
setFixedTransform | 関節の変換(DH または同次変換)を設定します | Robotics System Toolbox | R2016b |
addVisual | 表示用のビジュアルジオメトリを追加します | Robotics System Toolbox | R2019a |
addCollision | プランニング用の衝突ジオメトリを追加します | Robotics System Toolbox | R2019b |
addSubtree | サブツリー(グリッパー)をボディに取り付けます | Robotics System Toolbox | R2016b |
getTransform | 指定した構成の順運動学を計算します | Robotics System Toolbox | R2016b |
inverseKinematics | 単一の目標姿勢について逆運動学を解きます | Robotics System Toolbox | R2016b |
generalizedInverseKinematics | 複数の制約を使用して逆運動学を解きます | Robotics System Toolbox | R2017a |
show | ロボットの構成を可視化します | Robotics System Toolbox | R2016b |
パターン
可視化
figure;
show(robot, q, Frames="off");
axis auto;
view(45, 30);
title("Robot at configuration q");
複数の構成を表示する場合は、tiledlayout/nexttile を使用します。
figure;
tiledlayout(1, 3);
for i = 1:3
nexttile;
show(robot, qAll(i,:), Frames="off", PreservePlot=false);
axis auto;
title(sprintf("Waypoint %d", i));
end
初期推定値を使用したIK収束の改善
連続するウェイポイントについてIKを解く場合は、前回の解を初期推定値として使用します。
qPrev = homeConfiguration(robot);
for i = 1:numWaypoints
[qSol, solnInfo] = ik("tool0", targetPoses(:,:,i), weights, qPrev);
% ... validate ...
qPrev = qSol;
end
規約
- 作成時またはインポート時に、必ず
DataFormat="row"を設定します - 関節の制限値はラジアン単位です(度で指定する場合は
deg2radを使用します) - 見やすく可視化するには、
Frames="off"とaxis autoを使用します subplotの代わりにtiledlayout/nexttileを使用します- エンドエフェクターのフレームには、内容が分かる名前を付けます(例:
"tool_tip"、"bucket_tip") inverseKinematicsの重みは[orientation(3) position(3)]です。位置を優先するタスクでは、位置の重みを大きく設定します
よくある間違い
| 間違い | 間違っている理由 | 正しい方法 |
|---|---|---|
loadrobot にロボットがあるのに DH から構築する | 衝突メッシュがないため、計画が失敗しても気づけません | まず loadrobot ライブラリを確認します |
見た目を表現するために addCollision を使う | 衝突形状は簡略化されており、show では描画されません | 表示には addVisual を、計画には addCollision を使います |
| IK の検証を省略する | 解が収束しない場合があります。ExitFlag <= 0 は失敗を意味します | 常に ExitFlag を確認し、FK で位置誤差を検証します |
DataFormat="column" または "struct" を使う | 行ベクトルを想定する計画/軌道関数と互換性がありません | 常に DataFormat="row" を使います |
| マニピュレーションタスクでグリッパーを省略する | オブジェクトとのインタラクション(ピック、リフト、把持)には、モデルへのグリッパーの取り付けが必要です | タスクにオブジェクトとの接触が含まれる場合は、必ずグリッパーを取り付けます |
接触フレームなしで "tool0" または先端ボディを使って IK を解く | "tool0" はフランジ(接触点からオフセットされています)です。先端ボディのフレームは 90° 回転しているため、扱いに注意が必要です | グリッパーのオフセット位置に固定の "contact_point" フレームを追加し、そのフレームを対象に IK を解きます |
| カスタムグリッパーを一から作る | 用意されているモデルは形状が正確で、そのまま取り付けられます | 使用可能なグリッパーについては references/gripper-models.md を確認します |
85 mm を超えるオブジェクトに robotiq2F85 を使う | ジョーが十分に開かず、オブジェクトを把持できません | オブジェクトの寸法とグリッパーの最大開口幅を比較します。大きなオブジェクトにはバキュームを使います |
| 複数の制約が必要なのに IK を使う | inverseKinematics が扱えるのは単一の姿勢目標のみです | 制約オブジェクトとともに generalizedInverseKinematics を使います |
| ウェイポイント列の関節連続性を確認しない | 解の間に大きな跳躍があると、危険な軌道になります | 連続する解を比較し、30 度を超える跳躍にフラグを付けます |
ReplaceBase=false を指定せずに addSubtree を使う | グリッパーのベースのビジュアルメッシュが気づかないうちに破棄され、ハウジングが可視化から消えます | グリッパーを取り付けるときは、必ず ReplaceBase=false を渡します |
| フレームを補正せずに KUKA iiwa にグリッパーを取り付ける | iiwa_link_ee の Z 軸はアームに対して垂直なため、グリッパーが横向きになります | 取り付ける前に Ry(90°) で補正した tool0 を追加します。詳しくは references/ee-frame-alignment.md を参照してください |
すべての loadrobot モデルで tool0 の Z 軸が外向きだと思い込む | 一部のロボット(KUKA iiwa)には tool0 がないか、EE フレームが正しく位置合わせされていません | グリッパーを取り付ける前に references/ee-frame-alignment.md の表を確認するか、診断を実行します |
閉ループのパラレルロボットに rigidBodyTree を使う | 閉じた運動学連鎖を表現できません | references/parallel-robot-guidance.md を参照してください |
Copyright 2026 The MathWorks, Inc.