2222
2323
2424class CCD_ALGORITHM_CODE (IntEnum ):
25+ # Our MPR (with SDF)
2526 MPR = 0
26- MPR_SDF = 1
27+ # MuJoCo MPR
28+ MJ_MPR = 1
29+ # Our GJK
2730 GJK = 2
31+ # MuJoCo GJK
32+ MJ_GJK = 3
2833
2934
3035@ti .func
@@ -54,15 +59,19 @@ def __init__(self, rigid_solver: "RigidSolver"):
5459
5560 # Identify the convex collision detection (ccd) algorithm
5661 if self ._solver ._options .use_gjk_collision :
57- self .ccd_algorithm = CCD_ALGORITHM_CODE .GJK
58- elif self ._solver ._enable_mujoco_compatibility :
59- self .ccd_algorithm = CCD_ALGORITHM_CODE .MPR
62+ if self ._solver ._enable_mujoco_compatibility :
63+ self .ccd_algorithm = CCD_ALGORITHM_CODE .MJ_GJK
64+ else :
65+ self .ccd_algorithm = CCD_ALGORITHM_CODE .GJK
6066 else :
61- self .ccd_algorithm = CCD_ALGORITHM_CODE .MPR_SDF
67+ if self ._solver ._enable_mujoco_compatibility :
68+ self .ccd_algorithm = CCD_ALGORITHM_CODE .MJ_MPR
69+ else :
70+ self .ccd_algorithm = CCD_ALGORITHM_CODE .MPR
6271
6372 # FIXME: MPR is necessary because it is used for terrain collision detection
6473 self ._mpr = MPR (rigid_solver )
65- self ._gjk = GJK (rigid_solver ) if self .ccd_algorithm == CCD_ALGORITHM_CODE . GJK else None
74+ self ._gjk = GJK (rigid_solver ) if self ._solver . _options . use_gjk_collision else None
6675
6776 # multi contact perturbation and tolerance
6877 if self ._solver ._enable_mujoco_compatibility :
@@ -1110,6 +1119,7 @@ def _func_plane_box_contact(self, i_ga, i_gb, i_b):
11101119
11111120 @ti .func
11121121 def _func_add_contact (self , i_ga , i_gb , normal , contact_pos , penetration , i_b ):
1122+ # print(f"Adding contact {i_ga} {i_gb}, normal:", normal, "contact_pos:", contact_pos, "penetration:", penetration)
11131123 i_col = self .n_contacts [i_b ]
11141124
11151125 if i_col == self ._max_contact_pairs :
@@ -1265,8 +1275,8 @@ def _func_convex_convex_contact(self, i_ga, i_gb, i_b):
12651275 contact_pos = v1 - 0.5 * penetration * normal
12661276 is_col = penetration > 0
12671277 else :
1268- ### MPR, MPR + SDF
1269- if ti .static (self .ccd_algorithm != CCD_ALGORITHM_CODE .GJK ):
1278+ ### MPR, MJ_MPR
1279+ if ti .static (self .ccd_algorithm in ( CCD_ALGORITHM_CODE .MPR , CCD_ALGORITHM_CODE . MJ_MPR ) ):
12701280 # Try using MPR before anything else
12711281 is_mpr_updated = False
12721282 is_mpr_guess_direction_available = True
@@ -1301,10 +1311,9 @@ def _func_convex_convex_contact(self, i_ga, i_gb, i_b):
13011311 # associated with the point of deepest penetration.
13021312 try_sdf = True
13031313
1304- ### GJK
1305- elif ti .static (self .ccd_algorithm == CCD_ALGORITHM_CODE .GJK ):
1306- # If it was not the first detection, only detect single contact point.
1307- self ._gjk .func_gjk_contact (i_ga , i_gb , i_b , i_detection == 0 )
1314+ ### GJK, MJ_GJK
1315+ elif ti .static (self .ccd_algorithm in (CCD_ALGORITHM_CODE .GJK , CCD_ALGORITHM_CODE .MJ_GJK )):
1316+ self ._gjk .func_gjk_contact (i_ga , i_gb , i_b )
13081317
13091318 is_col = self ._gjk .is_col [i_b ] == 1
13101319 penetration = self ._gjk .penetration [i_b ]
@@ -1326,7 +1335,7 @@ def _func_convex_convex_contact(self, i_ga, i_gb, i_b):
13261335 contact_pos = self ._gjk .contact_pos [i_b , 0 ]
13271336 normal = self ._gjk .normal [i_b , 0 ]
13281337
1329- if ti .static (self .ccd_algorithm == CCD_ALGORITHM_CODE .MPR_SDF ):
1338+ if ti .static (self .ccd_algorithm == CCD_ALGORITHM_CODE .MPR ):
13301339 if try_sdf :
13311340 is_col_a = False
13321341 is_col_b = False
@@ -1392,15 +1401,15 @@ def _func_convex_convex_contact(self, i_ga, i_gb, i_b):
13921401 axis_0 , axis_1 = self ._func_contact_orthogonals (i_ga , i_gb , normal , i_b )
13931402 n_con = 1
13941403
1395- if ti .static (not self ._solver . _enable_mujoco_compatibility ):
1404+ if ti .static (self .ccd_algorithm in ( CCD_ALGORITHM_CODE . MPR , CCD_ALGORITHM_CODE . GJK ) ):
13961405 self .contact_cache [i_ga , i_gb , i_b ].normal = normal
13971406 else :
13981407 # Clear collision normal cache if not in contact
13991408 # self.contact_cache[i_ga, i_gb, i_b].i_va_ws = -1
14001409 self .contact_cache [i_ga , i_gb , i_b ].normal .fill (0.0 )
14011410
14021411 elif multi_contact and is_col_0 > 0 and is_col > 0 :
1403- if ti .static (self .ccd_algorithm == CCD_ALGORITHM_CODE .MPR_SDF ):
1412+ if ti .static (self .ccd_algorithm in ( CCD_ALGORITHM_CODE .MPR , CCD_ALGORITHM_CODE . GJK ) ):
14041413 # 1. Project the contact point on both geometries
14051414 # 2. Revert the effect of small rotation
14061415 # 3. Update contact point
@@ -1437,9 +1446,9 @@ def _func_convex_convex_contact(self, i_ga, i_gb, i_b):
14371446 # dynamics since zero-penetration contact points should not induce any force.
14381447 penetration = normal .dot (contact_point_b - contact_point_a )
14391448
1440- elif ti .static (self .ccd_algorithm == CCD_ALGORITHM_CODE .GJK ):
1449+ elif ti .static (self .ccd_algorithm == CCD_ALGORITHM_CODE .MJ_GJK ):
14411450 # Only change penetration to the initial one, because the normal vector could change abruptly
1442- # under GJK-EPA as the nearest simplex is determined by discrete logic, unlike MPR .
1451+ # under MuJoCo's GJK-EPA.
14431452 penetration = penetration_0
14441453
14451454 # Discard contact point is repeated
@@ -1457,10 +1466,10 @@ def _func_convex_convex_contact(self, i_ga, i_gb, i_b):
14571466 self ._func_add_contact (i_ga , i_gb , normal , contact_pos , penetration , i_b )
14581467 n_con = n_con + 1
14591468
1460- self ._solver .geoms_state [i_ga , i_b ].pos = ga_pos
1461- self ._solver .geoms_state [i_ga , i_b ].quat = ga_quat
1462- self ._solver .geoms_state [i_gb , i_b ].pos = gb_pos
1463- self ._solver .geoms_state [i_gb , i_b ].quat = gb_quat
1469+ self ._solver .geoms_state [i_ga , i_b ].pos = ga_pos
1470+ self ._solver .geoms_state [i_ga , i_b ].quat = ga_quat
1471+ self ._solver .geoms_state [i_gb , i_b ].pos = gb_pos
1472+ self ._solver .geoms_state [i_gb , i_b ].quat = gb_quat
14641473
14651474 @ti .func
14661475 def _func_rotate_frame (self , i_g , contact_pos , qrot , i_b ):
0 commit comments