1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

干渉判定用ライブラリ python-fcl の使用方法

Last updated at Posted at 2025-06-13

はじめに

私がロボットに関して興味を持っており,ロボットの経路を作成したいと思っている.
経路生成を実施するためには,干渉判定の処理が必要である.自作で干渉判定の処理を作成したが,処理時間が長いためライブラリを使用しようと考えた.
Pythonにて経路生成を実装しているため,Python用の干渉判定ライブラリを調査したところ python-fcl が候補となった.
本記事では,python-fcl の使用方法を説明する.
python-fcl は下記の GitHub に保存されている.
https://github.com/BerkeleyAutomation/python-fcl

本記事で実装すること

・python-fcl の使用方法を説明する

本記事では実装できないこと(将来実装したい内容)

・経路生成(RRTなど)に python-fcl を組み込む
・ロボットを python-fcl で定義する

動作環境

・macOS Sequoia (バージョン15.5)
・Python3 (3.10.9)
・Numpy (1.23.5) (数値計算用ライブラリ)
・python-fcl (4.1.2) (干渉判定用ライブラリ)

python-fcl の使用方法

python-fcl の使用方法を説明する.

python-fcl のインストール方法

python-fcl のインストール方法は下記の通りである.
私は下記を実施したら,python-fcl が動いた.(以前にxcodeよりC++をインストールしていたから,簡単に動いたかもしれない)

pip install python-fcl

python-fcl で使用可能な干渉物

python-fcl で使用可能な干渉物を下表にまとめた.

No 名称
1 直方体
2
3 カプセル(円柱+半球)
4 円錐
5 円柱
6 平面
7 半空間(無限の平面)
8 凸多面体
9 三角形
10 メッシュ
11 楕円体

干渉物の回転を定義

fcl で干渉物を定義するが,干渉物の回転も与えることができる.
そのため,干渉物の回転を先に関数化することによって,後ほど干渉物に回転を与えれるようにする.

test_fcl.py
import numpy as np
import fcl

def rotation_z(theta):
    """
    z軸へtheta回転させた時の回転行列を返す

    パラメータ
        theta(float): 回転角度 [rad]
    
    戻り値
        rotation(numpy.ndarray): 回転行列
    """
    rotation = np.array([[np.cos(theta), -np.sin(theta), 0],
                         [np.sin(theta),  np.cos(theta), 0],
                         [0,              0,             1]])

    return rotation

def rotation_y(theta):
    """
    y軸へtheta回転させた時の回転行列を返す

    パラメータ
        theta(float): 回転角度 [rad]
    
    戻り値
        rotation(numpy.ndarray): 回転行列
    """
    rotation = np.array([[ np.cos(theta), 0, np.sin(theta)],
                         [ 0,             1, 0            ],
                         [-np.sin(theta), 0, np.cos(theta)]])

    return rotation

def rotation_x(theta):
    """
    x軸へtheta回転させた時の回転行列を返す

    パラメータ
        theta(float): 回転角度 [rad]
    
    戻り値
        rotation(numpy.ndarray): 回転行列
    """
    rotation = np.array([[1, 0,              0            ],
                         [0, np.cos(theta), -np.sin(theta)],
                         [0, np.sin(theta),  np.cos(theta)]])

    return rotation

直方体 (Box) の定義方法

fcl で直方体を定義する方法を説明する.
fcl.Box() で直方体の各辺の長さを与える.
fcl.Transform() で干渉物の回転行列と平行移動を与える.
fcl.CollisionObject() で干渉物オブジェクトを作成する.

test_fcl.py
# x軸に1,y軸に2,z軸に3の長さを持つ直方体
box1 = fcl.Box(1, 2, 3)
# 直方体の基準点を(0, 0, 0),回転行列を無回転で定義 (今回は原点かつ無回転)
tra1 = fcl.Transform()
# 干渉判定用のオブジェクト作成 (今回は無回転の直方体)
col1 = fcl.CollisionObject(box1, tra1)

# 1辺が2の長さを持つ立方体
box2 = fcl.Box(2, 2, 2)
# 立方体の基準点を(0, 0, 5),回転行列を無回転で定義
tra2 = fcl.Transform(np.array([0, 0, 5]))
# 干渉判定用のオブジェクト作詞
col2 = fcl.CollisionObject(box2, tra2)

# x軸に3.1,y軸に2.4,z軸に1.1の長さを持つ直方体
box3 = fcl.Box(3.1, 2.4, 1.1)
# z軸に90度回転させた回転行列
rotation = rotation_z(np.deg2rad(90))
# 直方体の基準点を(3.2, 3.5, 3.1),回転行列をz軸に90度回転で定義
# fcl.Transform には,回転行列, 平行移動したい位置の順番に引数を与える必要がある
tra3 = fcl.Transform(rotation, np.array([3.2, 3.5, 3.1]))
# 干渉判定用のオブジェクト作詞
col3 = fcl.CollisionObject(box3, tra3)

球 (Sphere) の定義方法

fcl で球を定義する方法を説明する.
fcl.Sphere() で球の半径を与える.

test_fcl.py
# 半径1の球
sph1 = fcl.Sphere(1)
# 球の基準点を(1, 1, 0),回転行列を無回転で定義
tra1 = fcl.Transform(np.array([1, 1, 0]))
# 干渉判定用のオブジェクト作成 (今回は無回転の直方体)
col1 = fcl.CollisionObject(sph1, tra1)

# 半径2の球
sph2 = fcl.Sphere(2)
# z軸に180度回転させた回転行列
rotation = rotation_z(np.deg2rad(180))
# 球の基準点を(3.1, 3.3, 3.0),回転行列をz軸に180度回転で定義
# fcl.Transform には,回転行列, 平行移動したい位置の順番に引数を与える必要がある
tra2 = fcl.Transform(rotation, np.array([3.1, 3.3, 3.0]))
# 干渉判定用のオブジェクト作詞
col2 = fcl.CollisionObject(sph2, tra2)

カプセル (Capsule) の定義方法

fcl でカプセルを定義する方法を説明する.
fcl.Capsule() でカプセルの半球の半径,円柱の高さを与える.

test_fcl.py
# 円柱部分の高さが2,半径1の半球
cap1 = fcl.Capsule(1, 2)
# カプセルの基準点を(10, 3, 0),回転行列を無回転で定義
tra1 = fcl.Transform(np.array([10, 3, 0]))
# 干渉判定用のオブジェクト作成 (今回は無回転の直方体)
col1 = fcl.CollisionObject(cap1, tra1)

# 円柱部分の高さが20.4,半径5.2の半球
cap2 = fcl.Capsule(5.2, 20.4)
# x軸に90度回転させた回転行列
rotation = rotation_x(np.deg2rad(90))
# カプセルの基準点を(1.5, 2.2, 3),回転行列をx軸に90度回転で定義
# fcl.Transform には,回転行列, 平行移動したい位置の順番に引数を与える必要がある
tra2 = fcl.Transform(rotation, np.array([1.5, 2.2, 3]))
# 干渉判定用のオブジェクト作詞
col2 = fcl.CollisionObject(cap2, tra2)

円錐 (Cone) の定義方法

fcl で円錐を定義する方法を説明する.
fcl.Cone() で円錐の底面の半径,高さを与える.

test_fcl.py
# 底面の半径2,高さ1の円錐
con1 = fcl.Cone(2, 1)
# 円錐の基準点を(1, 0, 5),回転行列を無回転で定義
tra1 = fcl.Transform(np.array([1, 0, 5]))
# 干渉判定用のオブジェクト作成 (今回は無回転の直方体)
col1 = fcl.CollisionObject(con1, tra1)

# 底面の半径1.2, 高さ5.7の円錐
con2 = fcl.Cone(1.2, 5.7)
# y軸に45度回転させた回転行列
rotation = rotation_y(np.deg2rad(45))
# 円錐の基準点を(1, 5.2, 9.9),回転行列をx軸に90度回転で定義
# fcl.Transform には,回転行列, 平行移動したい位置の順番に引数を与える必要がある
tra2 = fcl.Transform(rotation, np.array([1, 5.2, 9.9]))
# 干渉判定用のオブジェクト作詞
col2 = fcl.CollisionObject(con2, tra2)

円柱 (Cylinder) の定義方法

fcl で円柱を定義する方法を説明する.
fcl.Cylinder() で円柱の半径,高さを与える.

test_fcl.py
# 半径100,高さ1の円柱
cyl1 = fcl.Cylinder(100, 1)
# 円柱の基準点を(0, 0, 0),回転行列を無回転で定義
tra1 = fcl.Transform()
# 干渉判定用のオブジェクト作成 (今回は無回転の直方体)
col1 = fcl.CollisionObject(cyl1, tra1)

# 底面の半径1.55, 高さ80.99の円錐
cyl2 = fcl.Cylinder(1.55, 80.99)
# z軸に45度回転させ,y軸に30度回転させた回転行列
rotation = np.dot( rotation_y(np.deg2rad(30)), rotation_z(np.deg2rad(45)) )
# 円柱の基準点を(0, 10.1, 3.9),回転行列をx軸に90度回転で定義
# fcl.Transform には,回転行列, 平行移動したい位置の順番に引数を与える必要がある
tra2 = fcl.Transform(rotation, np.array([0, 10.1, 3.9]))
# 干渉判定用のオブジェクト作詞
col2 = fcl.CollisionObject(cyl2, tra2)

平面 (Plane) の定義方法

fcl で平面を定義する方法を説明する.
fcl.Plane() で平面のパラメータを与える.

test_fcl.py
# ax + by + cz + d = 0 という平面を表す
# z = 0の平面 (0 * x + 0 * y + 1 * z + 0 = 0よりz = 0の平面となる)
# Planeのパラメータは小数点でないとエラーが発生する
pln1 = fcl.Plane(np.array([0.0, 0.0, 1.0]), 0.0)
# 平面の基準点を(0, 0, 0),回転行列を無回転で定義
tra1 = fcl.Transform()
# 干渉判定用のオブジェクト作成 (今回は無回転の直方体)
col1 = fcl.CollisionObject(pln1, tra1)

# ax + by + cz + d = 0 という平面を表す
# z = 0の平面 (1 * x + 0 * y + 0 * z - 5 = 0よりx = 5の平面となる)
# Planeのパラメータは小数点でないとエラーが発生する
pln2 = fcl.Plane(np.array([1.0, 0.0, 0.0]), -5.0)
# 平面の基準点を(0, 0, 0),回転行列を無回転で定義
tra2 = fcl.Transform()
# 干渉判定用のオブジェクト作詞
col2 = fcl.CollisionObject(pln2, tra2)

半空間 (HalfSpace) の定義方法

fcl で平面を定義する方法を説明する.
fcl.Halfspace() で半空間のパラメータを与える.

test_fcl.py
# ax + by + cz + d <= 0 という半空間を表す
# z <= 0の半空間 (0 * x + 0 * y + 1 * z + 0 = 0よりz <= 0の半空間となる)
# Halfspaceのパラメータは小数点でないとエラーが発生する
hsp1 = fcl.Halfspace(np.array([0.0, 0.0, 1.0]), 0.0)
# 半空間の基準点を(0, 0, 0),回転行列を無回転で定義
tra1 = fcl.Transform()
# 干渉判定用のオブジェクト作成 (今回は無回転の直方体)
col1 = fcl.CollisionObject(hsp1, tra1)

# ax + by + cz + d <= 0 という平面を表す
# y <= -1の半空間 (0 * x + 1 * y + 0 * z + 1 = 0よりy <= -1の半空間となる)
# Halfspaceのパラメータは小数点でないとエラーが発生する
hsp2 = fcl.Halfspace(np.array([1.0, 0.0, 0.0]), -5.0)
# 半空間の基準点を(0, 0, 0),回転行列を無回転で定義
tra2 = fcl.Transform()
# 干渉判定用のオブジェクト作詞
col2 = fcl.CollisionObject(hsp2, tra2)

凸多面体 (Convex) の定義方法

fcl で凸多面体 (どの2点を選んでも、その間を結ぶ線分が必ず立体内部に収まる.立方体は凸多面体である.星形の多面体は凸多面体ではない.) を定義する方法を説明する.
fcl.Convex() で凸多面体のパラメータを与える.

test_fcl.py
# 凸多面体を構成する頂点群を定義
verts = np.array([[1.0, 1.0, 1.0],
                  [2.0, 1.0, 1.0],
                  [1.0, 2.0, 1.0],
                  [1.0, 1.0, 2.0]], dtype=np.float64)

tris = np.array([[0, 2, 1],
                 [0, 3, 2],
                 [0, 1, 3],
                 [1, 2, 3]], dtype=np.int64)

faces = np.concatenate((3 * np.ones((len(tris), 1), dtype=np.int64), tris), axis=1).flatten()

convex = fcl.Convex(verts, len(tris), faces)
# verts: (N, 3) のfloat64配列
# len(tris): 三角形面の数 (int)
# faces: (num_faces * 4)のint64配列で,各面の頂点数(3) + 頂点インデックス3つを連結したもの
# 半空間の基準点を(0, 0, 0),回転行列を無回転で定義
tra1 = fcl.Transform()
# 干渉判定用のオブジェクト作成 (今回は無回転の直方体)
col1 = fcl.CollisionObject(convex, tra1)

三角形 (TriangleP) の定義方法

fcl で三角形を定義する方法を説明する.
fcl.TriangleP() で三角形のパラメータを与える.

test_fcl.py
# 三角形の頂点を定義
vert1  = np.array([1.0, 2.0, 3.0])
vert2  = np.array([2.0, 1.0, 3.0])
vert3  = np.array([3.0, 2.0, 1.0])
# TrianglePオブジェクトの生成
tri1 = fcl.TriangleP(vert1, vert2, vert3)
# 三角形の基準点を(0, 0, 0),回転行列を無回転で定義
tra1 = fcl.Transform()
# 干渉判定用のオブジェクト作成 (今回は無回転の直方体)
col1 = fcl.CollisionObject(tri1, tra1)

# TrianglePオブジェクトの生成
tri2 = fcl.TriangleP(vert1, vert2, vert3)
# z軸に90度回転させ,y軸に60度回転させた回転行列
rotation = np.dot( rotation_y(np.deg2rad(60)), rotation_z(np.deg2rad(90)) )
# 三角形の基準点を(1.3, 1.1, 5.9)
tra2 = fcl.Transform(rotation, np.array([1.3, 1.1, 5.9]))
# 干渉判定用のオブジェクト作成 (今回は無回転の直方体)
col2 = fcl.CollisionObject(tri2, tra2)

メッシュ (Mesh) の定義方法

fcl でメッシュを定義する方法を説明する.
fcl.BVHModel() でメッシュのパラメータを与える.

test_fcl.py
# 三角形ポリゴンの定義
# 頂点座標(N x 3 配列)
vertices = np.array([
    [0.0, 0.0, 0.0],  # 頂点0
    [1.0, 0.0, 0.0],  # 頂点1
    [0.5, 1.0, 0.0],  # 頂点2
    [0.5, 0.5, 1.0]   # 頂点3
], dtype=np.float64)

# 三角形インデックス(M x 3 配列)
triangles = np.array([
    [0, 1, 2],  # 三角形0
    [0, 1, 3],  # 三角形1
    [1, 2, 3],  # 三角形2
    [2, 0, 3]   # 三角形3
], dtype=np.int32)

# BVHモデルの作成
mesh = fcl.BVHModel()
# モデル構築開始(頂点数・三角形数を指定)
mesh.beginModel(len(vertices), len(triangles))
# 頂点・三角形をモデルに追加
mesh.addSubModel(vertices, triangles)
# モデル構築終了(BVH構築も同時に行われる)
mesh.endModel()
# 三角形の基準点を(0, 0, 0),回転行列を無回転で定義
tra1 = fcl.Transform()
# 干渉判定用のオブジェクト作成 (今回は無回転のメッシュ)
col1 = fcl.CollisionObject(mesh, tra1)

楕円体 (Ellipsoid) の定義方法

fcl で楕円体を定義する方法を説明する.
fcl.Ellipsoid() で楕円体のパラメータを与える.

test_fcl.py
# x軸に3,y軸に1,z軸に5の長さを持つ楕円体
elp1 = fcl.Ellipsoid(3, 1, 5)
# 楕円体の基準点を(0, 0, 0),回転行列を無回転で定義
tra1 = fcl.Transform()
# 干渉判定用のオブジェクト作成 (今回は無回転の直方体)
col1 = fcl.CollisionObject(elp1, tra1)

# x軸に1.5,y軸に0.4,z軸に9.5の長さを持つ楕円体
elp2 = fcl.Ellipsoid(1.5, 0.4, 9.5)
# z軸に180度回転させ,y軸に45度回転させた回転行列
rotation = np.dot( rotation_y(np.deg2rad(45)), rotation_z(np.deg2rad(180)) )
# 楕円体の基準点を(0.5, 4.2, 2.5)平行移動
tra2 = fcl.Transform(rotation, np.array([0.5, 4.2, 2.5]))
# 干渉判定用のオブジェクト作詞
col2 = fcl.CollisionObject(elp2, tra2)

python-fcl による干渉判定処理

上記にて,干渉物の定義方法を説明した.
次は定義した干渉物を使用した,下記の処理方法を説明する.
・干渉判定 (Collision Detection)
・最短距離計算 (Distance Computation)
・連続干渉判定 (Continuous Collision Detection)

干渉判定 (Collision Detection)

python-fcl にて,干渉判定の処理方法を説明する.
今回は球と立方体の干渉判定を実施してみた.

test_fcl.py
# 半径0.5の球
sph = fcl.Sphere(0.5)
# 干渉物の基準点は原点,回転は無回転とする
sph_tf = fcl.Transform()
sphere_obj = fcl.CollisionObject(sph, sph_tf)

# 衝突リクエストと結果オブジェクト
# num_max_contacts ... 最大の衝突点数
# enable_contact ... 衝突点情報の有無
request = fcl.CollisionRequest(num_max_contacts=10, enable_contact=True)

# 判定実行
for i in range(10):
    # 1辺が1の立方体
    box = fcl.Box(i, i, i)
    box_tf = fcl.Transform(np.array([i, 0.0, 0.0]))
    box_obj = fcl.CollisionObject(box, box_tf)

    # 結果オブジェクトのインスタンスを生成
    # 結果オブジェクトを使い回すと,前回の情報が残ったままとなっているから,毎回インスタンスを生成する
    result = fcl.CollisionResult()
    ret = fcl.collide(sphere_obj, box_obj, request, result)
    print(f"ret = {ret}")
    print(f"result.is_collision = {result.is_collision}")
    if result.is_collision:
        print("衝突点の数:", len(result.contacts))
        for i, contact in enumerate(result.contacts):
            print(f"--- 衝突点 {i+1} ---")
            print("位置:", contact.pos)                 # 衝突点の座標
            print("法線:", contact.normal)              # 接触面の法線ベクトル
            print("距離:", contact.penetration_depth)   # めり込み量(負の距離)

結果は以下となり,想定通りの結果となった.
スクリーンショット 2025-06-13 17.17.26.png

最短距離計算 (Distance Computation)

python-fcl にて,最短距離計算の処理方法を説明する.
今回は球と立方体の最短距離計算を実施してみた.

test_fcl.py
# 円柱の半径を0.5,高さを2.0
cyl = fcl.Cylinder(0.5, 2.0)
# 円柱の基準点(中点)は原点、回転を無回転とする
cyl_tf = fcl.Transform()
# 干渉物オブジェクトの作成
cyl_obj = fcl.CollisionObject(cyl, cyl_tf)

# カプセルの半球の半径を0.4,円柱の高さを1.5
cap = fcl.Capsule(0.4, 1.5)
# カプセルの基準点(中点)は[1.2, 0.0, 0.0]、回転を無回転とする
cap_tf = fcl.Transform(np.array([1.2, 0.0, 0.0]))
# 干渉物オブジェクトの作成
cap_obj = fcl.CollisionObject(cap, cap_tf)

# 干渉判定と異なる箇所 ↓
# 距離計算用リクエストと結果オブジェクトを定義
request = fcl.DistanceRequest()
result  = fcl.DistanceResult()

# 距離計算実行
ret = fcl.distance(cyl_obj, cap_obj, request, result)

# 結果表示
# min_distance > 0: 衝突していない
# min_distance = 0: 接触 (境界で接している)
# min_distance < 0: 干渉 (めり込んでいる)
print(f"Distance: {result.min_distance}")
print(f"Nearest point on cylinder: {result.nearest_points[0]}")
print(f"Nearest point on capsule: {result.nearest_points[1]}")
# 干渉判定と異なる箇所 ↑

結果は以下となった.最短距離が0.3であるのは想定通りだが,最短距離の位置のz軸が-0.3となる理由は不明である.z軸が0.0でも,-0.1でも最短距離は0.3になるため,どうして-0.3が一意に決まったのかは不明.
スクリーンショット 2025-06-13 17.21.14.png

連続干渉判定 (Continuous Collision Detection)

python-fcl にて,連続干渉判定の処理方法を説明する.
今回は立方体と立方体の連続干渉判定を実施してみた.

test_fcl.py
# 1辺が1の立方体
box1 = fcl.Box(1.0, 1.0, 1.0)
# 初期位置(中心点)は原点,姿勢は無回転
box1_tf_start = fcl.Transform()
# 干渉物オブジェクトの作成
box1_obj = fcl.CollisionObject(box1, box1_tf_start)
# 終了位置はx方向に1.5移動
box1_tf_end = fcl.Transform(np.array([1.5, 0, 0]))

# 1辺が1の立方体
box2 = fcl.Box(1.0, 1.0, 1.0)
# 初期位置はxに2.5,姿勢は無回転
box2_tf_start = fcl.Transform(np.array([2.5, 0, 0]))
# 干渉物オブジェクトの作成
box2_obj = fcl.CollisionObject(box2, box2_tf_start)
# 終了位置は初期位置と同じ
box2_tf_end = box2_tf_start

# 連続干渉判定用リクエストと結果
ccd_request = fcl.ContinuousCollisionRequest()
ccd_result  = fcl.ContinuousCollisionResult()

# 連続干渉判定の実行
ret = fcl.continuousCollide(
    box1_obj, box1_tf_end,
    box2_obj, box2_tf_end,
    ccd_request, ccd_result)

print(f"ret = {ret}")
print(f"ccd_result.is_collide = {ccd_result.is_collide}")
if ccd_result.is_collide:   # 干渉あり
    # 干渉時の時間
    print(f"Time of contact: {ccd_result.time_of_contact}")

上記を実施すると結果は以下となった.
結果としては,干渉なしとなった.retには干渉した時の時間が(0, 1)で保存され,初期位置から目標位置へ連続干渉をしても,干渉しなかったら1が返ってくる.
スクリーンショット 2025-06-13 18.05.49.png
想定の動きとしては,目標位置に移動するとちょうどbox1とbox2が接するような処理としていたのが問題であった.そのため,box1_tf_endをx方向に1.6移動させると干渉があるのではないかと思われる.

test_fcl.py
box1_tf_end = fcl.Transform(np.array([1.6, 0.0, 0]))

結果は以下となった.干渉なしと想定外の結果となった.
スクリーンショット 2025-06-13 18.05.49.png

box1_tf_endとbox2_tf_startを以下のように修正したら,上手くいった.

test_fcl.py
box1_tf_end = fcl.Transform(np.array([0, 1.6, 0]))
box2_tf_start = fcl.Transform(np.array([0, 2.5, 0]))
test_fcl.py
box1_tf_end = fcl.Transform(np.array([0, 0, 1.6]))
box2_tf_start = fcl.Transform(np.array([0, 0, 2.5]))

スクリーンショット 2025-06-13 18.14.29.png

y,z軸だけを移動させると干渉ありになるが,x軸だけを移動させると干渉なしになる理由がわからない.
そのため,x軸だけでなく,y,z軸も以下のように微小に動かすことが必要である.

test_fcl.py
epsilon = 1e-6
box1_tf_end = fcl.Transform(np.array([1.6, epsilon, epsilon]))
box2_tf_start = fcl.Transform(np.array([2.5, epsilon, epsilon]))

python-fcl を使用することによって,どのような環境でも構築でき,経路生成に活かすことができる.
また,ロボットも python-fcl により定義することができるようになる.

複数の干渉物をAABBとして,一つにまとめる

複数の干渉物を AABB(Axis-Aligned Bounding Box) として,一つにまとめる方法を説明する.
今回は複数の円をAABbとして,一つにまとめるソースコードを下記に記す.

test_fcl.py
objects = []

# 円形の干渉物を定義 (円の位置 (x, y) と半径を定義)
circles = [[0.8, 0.8, 0.3], [1.2, 0.8, 0.3], [1.2, 1.2, 0.3], [0.8, 1.2, 0.3]]
for x, y, radius in circles:
    # fclに円が定義されていないため,楕円のz軸を0として円とする
    circle = fcl.Ellipsoid(radius, radius, 0.0)
    # 円の中心点が原点であるため,中心点を平行移動させる
    translation = fcl.Transform(np.array([x, y, 0.0]))
    obj = fcl.CollisionObject(circle, translation)
    # モデルを追加
    objects.append(obj)

# DynamicAABBTreeCollisionManager に登録
manager1 = fcl.DynamicAABBTreeCollisionManager()
manager1.registerObjects(objects)
manager1.setup()

# DynamicAABBTreeCollisionManager に登録
manager2 = fcl.DynamicAABBTreeCollisionManager()
manager2.registerObjects(objects)
manager2.setup()

# 干渉判定で使用するリクエストと干渉データ
request  = fcl.CollisionRequest(num_max_contacts=100, enable_contact=True)
col_data = fcl.CollisionData(request=request)

# 干渉物の干渉判定
manager1.collide(manager2, col_data, fcl.defaultCollisionCallback)
print(col_data.result.is_collision)

おわりに

本記事では,Pythonを使用して,下記内容を実装しました.
・干渉判定用ライブラリである python-fcl の使用方法を説明

次記事では,下記内容を実装していきます.
・経路生成手法である RRT に python-fcl を組み込む

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?