Robotics
STEP から URDF への変換 (FreeCAD スクリプト)
freecadcmd で STEP を読み、リンク単位で STL を書き出し、軸受位置から関節軸を復元して URDF を書く手順
要点
STEP に拘束情報は無いが、軸受・減速機のパーツ位置から関節軸を復元できる。FreeCAD をヘッドレス (freecadcmd) でスクリプト実行すれば、STEP → リンク別 STL + URDF の変換がローカルで完結する。
手順
- 構造把握: STEP をテキストとして
grep -o "PRODUCT('[^']*'"するとパーツ名一覧が API 無しで得られる - 階層とグローバル座標の取得:
freecadcmdで Python スクリプトを実行
import FreeCAD, Import
doc = FreeCAD.newDocument("r")
Import.insert("robot.stp", "r")
# App::Part コンテナは .Group で子を辿る
# Part::Feature のグローバル配置:
gp = feat.getGlobalPlacement()
sh = feat.Shape.copy()
sh.Placement = gp.multiply(feat.Placement.inverse()).multiply(sh.Placement)- 関節軸の特定: 軸受 (型番名で入っていることが多い) や減速機の
CenterOfGravityを出力し、同軸に並ぶ位置 = 関節。リンク長が丸い数字 (例: 400.0 mm) になれば推定が正しい傍証になる - リンク単位で STL 書き出し:
import Part, MeshPart
comp = Part.makeCompound(shapes) # グローバル座標に変換済みの shape 群
mesh = MeshPart.meshFromShape(Shape=comp, LinearDeflection=0.8, AngularDeflection=0.6)
mesh.write("link_arm1.stl")- URDF 記述。座標の扱いは次節
- 検証:
check_urdf robot.urdf
URDF の座標処理
メッシュを CAD グローバル座標のまま書き出した場合:
- リンク frame の原点を関節ピボット位置 (グローバル) に置く
- joint の
<origin>= (親 frame からの差分) - visual/collision の
<origin>= (メッシュをリンク frame に引き戻す) - 全 joint の回転をゼロにすれば、ゼロ姿勢 = CAD の姿勢になる
- mm の STL は
<mesh scale="0.001 0.001 0.001"/>で m に変換 - CAD が Y-up の場合、root に fixed joint
rpy="1.5708 0 0"を挟んで Z-up に立てる
制約
- 閉ループは表現できない: 平行リンク機構 (パレタイジングロボット等) は URDF の木構造に入らない。平行なバーは同角度で回る性質を使い、平行先のアームに fixed で付けるとゼロ姿勢では正しく、関節を動かすと位置が数十 mm ずれる (回転中心が違うため)。正確に扱うなら SDF や MuJoCo の equality constraint を使う
- 慣性はメッシュ体積 × 仮定密度 + bounding box 近似で概算。真面目なシミュレーションでは CAD 側の質量特性から取り直す
- 軸受が STEP に含まれていない (簡略化済み) モデルでは関節軸の復元根拠が減る
他手法との比較
- Assembly と mate を作り直せる状況なら Onshape 経由 や Fusion 360 経由 の方が再現性がある
- この方法は「STEP しか手元に無い」「変換ツールに上げたくない」「1 回きり」の場合に速い。ジョイント再定義を GUI でやらずに済む
関連
- Onshape から URDF への変換
- CAD から URDF への変換 (Fusion 360 / Inventor)
- URDF の visual メッシュを Inventor の DAE で差し替える
最終更新: