Import google-deepmind/mujoco_warp from GitHub.
PiperOrigin-RevId: 892971818 Change-Id: Ibce0c41294a4fcf2825a246a9533e8927fdc7e82
This commit is contained in:
committed by
Copybara-Service
parent
70a7647ad9
commit
e9de329e4e
@@ -64,6 +64,7 @@ from mujoco.mjx.third_party.mujoco_warp._src.ray import rays as rays
|
|||||||
from mujoco.mjx.third_party.mujoco_warp._src.render import render as render
|
from mujoco.mjx.third_party.mujoco_warp._src.render import render as render
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.render_util import get_depth as get_depth
|
from mujoco.mjx.third_party.mujoco_warp._src.render_util import get_depth as get_depth
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.render_util import get_rgb as get_rgb
|
from mujoco.mjx.third_party.mujoco_warp._src.render_util import get_rgb as get_rgb
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.render_util import get_segmentation as get_segmentation
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.sensor import energy_pos as energy_pos
|
from mujoco.mjx.third_party.mujoco_warp._src.sensor import energy_pos as energy_pos
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.sensor import energy_vel as energy_vel
|
from mujoco.mjx.third_party.mujoco_warp._src.sensor import energy_vel as energy_vel
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.sensor import sensor_acc as sensor_acc
|
from mujoco.mjx.third_party.mujoco_warp._src.sensor import sensor_acc as sensor_acc
|
||||||
@@ -92,6 +93,7 @@ from mujoco.mjx.third_party.mujoco_warp._src.support import xfrc_accumulate as x
|
|||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import BiasType as BiasType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import BiasType as BiasType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import BroadphaseFilter as BroadphaseFilter
|
from mujoco.mjx.third_party.mujoco_warp._src.types import BroadphaseFilter as BroadphaseFilter
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import BroadphaseType as BroadphaseType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import BroadphaseType as BroadphaseType
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import Callback as Callback
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import ConeType as ConeType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import ConeType as ConeType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import Constraint as Constraint
|
from mujoco.mjx.third_party.mujoco_warp._src.types import Constraint as Constraint
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import Contact as Contact
|
from mujoco.mjx.third_party.mujoco_warp._src.types import Contact as Contact
|
||||||
|
|||||||
+260
-130
@@ -189,12 +189,12 @@ def _compute_bvh_bounds(
|
|||||||
upper_out: wp.array(dtype=wp.vec3),
|
upper_out: wp.array(dtype=wp.vec3),
|
||||||
group_out: wp.array(dtype=int),
|
group_out: wp.array(dtype=int),
|
||||||
):
|
):
|
||||||
world_id, geom_local_id = wp.tid()
|
worldid, geom_local_id = wp.tid()
|
||||||
geom_id = enabled_geom_ids[geom_local_id]
|
geom_id = enabled_geom_ids[geom_local_id]
|
||||||
|
|
||||||
pos = geom_xpos_in[world_id, geom_id]
|
pos = geom_xpos_in[worldid, geom_id]
|
||||||
rot = geom_xmat_in[world_id, geom_id]
|
rot = geom_xmat_in[worldid, geom_id]
|
||||||
size = geom_size[world_id % geom_size.shape[0], geom_id]
|
size = geom_size[worldid % geom_size.shape[0], geom_id]
|
||||||
type = geom_type[geom_id]
|
type = geom_type[geom_id]
|
||||||
|
|
||||||
# TODO: Investigate branch elimination with static loop unrolling
|
# TODO: Investigate branch elimination with static loop unrolling
|
||||||
@@ -218,9 +218,9 @@ def _compute_bvh_bounds(
|
|||||||
hfield_center = pos + rot[:, 2] * size[2]
|
hfield_center = pos + rot[:, 2] * size[2]
|
||||||
lower_bound, upper_bound = _compute_box_bounds(hfield_center, rot, size)
|
lower_bound, upper_bound = _compute_box_bounds(hfield_center, rot, size)
|
||||||
|
|
||||||
lower_out[world_id * bvh_ngeom + geom_local_id] = lower_bound
|
lower_out[worldid * bvh_ngeom + geom_local_id] = lower_bound
|
||||||
upper_out[world_id * bvh_ngeom + geom_local_id] = upper_bound
|
upper_out[worldid * bvh_ngeom + geom_local_id] = upper_bound
|
||||||
group_out[world_id * bvh_ngeom + geom_local_id] = world_id
|
group_out[worldid * bvh_ngeom + geom_local_id] = worldid
|
||||||
|
|
||||||
|
|
||||||
@wp.kernel
|
@wp.kernel
|
||||||
@@ -235,14 +235,70 @@ def compute_bvh_group_roots(
|
|||||||
group_root_out[tid] = root
|
group_root_out[tid] = root
|
||||||
|
|
||||||
|
|
||||||
|
@wp.kernel
|
||||||
|
def _compute_flex_bvh_bounds(
|
||||||
|
# Model:
|
||||||
|
flex_vertadr: wp.array(dtype=int),
|
||||||
|
flex_vertnum: wp.array(dtype=int),
|
||||||
|
flex_edge: wp.array(dtype=wp.vec2i),
|
||||||
|
flex_radius: wp.array(dtype=float),
|
||||||
|
# Data in:
|
||||||
|
flexvert_xpos_in: wp.array2d(dtype=wp.vec3),
|
||||||
|
# In:
|
||||||
|
flex_geom_flexid: wp.array(dtype=int),
|
||||||
|
flex_geom_edgeid: wp.array(dtype=int),
|
||||||
|
bvh_ngeom: int,
|
||||||
|
total_bvh_size: int,
|
||||||
|
# Out:
|
||||||
|
lower_out: wp.array(dtype=wp.vec3),
|
||||||
|
upper_out: wp.array(dtype=wp.vec3),
|
||||||
|
group_out: wp.array(dtype=int),
|
||||||
|
):
|
||||||
|
worldid, flexlocalid = wp.tid()
|
||||||
|
|
||||||
|
flex_id = flex_geom_flexid[flexlocalid]
|
||||||
|
edge_id = flex_geom_edgeid[flexlocalid]
|
||||||
|
out_idx = worldid * total_bvh_size + bvh_ngeom + flexlocalid
|
||||||
|
radius = flex_radius[flex_id]
|
||||||
|
inflate = wp.vec3(radius, radius, radius)
|
||||||
|
|
||||||
|
if edge_id >= 0: # capsule (1D edge)
|
||||||
|
edge = flex_edge[edge_id]
|
||||||
|
vert_adr = flex_vertadr[flex_id]
|
||||||
|
v0 = flexvert_xpos_in[worldid, vert_adr + edge[0]]
|
||||||
|
v1 = flexvert_xpos_in[worldid, vert_adr + edge[1]]
|
||||||
|
lower_out[out_idx] = wp.min(v0, v1) - inflate
|
||||||
|
upper_out[out_idx] = wp.max(v0, v1) + inflate
|
||||||
|
else: # mesh (2D/3D)
|
||||||
|
vert_adr = flex_vertadr[flex_id]
|
||||||
|
nvert = flex_vertnum[flex_id]
|
||||||
|
min_bound = wp.vec3(MJ_MAXVAL, MJ_MAXVAL, MJ_MAXVAL)
|
||||||
|
max_bound = wp.vec3(-MJ_MAXVAL, -MJ_MAXVAL, -MJ_MAXVAL)
|
||||||
|
for i in range(nvert):
|
||||||
|
v = flexvert_xpos_in[worldid, vert_adr + i]
|
||||||
|
min_bound = wp.min(min_bound, v)
|
||||||
|
max_bound = wp.max(max_bound, v)
|
||||||
|
lower_out[out_idx] = min_bound - inflate
|
||||||
|
upper_out[out_idx] = max_bound + inflate
|
||||||
|
|
||||||
|
group_out[out_idx] = worldid
|
||||||
|
|
||||||
|
|
||||||
def build_scene_bvh(mjm: mujoco.MjModel, mjd: mujoco.MjData, rc: RenderContext, nworld: int):
|
def build_scene_bvh(mjm: mujoco.MjModel, mjd: mujoco.MjData, rc: RenderContext, nworld: int):
|
||||||
"""Build a global BVH for all geometries in all worlds."""
|
"""Build a global BVH for all geometries in all worlds."""
|
||||||
|
total_bvh_size = rc.bvh_ngeom + rc.bvh_nflexgeom
|
||||||
|
|
||||||
geom_type = wp.array(mjm.geom_type, dtype=int)
|
geom_type = wp.array(mjm.geom_type, dtype=int)
|
||||||
geom_dataid = wp.array(mjm.geom_dataid, dtype=int)
|
geom_dataid = wp.array(mjm.geom_dataid, dtype=int)
|
||||||
geom_size = wp.array(np.tile(mjm.geom_size[np.newaxis, :, :], (nworld, 1, 1)), dtype=wp.vec3)
|
geom_size = wp.array(np.tile(mjm.geom_size[np.newaxis, :, :], (nworld, 1, 1)), dtype=wp.vec3)
|
||||||
geom_xpos = wp.array(np.tile(mjd.geom_xpos[np.newaxis, :, :], (nworld, 1, 1)), dtype=wp.vec3)
|
geom_xpos = wp.array(np.tile(mjd.geom_xpos[np.newaxis, :, :], (nworld, 1, 1)), dtype=wp.vec3)
|
||||||
geom_xmat = wp.array(np.tile(mjd.geom_xmat.reshape(mjm.ngeom, 3, 3)[np.newaxis, :, :, :], (nworld, 1, 1, 1)), dtype=wp.mat33)
|
geom_xmat = wp.array(np.tile(mjd.geom_xmat.reshape(mjm.ngeom, 3, 3)[np.newaxis, :, :, :], (nworld, 1, 1, 1)), dtype=wp.mat33)
|
||||||
|
|
||||||
|
flex_vertadr = wp.array(mjm.flex_vertadr, dtype=int)
|
||||||
|
flex_vertnum = wp.array(mjm.flex_vertnum, dtype=int)
|
||||||
|
flex_edge = wp.array(mjm.flex_edge, dtype=wp.vec2i)
|
||||||
|
flex_radius = wp.array(mjm.flex_radius, dtype=float)
|
||||||
|
|
||||||
wp.launch(
|
wp.launch(
|
||||||
kernel=_compute_bvh_bounds,
|
kernel=_compute_bvh_bounds,
|
||||||
dim=(nworld, rc.bvh_ngeom),
|
dim=(nworld, rc.bvh_ngeom),
|
||||||
@@ -252,7 +308,7 @@ def build_scene_bvh(mjm: mujoco.MjModel, mjd: mujoco.MjData, rc: RenderContext,
|
|||||||
geom_size,
|
geom_size,
|
||||||
geom_xpos,
|
geom_xpos,
|
||||||
geom_xmat,
|
geom_xmat,
|
||||||
rc.bvh_ngeom,
|
total_bvh_size,
|
||||||
rc.enabled_geom_ids,
|
rc.enabled_geom_ids,
|
||||||
rc.mesh_bounds_size,
|
rc.mesh_bounds_size,
|
||||||
rc.hfield_bounds_size,
|
rc.hfield_bounds_size,
|
||||||
@@ -262,6 +318,26 @@ def build_scene_bvh(mjm: mujoco.MjModel, mjd: mujoco.MjData, rc: RenderContext,
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
flexvert_xpos = wp.array(np.tile(mjd.flexvert_xpos[np.newaxis, :, :], (nworld, 1, 1)), dtype=wp.vec3)
|
||||||
|
wp.launch(
|
||||||
|
kernel=_compute_flex_bvh_bounds,
|
||||||
|
dim=(nworld, rc.bvh_nflexgeom),
|
||||||
|
inputs=[
|
||||||
|
flex_vertadr,
|
||||||
|
flex_vertnum,
|
||||||
|
flex_edge,
|
||||||
|
flex_radius,
|
||||||
|
flexvert_xpos,
|
||||||
|
rc.flex_geom_flexid,
|
||||||
|
rc.flex_geom_edgeid,
|
||||||
|
rc.bvh_ngeom,
|
||||||
|
total_bvh_size,
|
||||||
|
rc.lower,
|
||||||
|
rc.upper,
|
||||||
|
rc.group,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
bvh = wp.Bvh(rc.lower, rc.upper, groups=rc.group, constructor="sah")
|
bvh = wp.Bvh(rc.lower, rc.upper, groups=rc.group, constructor="sah")
|
||||||
|
|
||||||
# BVH handle must be stored to avoid garbage collection
|
# BVH handle must be stored to avoid garbage collection
|
||||||
@@ -277,6 +353,8 @@ def build_scene_bvh(mjm: mujoco.MjModel, mjd: mujoco.MjData, rc: RenderContext,
|
|||||||
|
|
||||||
|
|
||||||
def refit_scene_bvh(m: Model, d: Data, rc: RenderContext):
|
def refit_scene_bvh(m: Model, d: Data, rc: RenderContext):
|
||||||
|
total_bvh_size = rc.bvh_ngeom + rc.bvh_nflexgeom
|
||||||
|
|
||||||
wp.launch(
|
wp.launch(
|
||||||
kernel=_compute_bvh_bounds,
|
kernel=_compute_bvh_bounds,
|
||||||
dim=(d.nworld, rc.bvh_ngeom),
|
dim=(d.nworld, rc.bvh_ngeom),
|
||||||
@@ -286,7 +364,7 @@ def refit_scene_bvh(m: Model, d: Data, rc: RenderContext):
|
|||||||
m.geom_size,
|
m.geom_size,
|
||||||
d.geom_xpos,
|
d.geom_xpos,
|
||||||
d.geom_xmat,
|
d.geom_xmat,
|
||||||
rc.bvh_ngeom,
|
total_bvh_size,
|
||||||
rc.enabled_geom_ids,
|
rc.enabled_geom_ids,
|
||||||
rc.mesh_bounds_size,
|
rc.mesh_bounds_size,
|
||||||
rc.hfield_bounds_size,
|
rc.hfield_bounds_size,
|
||||||
@@ -296,6 +374,26 @@ def refit_scene_bvh(m: Model, d: Data, rc: RenderContext):
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if rc.bvh_nflexgeom > 0:
|
||||||
|
wp.launch(
|
||||||
|
kernel=_compute_flex_bvh_bounds,
|
||||||
|
dim=(d.nworld, rc.bvh_nflexgeom),
|
||||||
|
inputs=[
|
||||||
|
m.flex_vertadr,
|
||||||
|
m.flex_vertnum,
|
||||||
|
m.flex_edge,
|
||||||
|
m.flex_radius,
|
||||||
|
d.flexvert_xpos,
|
||||||
|
rc.flex_geom_flexid,
|
||||||
|
rc.flex_geom_edgeid,
|
||||||
|
rc.bvh_ngeom,
|
||||||
|
total_bvh_size,
|
||||||
|
rc.lower,
|
||||||
|
rc.upper,
|
||||||
|
rc.group,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
rc.bvh.refit()
|
rc.bvh.refit()
|
||||||
|
|
||||||
|
|
||||||
@@ -500,6 +598,12 @@ def build_hfield_bvh(
|
|||||||
@wp.kernel
|
@wp.kernel
|
||||||
def accumulate_flex_vertex_normals(
|
def accumulate_flex_vertex_normals(
|
||||||
# Model:
|
# Model:
|
||||||
|
nflex: int,
|
||||||
|
flex_dim: wp.array(dtype=int),
|
||||||
|
flex_vertadr: wp.array(dtype=int),
|
||||||
|
flex_elemadr: wp.array(dtype=int),
|
||||||
|
flex_elemnum: wp.array(dtype=int),
|
||||||
|
flex_elemdataadr: wp.array(dtype=int),
|
||||||
flex_elem: wp.array(dtype=int),
|
flex_elem: wp.array(dtype=int),
|
||||||
# Data in:
|
# Data in:
|
||||||
flexvert_xpos_in: wp.array2d(dtype=wp.vec3),
|
flexvert_xpos_in: wp.array2d(dtype=wp.vec3),
|
||||||
@@ -509,10 +613,22 @@ def accumulate_flex_vertex_normals(
|
|||||||
"""Accumulate per-vertex normals by summing adjacent face normals."""
|
"""Accumulate per-vertex normals by summing adjacent face normals."""
|
||||||
worldid, elemid = wp.tid()
|
worldid, elemid = wp.tid()
|
||||||
|
|
||||||
elem_base = elemid * 3
|
for i in range(nflex):
|
||||||
i0 = flex_elem[elem_base + 0]
|
locid = elemid - flex_elemadr[i]
|
||||||
i1 = flex_elem[elem_base + 1]
|
if locid >= 0 and locid < flex_elemnum[i]:
|
||||||
i2 = flex_elem[elem_base + 2]
|
f = i
|
||||||
|
break
|
||||||
|
|
||||||
|
if flex_dim[f] == 1 or flex_dim[f] == 3:
|
||||||
|
return
|
||||||
|
|
||||||
|
local_elemid = elemid - flex_elemadr[f]
|
||||||
|
elem_adr = flex_elemdataadr[f]
|
||||||
|
vert_adr = flex_vertadr[f]
|
||||||
|
elem_base = elem_adr + local_elemid * 3
|
||||||
|
i0 = vert_adr + flex_elem[elem_base + 0]
|
||||||
|
i1 = vert_adr + flex_elem[elem_base + 1]
|
||||||
|
i2 = vert_adr + flex_elem[elem_base + 2]
|
||||||
|
|
||||||
v0 = flexvert_xpos_in[worldid, i0]
|
v0 = flexvert_xpos_in[worldid, i0]
|
||||||
v1 = flexvert_xpos_in[worldid, i1]
|
v1 = flexvert_xpos_in[worldid, i1]
|
||||||
@@ -611,11 +727,12 @@ def _build_flex_2d_elements(
|
|||||||
|
|
||||||
@wp.kernel
|
@wp.kernel
|
||||||
def _build_flex_2d_sides(
|
def _build_flex_2d_sides(
|
||||||
|
# Model:
|
||||||
|
flex_shell: wp.array(dtype=int),
|
||||||
# Data in:
|
# Data in:
|
||||||
flexvert_xpos_in: wp.array2d(dtype=wp.vec3),
|
flexvert_xpos_in: wp.array2d(dtype=wp.vec3),
|
||||||
# In:
|
# In:
|
||||||
flexvert_norm_in: wp.array2d(dtype=wp.vec3),
|
flexvert_norm_in: wp.array2d(dtype=wp.vec3),
|
||||||
flex_shell_in: wp.array(dtype=int),
|
|
||||||
shell_adr: int,
|
shell_adr: int,
|
||||||
vert_adr: int,
|
vert_adr: int,
|
||||||
face_offset: int,
|
face_offset: int,
|
||||||
@@ -635,8 +752,8 @@ def _build_flex_2d_sides(
|
|||||||
worldid, shellid = wp.tid()
|
worldid, shellid = wp.tid()
|
||||||
|
|
||||||
base = shell_adr + 2 * shellid
|
base = shell_adr + 2 * shellid
|
||||||
i0 = vert_adr + flex_shell_in[base + 0]
|
i0 = vert_adr + flex_shell[base + 0]
|
||||||
i1 = vert_adr + flex_shell_in[base + 1]
|
i1 = vert_adr + flex_shell[base + 1]
|
||||||
|
|
||||||
v0 = flexvert_xpos_in[worldid, i0]
|
v0 = flexvert_xpos_in[worldid, i0]
|
||||||
v1 = flexvert_xpos_in[worldid, i1]
|
v1 = flexvert_xpos_in[worldid, i1]
|
||||||
@@ -672,10 +789,11 @@ def _build_flex_2d_sides(
|
|||||||
|
|
||||||
@wp.kernel
|
@wp.kernel
|
||||||
def _build_flex_3d_shells(
|
def _build_flex_3d_shells(
|
||||||
|
# Model:
|
||||||
|
flex_shell: wp.array(dtype=int),
|
||||||
# Data in:
|
# Data in:
|
||||||
flexvert_xpos_in: wp.array2d(dtype=wp.vec3),
|
flexvert_xpos_in: wp.array2d(dtype=wp.vec3),
|
||||||
# In:
|
# In:
|
||||||
flex_shell_in: wp.array(dtype=int),
|
|
||||||
shell_adr: int,
|
shell_adr: int,
|
||||||
vert_adr: int,
|
vert_adr: int,
|
||||||
face_offset: int,
|
face_offset: int,
|
||||||
@@ -693,9 +811,9 @@ def _build_flex_3d_shells(
|
|||||||
worldid, shellid = wp.tid()
|
worldid, shellid = wp.tid()
|
||||||
|
|
||||||
base = shell_adr + shellid * 3
|
base = shell_adr + shellid * 3
|
||||||
i0 = vert_adr + flex_shell_in[base + 0]
|
i0 = vert_adr + flex_shell[base + 0]
|
||||||
i1 = vert_adr + flex_shell_in[base + 1]
|
i1 = vert_adr + flex_shell[base + 1]
|
||||||
i2 = vert_adr + flex_shell_in[base + 2]
|
i2 = vert_adr + flex_shell[base + 2]
|
||||||
|
|
||||||
face_id = worldid * nface + face_offset + shellid
|
face_id = worldid * nface + face_offset + shellid
|
||||||
base = face_id * 3
|
base = face_id * 3
|
||||||
@@ -716,53 +834,36 @@ def _build_flex_3d_shells(
|
|||||||
|
|
||||||
|
|
||||||
@wp.kernel
|
@wp.kernel
|
||||||
def _update_flex_face_points(
|
def _update_flex_2d_face_points(
|
||||||
# Model:
|
# Model:
|
||||||
nflex: int,
|
|
||||||
flex_dim: wp.array(dtype=int),
|
|
||||||
flex_vertadr: wp.array(dtype=int),
|
flex_vertadr: wp.array(dtype=int),
|
||||||
flex_elemnum: wp.array(dtype=int),
|
flex_elemnum: wp.array(dtype=int),
|
||||||
|
flex_elemdataadr: wp.array(dtype=int),
|
||||||
|
flex_shelldataadr: wp.array(dtype=int),
|
||||||
flex_elem: wp.array(dtype=int),
|
flex_elem: wp.array(dtype=int),
|
||||||
|
flex_shell: wp.array(dtype=int),
|
||||||
|
flex_radius: wp.array(dtype=float),
|
||||||
# Data in:
|
# Data in:
|
||||||
flexvert_xpos_in: wp.array2d(dtype=wp.vec3),
|
flexvert_xpos_in: wp.array2d(dtype=wp.vec3),
|
||||||
# In:
|
# In:
|
||||||
flex_shell_in: wp.array(dtype=int),
|
|
||||||
flexvert_norm_in: wp.array2d(dtype=wp.vec3),
|
flexvert_norm_in: wp.array2d(dtype=wp.vec3),
|
||||||
flex_elemdataadr: wp.array(dtype=int),
|
flex_id: int,
|
||||||
flex_shelldataadr: wp.array(dtype=int),
|
nface: int,
|
||||||
flex_faceadr: wp.array(dtype=int),
|
|
||||||
flex_radius: wp.array(dtype=float),
|
|
||||||
flex_workadr: wp.array(dtype=int),
|
|
||||||
flex_worknum: wp.array(dtype=int),
|
|
||||||
nfaces: int,
|
|
||||||
smooth: bool,
|
smooth: bool,
|
||||||
# Out:
|
# Out:
|
||||||
face_point_out: wp.array(dtype=wp.vec3),
|
face_point_out: wp.array(dtype=wp.vec3),
|
||||||
):
|
):
|
||||||
worldid, workid = wp.tid()
|
worldid, workid = wp.tid()
|
||||||
|
|
||||||
# identify which flex this work item belongs to
|
elem_adr = flex_elemdataadr[flex_id]
|
||||||
f = int(0)
|
vert_adr = flex_vertadr[flex_id]
|
||||||
locid = int(0)
|
radius = flex_radius[flex_id]
|
||||||
for i in range(nflex):
|
nelem = flex_elemnum[flex_id]
|
||||||
locid = workid - flex_workadr[i]
|
world_face_offset = worldid * nface
|
||||||
if locid >= 0 and locid < flex_worknum[i]:
|
|
||||||
f = i
|
|
||||||
break
|
|
||||||
|
|
||||||
dim = flex_dim[f]
|
if workid < nelem:
|
||||||
face_offset = flex_faceadr[f]
|
|
||||||
world_face_offset = worldid * nfaces
|
|
||||||
vert_adr = flex_vertadr[f]
|
|
||||||
|
|
||||||
if dim == 2:
|
|
||||||
radius = flex_radius[f]
|
|
||||||
elem_count = flex_elemnum[f]
|
|
||||||
|
|
||||||
if locid < elem_count:
|
|
||||||
# 2D element faces
|
# 2D element faces
|
||||||
elemid = locid
|
elemid = workid
|
||||||
elem_adr = flex_elemdataadr[f]
|
|
||||||
ebase = elem_adr + elemid * 3
|
ebase = elem_adr + elemid * 3
|
||||||
i0 = vert_adr + flex_elem[ebase + 0]
|
i0 = vert_adr + flex_elem[ebase + 0]
|
||||||
i1 = vert_adr + flex_elem[ebase + 1]
|
i1 = vert_adr + flex_elem[ebase + 1]
|
||||||
@@ -792,24 +893,24 @@ def _update_flex_face_points(
|
|||||||
p1_neg = v1 - radius * n1
|
p1_neg = v1 - radius * n1
|
||||||
p2_neg = v2 - radius * n2
|
p2_neg = v2 - radius * n2
|
||||||
|
|
||||||
face_id0 = world_face_offset + face_offset + (2 * elemid)
|
face_id0 = world_face_offset + (2 * elemid)
|
||||||
base0 = face_id0 * 3
|
base0 = face_id0 * 3
|
||||||
face_point_out[base0 + 0] = p0_pos
|
face_point_out[base0 + 0] = p0_pos
|
||||||
face_point_out[base0 + 1] = p1_pos
|
face_point_out[base0 + 1] = p1_pos
|
||||||
face_point_out[base0 + 2] = p2_pos
|
face_point_out[base0 + 2] = p2_pos
|
||||||
|
|
||||||
face_id1 = world_face_offset + face_offset + (2 * elemid + 1)
|
face_id1 = world_face_offset + (2 * elemid + 1)
|
||||||
base1 = face_id1 * 3
|
base1 = face_id1 * 3
|
||||||
face_point_out[base1 + 0] = p0_neg
|
face_point_out[base1 + 0] = p0_neg
|
||||||
face_point_out[base1 + 1] = p1_neg
|
face_point_out[base1 + 1] = p1_neg
|
||||||
face_point_out[base1 + 2] = p2_neg
|
face_point_out[base1 + 2] = p2_neg
|
||||||
else:
|
else:
|
||||||
# 2D shell faces
|
# 2D shell faces
|
||||||
shellid = locid - elem_count
|
shell_adr = flex_shelldataadr[flex_id]
|
||||||
shell_adr = flex_shelldataadr[f]
|
shellid = workid - nelem
|
||||||
sbase = shell_adr + 2 * shellid
|
sbase = shell_adr + 2 * shellid
|
||||||
i0 = vert_adr + flex_shell_in[sbase + 0]
|
i0 = vert_adr + flex_shell[sbase + 0]
|
||||||
i1 = vert_adr + flex_shell_in[sbase + 1]
|
i1 = vert_adr + flex_shell[sbase + 1]
|
||||||
|
|
||||||
v0 = flexvert_xpos_in[worldid, i0]
|
v0 = flexvert_xpos_in[worldid, i0]
|
||||||
v1 = flexvert_xpos_in[worldid, i1]
|
v1 = flexvert_xpos_in[worldid, i1]
|
||||||
@@ -817,7 +918,7 @@ def _update_flex_face_points(
|
|||||||
n0 = flexvert_norm_in[worldid, i0]
|
n0 = flexvert_norm_in[worldid, i0]
|
||||||
n1 = flexvert_norm_in[worldid, i1]
|
n1 = flexvert_norm_in[worldid, i1]
|
||||||
|
|
||||||
shell_face_offset = face_offset + (2 * elem_count)
|
shell_face_offset = 2 * nelem
|
||||||
face_id0 = world_face_offset + shell_face_offset + (2 * shellid)
|
face_id0 = world_face_offset + shell_face_offset + (2 * shellid)
|
||||||
base0 = face_id0 * 3
|
base0 = face_id0 * 3
|
||||||
face_point_out[base0 + 0] = v0 + radius * n0
|
face_point_out[base0 + 0] = v0 + radius * n0
|
||||||
@@ -829,50 +930,67 @@ def _update_flex_face_points(
|
|||||||
face_point_out[base1 + 0] = v1 - radius * n1
|
face_point_out[base1 + 0] = v1 - radius * n1
|
||||||
face_point_out[base1 + 1] = v0 + radius * n0
|
face_point_out[base1 + 1] = v0 + radius * n0
|
||||||
face_point_out[base1 + 2] = v0 - radius * n0
|
face_point_out[base1 + 2] = v0 - radius * n0
|
||||||
else:
|
|
||||||
# 3D shell faces
|
|
||||||
shellid = locid
|
|
||||||
shell_adr = flex_shelldataadr[f]
|
|
||||||
sbase = shell_adr + shellid * 3
|
|
||||||
i0 = vert_adr + flex_shell_in[sbase + 0]
|
|
||||||
i1 = vert_adr + flex_shell_in[sbase + 1]
|
|
||||||
i2 = vert_adr + flex_shell_in[sbase + 2]
|
|
||||||
|
|
||||||
v0 = flexvert_xpos_in[worldid, i0]
|
|
||||||
v1 = flexvert_xpos_in[worldid, i1]
|
|
||||||
v2 = flexvert_xpos_in[worldid, i2]
|
|
||||||
|
|
||||||
face_id = world_face_offset + face_offset + shellid
|
@wp.kernel
|
||||||
|
def _update_flex_3d_face_points(
|
||||||
|
# Model:
|
||||||
|
flex_vertadr: wp.array(dtype=int),
|
||||||
|
flex_shelldataadr: wp.array(dtype=int),
|
||||||
|
flex_shell: wp.array(dtype=int),
|
||||||
|
# Data in:
|
||||||
|
flexvert_xpos_in: wp.array2d(dtype=wp.vec3),
|
||||||
|
# In:
|
||||||
|
flex_id: int,
|
||||||
|
nface: int,
|
||||||
|
# Out:
|
||||||
|
face_point_out: wp.array(dtype=wp.vec3),
|
||||||
|
):
|
||||||
|
worldid, shellid = wp.tid()
|
||||||
|
|
||||||
|
shell_adr = flex_shelldataadr[flex_id]
|
||||||
|
vert_adr = flex_vertadr[flex_id]
|
||||||
|
|
||||||
|
face_id = worldid * nface + shellid
|
||||||
fbase = face_id * 3
|
fbase = face_id * 3
|
||||||
|
|
||||||
face_point_out[fbase + 0] = v0
|
sbase = shell_adr + shellid * 3
|
||||||
face_point_out[fbase + 1] = v1
|
i0 = vert_adr + flex_shell[sbase + 0]
|
||||||
face_point_out[fbase + 2] = v2
|
i1 = vert_adr + flex_shell[sbase + 1]
|
||||||
|
i2 = vert_adr + flex_shell[sbase + 2]
|
||||||
|
|
||||||
|
face_point_out[fbase + 0] = flexvert_xpos_in[worldid, i0]
|
||||||
|
face_point_out[fbase + 1] = flexvert_xpos_in[worldid, i1]
|
||||||
|
face_point_out[fbase + 2] = flexvert_xpos_in[worldid, i2]
|
||||||
|
|
||||||
|
|
||||||
def build_flex_bvh(
|
def build_flex_bvh(
|
||||||
mjm: mujoco.MjModel, mjd: mujoco.MjData, nworld: int, constructor: str = "sah", leaf_size: int = 2
|
mjm: mujoco.MjModel,
|
||||||
) -> tuple[wp.Mesh, wp.array, wp.array, wp.array, wp.array, wp.array, int]:
|
mjd: mujoco.MjData,
|
||||||
"""Create a Warp mesh BVH from flex data."""
|
nworld: int,
|
||||||
if (mjm.flex_dim == 1).any():
|
flex_id: int,
|
||||||
raise ValueError("1D Flex objects are not currently supported.")
|
constructor: str = "sah",
|
||||||
|
leaf_size: int = 2,
|
||||||
nflex = mjm.nflex
|
) -> tuple[wp.Mesh, wp.array, wp.array, wp.array, int]:
|
||||||
|
"""Create a Warp mesh BVH for a single 2D or 3D flex."""
|
||||||
nflexvert = mjm.nflexvert
|
nflexvert = mjm.nflexvert
|
||||||
nflexelemdata = len(mjm.flex_elem)
|
|
||||||
|
|
||||||
|
flex_dim = wp.array(mjm.flex_dim, dtype=int)
|
||||||
|
flex_elemadr = wp.array(mjm.flex_elemadr, dtype=int)
|
||||||
|
flex_elemnum = wp.array(mjm.flex_elemnum, dtype=int)
|
||||||
flex_elem = wp.array(mjm.flex_elem, dtype=int)
|
flex_elem = wp.array(mjm.flex_elem, dtype=int)
|
||||||
|
flex_elemdataadr = wp.array(mjm.flex_elemdataadr, dtype=int)
|
||||||
|
flex_vertadr = wp.array(mjm.flex_vertadr, dtype=int)
|
||||||
flexvert_xpos = wp.array(np.tile(mjd.flexvert_xpos[np.newaxis, :, :], (nworld, 1, 1)), dtype=wp.vec3)
|
flexvert_xpos = wp.array(np.tile(mjd.flexvert_xpos[np.newaxis, :, :], (nworld, 1, 1)), dtype=wp.vec3)
|
||||||
|
|
||||||
flex_faceadr = [0]
|
dim = int(mjm.flex_dim[flex_id])
|
||||||
for f in range(nflex):
|
nelem = int(mjm.flex_elemnum[flex_id])
|
||||||
if mjm.flex_dim[f] == 2:
|
nshell = int(mjm.flex_shellnum[flex_id])
|
||||||
flex_faceadr.append(flex_faceadr[-1] + 2 * mjm.flex_elemnum[f] + 2 * mjm.flex_shellnum[f])
|
|
||||||
elif mjm.flex_dim[f] == 3:
|
|
||||||
flex_faceadr.append(flex_faceadr[-1] + mjm.flex_shellnum[f])
|
|
||||||
|
|
||||||
nface = int(flex_faceadr[-1])
|
if dim == 2:
|
||||||
flex_faceadr = flex_faceadr[:-1]
|
nface = 2 * nelem + 2 * nshell
|
||||||
|
else:
|
||||||
|
nface = nshell
|
||||||
|
|
||||||
face_point = wp.empty(nface * 3 * nworld, dtype=wp.vec3)
|
face_point = wp.empty(nface * 3 * nworld, dtype=wp.vec3)
|
||||||
face_index = wp.empty(nface * 3 * nworld, dtype=wp.int32)
|
face_index = wp.empty(nface * 3 * nworld, dtype=wp.int32)
|
||||||
@@ -883,8 +1001,8 @@ def build_flex_bvh(
|
|||||||
|
|
||||||
wp.launch(
|
wp.launch(
|
||||||
kernel=accumulate_flex_vertex_normals,
|
kernel=accumulate_flex_vertex_normals,
|
||||||
dim=(nworld, nflexelemdata // 3),
|
dim=(nworld, mjm.nflexelem),
|
||||||
inputs=[flex_elem, flexvert_xpos],
|
inputs=[mjm.nflex, flex_dim, flex_vertadr, flex_elemadr, flex_elemnum, flex_elemdataadr, flex_elem, flexvert_xpos],
|
||||||
outputs=[flexvert_norm],
|
outputs=[flexvert_norm],
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -894,13 +1012,9 @@ def build_flex_bvh(
|
|||||||
inputs=[flexvert_norm],
|
inputs=[flexvert_norm],
|
||||||
)
|
)
|
||||||
|
|
||||||
for f in range(nflex):
|
elem_adr = mjm.flex_elemdataadr[flex_id]
|
||||||
dim = mjm.flex_dim[f]
|
shell_adr = mjm.flex_shelldataadr[flex_id]
|
||||||
elem_adr = mjm.flex_elemdataadr[f]
|
vert_adr = mjm.flex_vertadr[flex_id]
|
||||||
nelem = mjm.flex_elemnum[f]
|
|
||||||
shell_adr = mjm.flex_shelldataadr[f]
|
|
||||||
nshell = mjm.flex_shellnum[f]
|
|
||||||
vert_adr = mjm.flex_vertadr[f]
|
|
||||||
|
|
||||||
if dim == 2:
|
if dim == 2:
|
||||||
wp.launch(
|
wp.launch(
|
||||||
@@ -912,8 +1026,8 @@ def build_flex_bvh(
|
|||||||
flexvert_norm,
|
flexvert_norm,
|
||||||
elem_adr,
|
elem_adr,
|
||||||
vert_adr,
|
vert_adr,
|
||||||
flex_faceadr[f],
|
0, # face_offset
|
||||||
mjm.flex_radius[f],
|
mjm.flex_radius[flex_id],
|
||||||
nface,
|
nface,
|
||||||
],
|
],
|
||||||
outputs=[face_point, face_index, group],
|
outputs=[face_point, face_index, group],
|
||||||
@@ -923,13 +1037,13 @@ def build_flex_bvh(
|
|||||||
kernel=_build_flex_2d_sides,
|
kernel=_build_flex_2d_sides,
|
||||||
dim=(nworld, nshell),
|
dim=(nworld, nshell),
|
||||||
inputs=[
|
inputs=[
|
||||||
|
flex_shell,
|
||||||
flexvert_xpos,
|
flexvert_xpos,
|
||||||
flexvert_norm,
|
flexvert_norm,
|
||||||
flex_shell,
|
|
||||||
shell_adr,
|
shell_adr,
|
||||||
vert_adr,
|
vert_adr,
|
||||||
flex_faceadr[f] + 2 * nelem,
|
2 * nelem, # face_offset
|
||||||
mjm.flex_radius[f],
|
mjm.flex_radius[flex_id],
|
||||||
nface,
|
nface,
|
||||||
],
|
],
|
||||||
outputs=[face_point, face_index, group],
|
outputs=[face_point, face_index, group],
|
||||||
@@ -939,11 +1053,11 @@ def build_flex_bvh(
|
|||||||
kernel=_build_flex_3d_shells,
|
kernel=_build_flex_3d_shells,
|
||||||
dim=(nworld, nshell),
|
dim=(nworld, nshell),
|
||||||
inputs=[
|
inputs=[
|
||||||
flexvert_xpos,
|
|
||||||
flex_shell,
|
flex_shell,
|
||||||
|
flexvert_xpos,
|
||||||
shell_adr,
|
shell_adr,
|
||||||
vert_adr,
|
vert_adr,
|
||||||
flex_faceadr[f],
|
0, # face_offset
|
||||||
nface,
|
nface,
|
||||||
],
|
],
|
||||||
outputs=[face_point, face_index, group],
|
outputs=[face_point, face_index, group],
|
||||||
@@ -965,24 +1079,23 @@ def build_flex_bvh(
|
|||||||
outputs=[group_root],
|
outputs=[group_root],
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return flex_mesh, group_root
|
||||||
flex_mesh,
|
|
||||||
face_point,
|
|
||||||
group_root,
|
|
||||||
flex_shell,
|
|
||||||
flex_faceadr,
|
|
||||||
nface,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def refit_flex_bvh(m: Model, d: Data, rc: RenderContext):
|
def refit_flex_bvh(m: Model, d: Data, rc: RenderContext):
|
||||||
"""Refit the flex BVH."""
|
"""Refit per-flex BVHs."""
|
||||||
flexvert_norm = wp.zeros(d.flexvert_xpos.shape, dtype=wp.vec3)
|
flexvert_norm = wp.zeros(d.flexvert_xpos.shape, dtype=wp.vec3)
|
||||||
|
|
||||||
wp.launch(
|
wp.launch(
|
||||||
kernel=accumulate_flex_vertex_normals,
|
kernel=accumulate_flex_vertex_normals,
|
||||||
dim=(d.nworld, m.nflexelemdata // 3),
|
dim=(d.nworld, m.nflexelem),
|
||||||
inputs=[
|
inputs=[
|
||||||
|
m.nflex,
|
||||||
|
m.flex_dim,
|
||||||
|
m.flex_vertadr,
|
||||||
|
m.flex_elemadr,
|
||||||
|
m.flex_elemnum,
|
||||||
|
m.flex_elemdataadr,
|
||||||
m.flex_elem,
|
m.flex_elem,
|
||||||
d.flexvert_xpos,
|
d.flexvert_xpos,
|
||||||
],
|
],
|
||||||
@@ -991,32 +1104,49 @@ def refit_flex_bvh(m: Model, d: Data, rc: RenderContext):
|
|||||||
|
|
||||||
wp.launch(
|
wp.launch(
|
||||||
kernel=normalize_vertex_normals,
|
kernel=normalize_vertex_normals,
|
||||||
dim=(d.nworld, m.nflexvert),
|
dim=(d.nworld, d.flexvert_xpos.shape[1]),
|
||||||
inputs=[flexvert_norm],
|
inputs=[flexvert_norm],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
for i in range(m.nflex):
|
||||||
|
if rc.flex_dim_np[i] == 1:
|
||||||
|
continue
|
||||||
|
mesh = rc.flex_mesh_registry[i]
|
||||||
|
nface = mesh.points.shape[0] // (3 * d.nworld)
|
||||||
|
|
||||||
|
if rc.flex_dim_np[i] == 2:
|
||||||
wp.launch(
|
wp.launch(
|
||||||
kernel=_update_flex_face_points,
|
kernel=_update_flex_2d_face_points,
|
||||||
dim=(d.nworld, rc.flex_nwork),
|
dim=(d.nworld, nface // 2),
|
||||||
inputs=[
|
inputs=[
|
||||||
m.nflex,
|
|
||||||
m.flex_dim,
|
|
||||||
m.flex_vertadr,
|
m.flex_vertadr,
|
||||||
m.flex_elemnum,
|
m.flex_elemnum,
|
||||||
|
m.flex_elemdataadr,
|
||||||
|
m.flex_shelldataadr,
|
||||||
m.flex_elem,
|
m.flex_elem,
|
||||||
|
m.flex_shell,
|
||||||
|
m.flex_radius,
|
||||||
d.flexvert_xpos,
|
d.flexvert_xpos,
|
||||||
rc.flex_shell,
|
|
||||||
flexvert_norm,
|
flexvert_norm,
|
||||||
rc.flex_elemdataadr,
|
i,
|
||||||
rc.flex_shelldataadr,
|
nface,
|
||||||
rc.flex_faceadr,
|
|
||||||
rc.flex_radius,
|
|
||||||
rc.flex_workadr,
|
|
||||||
rc.flex_worknum,
|
|
||||||
rc.flex_nface,
|
|
||||||
rc.flex_render_smooth,
|
rc.flex_render_smooth,
|
||||||
],
|
],
|
||||||
outputs=[rc.flex_face_point],
|
outputs=[mesh.points],
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
wp.launch(
|
||||||
|
kernel=_update_flex_3d_face_points,
|
||||||
|
dim=(d.nworld, nface),
|
||||||
|
inputs=[
|
||||||
|
m.flex_vertadr,
|
||||||
|
m.flex_shelldataadr,
|
||||||
|
m.flex_shell,
|
||||||
|
d.flexvert_xpos,
|
||||||
|
i,
|
||||||
|
nface,
|
||||||
|
],
|
||||||
|
outputs=[mesh.points],
|
||||||
)
|
)
|
||||||
|
|
||||||
rc.flex_mesh.refit()
|
mesh.refit()
|
||||||
|
|||||||
@@ -15,34 +15,35 @@
|
|||||||
|
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
|
import warp as wp
|
||||||
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import CollisionContext
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import CollisionContext
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import contact_params
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import Geom
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import Geom
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import contact_params
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import geom_collision_pair
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import geom_collision_pair
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import write_contact
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import write_contact
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_gjk import ccd
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_gjk import ccd
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_gjk import multicontact
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_gjk import multicontact
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_gjk import support
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_gjk import support
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_primitive import contact_params
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_primitive import Geom
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_primitive import Geom
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_primitive import contact_params
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_primitive import geom_collision_pair
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_primitive import geom_collision_pair
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_primitive import write_contact
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_primitive import write_contact
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.math import make_frame
|
from mujoco.mjx.third_party.mujoco_warp._src.math import make_frame
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.math import upper_trid_index
|
from mujoco.mjx.third_party.mujoco_warp._src.math import upper_trid_index
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import Data
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import EnableBit
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import GeomType
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import mat43
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import mat63
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MAX_EPAFACES
|
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MAX_EPAFACES
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MAX_EPAHORIZON
|
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MAX_EPAHORIZON
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MAXCONPAIR
|
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MAXCONPAIR
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MAXVAL
|
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MAXVAL
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import Data
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import EnableBit
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import GeomType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import Model
|
from mujoco.mjx.third_party.mujoco_warp._src.types import Model
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import mat43
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import mat63
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import vec5
|
from mujoco.mjx.third_party.mujoco_warp._src.types import vec5
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import cache_kernel
|
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import cache_kernel
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import event_scope
|
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import event_scope
|
||||||
import warp as wp
|
|
||||||
|
|
||||||
# TODO(team): improve compile time to enable backward pass
|
# TODO(team): improve compile time to enable backward pass
|
||||||
wp.set_module_options({"enable_backward": False})
|
wp.set_module_options({"enable_backward": False})
|
||||||
@@ -233,6 +234,7 @@ def ccd_hfield_kernel_builder(
|
|||||||
contact_solimp_out: wp.array(dtype=vec5),
|
contact_solimp_out: wp.array(dtype=vec5),
|
||||||
contact_dim_out: wp.array(dtype=int),
|
contact_dim_out: wp.array(dtype=int),
|
||||||
contact_geom_out: wp.array(dtype=wp.vec2i),
|
contact_geom_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_efc_address_out: wp.array2d(dtype=int),
|
||||||
contact_worldid_out: wp.array(dtype=int),
|
contact_worldid_out: wp.array(dtype=int),
|
||||||
contact_type_out: wp.array(dtype=int),
|
contact_type_out: wp.array(dtype=int),
|
||||||
contact_geomcollisionid_out: wp.array(dtype=int),
|
contact_geomcollisionid_out: wp.array(dtype=int),
|
||||||
@@ -516,6 +518,7 @@ def ccd_hfield_kernel_builder(
|
|||||||
contact_solimp_out,
|
contact_solimp_out,
|
||||||
contact_dim_out,
|
contact_dim_out,
|
||||||
contact_geom_out,
|
contact_geom_out,
|
||||||
|
contact_efc_address_out,
|
||||||
contact_worldid_out,
|
contact_worldid_out,
|
||||||
contact_type_out,
|
contact_type_out,
|
||||||
contact_geomcollisionid_out,
|
contact_geomcollisionid_out,
|
||||||
@@ -572,6 +575,7 @@ def ccd_hfield_kernel_builder(
|
|||||||
contact_solimp_out,
|
contact_solimp_out,
|
||||||
contact_dim_out,
|
contact_dim_out,
|
||||||
contact_geom_out,
|
contact_geom_out,
|
||||||
|
contact_efc_address_out,
|
||||||
contact_worldid_out,
|
contact_worldid_out,
|
||||||
contact_type_out,
|
contact_type_out,
|
||||||
contact_geomcollisionid_out,
|
contact_geomcollisionid_out,
|
||||||
@@ -626,6 +630,7 @@ def ccd_hfield_kernel_builder(
|
|||||||
contact_solimp_out,
|
contact_solimp_out,
|
||||||
contact_dim_out,
|
contact_dim_out,
|
||||||
contact_geom_out,
|
contact_geom_out,
|
||||||
|
contact_efc_address_out,
|
||||||
contact_worldid_out,
|
contact_worldid_out,
|
||||||
contact_type_out,
|
contact_type_out,
|
||||||
contact_geomcollisionid_out,
|
contact_geomcollisionid_out,
|
||||||
@@ -681,6 +686,7 @@ def ccd_hfield_kernel_builder(
|
|||||||
contact_solimp_out,
|
contact_solimp_out,
|
||||||
contact_dim_out,
|
contact_dim_out,
|
||||||
contact_geom_out,
|
contact_geom_out,
|
||||||
|
contact_efc_address_out,
|
||||||
contact_worldid_out,
|
contact_worldid_out,
|
||||||
contact_type_out,
|
contact_type_out,
|
||||||
contact_geomcollisionid_out,
|
contact_geomcollisionid_out,
|
||||||
@@ -751,6 +757,7 @@ def ccd_kernel_builder(
|
|||||||
contact_solimp_out: wp.array(dtype=vec5),
|
contact_solimp_out: wp.array(dtype=vec5),
|
||||||
contact_dim_out: wp.array(dtype=int),
|
contact_dim_out: wp.array(dtype=int),
|
||||||
contact_geom_out: wp.array(dtype=wp.vec2i),
|
contact_geom_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_efc_address_out: wp.array2d(dtype=int),
|
||||||
contact_worldid_out: wp.array(dtype=int),
|
contact_worldid_out: wp.array(dtype=int),
|
||||||
contact_type_out: wp.array(dtype=int),
|
contact_type_out: wp.array(dtype=int),
|
||||||
contact_geomcollisionid_out: wp.array(dtype=int),
|
contact_geomcollisionid_out: wp.array(dtype=int),
|
||||||
@@ -871,6 +878,7 @@ def ccd_kernel_builder(
|
|||||||
contact_solimp_out,
|
contact_solimp_out,
|
||||||
contact_dim_out,
|
contact_dim_out,
|
||||||
contact_geom_out,
|
contact_geom_out,
|
||||||
|
contact_efc_address_out,
|
||||||
contact_worldid_out,
|
contact_worldid_out,
|
||||||
contact_type_out,
|
contact_type_out,
|
||||||
contact_geomcollisionid_out,
|
contact_geomcollisionid_out,
|
||||||
@@ -956,6 +964,7 @@ def ccd_kernel_builder(
|
|||||||
contact_solimp_out: wp.array(dtype=vec5),
|
contact_solimp_out: wp.array(dtype=vec5),
|
||||||
contact_dim_out: wp.array(dtype=int),
|
contact_dim_out: wp.array(dtype=int),
|
||||||
contact_geom_out: wp.array(dtype=wp.vec2i),
|
contact_geom_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_efc_address_out: wp.array2d(dtype=int),
|
||||||
contact_worldid_out: wp.array(dtype=int),
|
contact_worldid_out: wp.array(dtype=int),
|
||||||
contact_type_out: wp.array(dtype=int),
|
contact_type_out: wp.array(dtype=int),
|
||||||
contact_geomcollisionid_out: wp.array(dtype=int),
|
contact_geomcollisionid_out: wp.array(dtype=int),
|
||||||
@@ -1070,6 +1079,7 @@ def ccd_kernel_builder(
|
|||||||
contact_solimp_out,
|
contact_solimp_out,
|
||||||
contact_dim_out,
|
contact_dim_out,
|
||||||
contact_geom_out,
|
contact_geom_out,
|
||||||
|
contact_efc_address_out,
|
||||||
contact_worldid_out,
|
contact_worldid_out,
|
||||||
contact_type_out,
|
contact_type_out,
|
||||||
contact_geomcollisionid_out,
|
contact_geomcollisionid_out,
|
||||||
@@ -1156,6 +1166,7 @@ def convex_narrowphase(m: Model, d: Data, ctx: CollisionContext, collision_table
|
|||||||
d.contact.solimp,
|
d.contact.solimp,
|
||||||
d.contact.dim,
|
d.contact.dim,
|
||||||
d.contact.geom,
|
d.contact.geom,
|
||||||
|
d.contact.efc_address,
|
||||||
d.contact.worldid,
|
d.contact.worldid,
|
||||||
d.contact.type,
|
d.contact.type,
|
||||||
d.contact.geomcollisionid,
|
d.contact.geomcollisionid,
|
||||||
|
|||||||
+12
-21
@@ -18,14 +18,15 @@
|
|||||||
import dataclasses
|
import dataclasses
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
|
import warp as wp
|
||||||
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.math import safe_div
|
from mujoco.mjx.third_party.mujoco_warp._src.math import safe_div
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MINMU
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MINVAL
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import ContactType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import ContactType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import GeomType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import GeomType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import mat63
|
from mujoco.mjx.third_party.mujoco_warp._src.types import mat63
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MINMU
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MINVAL
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import vec5
|
from mujoco.mjx.third_party.mujoco_warp._src.types import vec5
|
||||||
import warp as wp
|
|
||||||
|
|
||||||
wp.set_module_options({"enable_backward": False})
|
wp.set_module_options({"enable_backward": False})
|
||||||
|
|
||||||
@@ -183,6 +184,7 @@ def write_contact(
|
|||||||
contact_solimp_out: wp.array(dtype=vec5),
|
contact_solimp_out: wp.array(dtype=vec5),
|
||||||
contact_dim_out: wp.array(dtype=int),
|
contact_dim_out: wp.array(dtype=int),
|
||||||
contact_geom_out: wp.array(dtype=wp.vec2i),
|
contact_geom_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_efc_address_out: wp.array2d(dtype=int),
|
||||||
contact_worldid_out: wp.array(dtype=int),
|
contact_worldid_out: wp.array(dtype=int),
|
||||||
contact_type_out: wp.array(dtype=int),
|
contact_type_out: wp.array(dtype=int),
|
||||||
contact_geomcollisionid_out: wp.array(dtype=int),
|
contact_geomcollisionid_out: wp.array(dtype=int),
|
||||||
@@ -222,6 +224,8 @@ def write_contact(
|
|||||||
contact_solimp_out[cid] = solimp_in
|
contact_solimp_out[cid] = solimp_in
|
||||||
contact_type_out[cid] = contact_type
|
contact_type_out[cid] = contact_type
|
||||||
contact_geomcollisionid_out[cid] = id_
|
contact_geomcollisionid_out[cid] = id_
|
||||||
|
for i in range(contact_efc_address_out.shape[1]):
|
||||||
|
contact_efc_address_out[cid, i] = -1
|
||||||
return int(active)
|
return int(active)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@@ -267,9 +271,7 @@ def contact_params(
|
|||||||
condim = pair_dim[pairid]
|
condim = pair_dim[pairid]
|
||||||
friction = pair_friction[worldid % pair_friction.shape[0], pairid]
|
friction = pair_friction[worldid % pair_friction.shape[0], pairid]
|
||||||
solref = pair_solref[worldid % pair_solref.shape[0], pairid]
|
solref = pair_solref[worldid % pair_solref.shape[0], pairid]
|
||||||
solreffriction = pair_solreffriction[
|
solreffriction = pair_solreffriction[worldid % pair_solreffriction.shape[0], pairid]
|
||||||
worldid % pair_solreffriction.shape[0], pairid
|
|
||||||
]
|
|
||||||
solimp = pair_solimp[worldid % pair_solimp.shape[0], pairid]
|
solimp = pair_solimp[worldid % pair_solimp.shape[0], pairid]
|
||||||
else:
|
else:
|
||||||
g1 = geoms[0]
|
g1 = geoms[0]
|
||||||
@@ -305,9 +307,7 @@ def contact_params(
|
|||||||
mix = wp.where((solmix1 < MJ_MINVAL) and (solmix2 >= MJ_MINVAL), 0.0, mix)
|
mix = wp.where((solmix1 < MJ_MINVAL) and (solmix2 >= MJ_MINVAL), 0.0, mix)
|
||||||
mix = wp.where((solmix1 >= MJ_MINVAL) and (solmix2 < MJ_MINVAL), 1.0, mix)
|
mix = wp.where((solmix1 >= MJ_MINVAL) and (solmix2 < MJ_MINVAL), 1.0, mix)
|
||||||
condim = wp.max(condim1, condim2)
|
condim = wp.max(condim1, condim2)
|
||||||
max_geom_friction = wp.max(
|
max_geom_friction = wp.max(geom_friction[friction_id, g1], geom_friction[friction_id, g2])
|
||||||
geom_friction[friction_id, g1], geom_friction[friction_id, g2]
|
|
||||||
)
|
|
||||||
|
|
||||||
friction = vec5(
|
friction = vec5(
|
||||||
max_geom_friction[0],
|
max_geom_friction[0],
|
||||||
@@ -317,22 +317,13 @@ def contact_params(
|
|||||||
max_geom_friction[2],
|
max_geom_friction[2],
|
||||||
)
|
)
|
||||||
|
|
||||||
if (
|
if geom_solref[solref_id, g1][0] > 0.0 and geom_solref[solref_id, g2][0] > 0.0:
|
||||||
geom_solref[solref_id, g1][0] > 0.0
|
solref = mix * geom_solref[solref_id, g1] + (1.0 - mix) * geom_solref[solref_id, g2]
|
||||||
and geom_solref[solref_id, g2][0] > 0.0
|
|
||||||
):
|
|
||||||
solref = (
|
|
||||||
mix * geom_solref[solref_id, g1]
|
|
||||||
+ (1.0 - mix) * geom_solref[solref_id, g2]
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
solref = wp.min(geom_solref[solref_id, g1], geom_solref[solref_id, g2])
|
solref = wp.min(geom_solref[solref_id, g1], geom_solref[solref_id, g2])
|
||||||
|
|
||||||
solreffriction = wp.vec2(0.0, 0.0)
|
solreffriction = wp.vec2(0.0, 0.0)
|
||||||
solimp = (
|
solimp = mix * geom_solimp[solimp_id, g1] + (1.0 - mix) * geom_solimp[solimp_id, g2]
|
||||||
mix * geom_solimp[solimp_id, g1]
|
|
||||||
+ (1.0 - mix) * geom_solimp[solimp_id, g2]
|
|
||||||
)
|
|
||||||
# geom priority is ignored
|
# geom priority is ignored
|
||||||
margin = geom_margin[margin_id, g1] + geom_margin[margin_id, g2]
|
margin = geom_margin[margin_id, g1] + geom_margin[margin_id, g2]
|
||||||
gap = geom_gap[gap_id, g1] + geom_gap[gap_id, g2]
|
gap = geom_gap[gap_id, g1] + geom_gap[gap_id, g2]
|
||||||
|
|||||||
+12
-19
@@ -15,25 +15,27 @@
|
|||||||
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
import warp as wp
|
||||||
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_convex import convex_narrowphase
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_convex import convex_narrowphase
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import CollisionContext
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import CollisionContext
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import create_collision_context
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import create_collision_context
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_flex import flex_narrowphase
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_primitive import primitive_narrowphase
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_primitive import primitive_narrowphase
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_sdf import sdf_narrowphase
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_sdf import sdf_narrowphase
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.math import upper_tri_index
|
from mujoco.mjx.third_party.mujoco_warp._src.math import upper_tri_index
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MAXVAL
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import BroadphaseFilter
|
from mujoco.mjx.third_party.mujoco_warp._src.types import BroadphaseFilter
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import BroadphaseType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import BroadphaseType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import CollisionType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import CollisionType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import Data
|
from mujoco.mjx.third_party.mujoco_warp._src.types import Data
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import DisableBit
|
from mujoco.mjx.third_party.mujoco_warp._src.types import DisableBit
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import GeomType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import GeomType
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import Model
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import mat23
|
from mujoco.mjx.third_party.mujoco_warp._src.types import mat23
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import mat63
|
from mujoco.mjx.third_party.mujoco_warp._src.types import mat63
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MAXVAL
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import Model
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import cache_kernel
|
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import cache_kernel
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import event_scope
|
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import event_scope
|
||||||
import warp as wp
|
|
||||||
|
|
||||||
wp.set_module_options({"enable_backward": False})
|
wp.set_module_options({"enable_backward": False})
|
||||||
|
|
||||||
@@ -290,25 +292,13 @@ def _broadphase_filter(opt_broadphase_filter: int, ngeom_aabb: int, ngeom_rbound
|
|||||||
# 8: obb
|
# 8: obb
|
||||||
|
|
||||||
aabb_id = worldid % ngeom_aabb if wp.static(ngeom_aabb > 1) else 0
|
aabb_id = worldid % ngeom_aabb if wp.static(ngeom_aabb > 1) else 0
|
||||||
center1, center2 = (
|
center1, center2 = geom_aabb[aabb_id, geom1, 0], geom_aabb[aabb_id, geom2, 0] # kernel_analyzer: ignore
|
||||||
geom_aabb[aabb_id, geom1, 0],
|
size1, size2 = geom_aabb[aabb_id, geom1, 1], geom_aabb[aabb_id, geom2, 1] # kernel_analyzer: ignore
|
||||||
geom_aabb[aabb_id, geom2, 0],
|
|
||||||
) # kernel_analyzer: ignore
|
|
||||||
size1, size2 = (
|
|
||||||
geom_aabb[aabb_id, geom1, 1],
|
|
||||||
geom_aabb[aabb_id, geom2, 1],
|
|
||||||
) # kernel_analyzer: ignore
|
|
||||||
|
|
||||||
rbound_id = worldid % ngeom_rbound if wp.static(ngeom_rbound > 1) else 0
|
rbound_id = worldid % ngeom_rbound if wp.static(ngeom_rbound > 1) else 0
|
||||||
rbound1, rbound2 = (
|
rbound1, rbound2 = geom_rbound[rbound_id, geom1], geom_rbound[rbound_id, geom2] # kernel_analyzer: ignore
|
||||||
geom_rbound[rbound_id, geom1],
|
|
||||||
geom_rbound[rbound_id, geom2],
|
|
||||||
) # kernel_analyzer: ignore
|
|
||||||
margin_id = worldid % ngeom_margin if wp.static(ngeom_margin > 1) else 0
|
margin_id = worldid % ngeom_margin if wp.static(ngeom_margin > 1) else 0
|
||||||
margin1, margin2 = (
|
margin1, margin2 = geom_margin[margin_id, geom1], geom_margin[margin_id, geom2] # kernel_analyzer: ignore
|
||||||
geom_margin[margin_id, geom1],
|
|
||||||
geom_margin[margin_id, geom2],
|
|
||||||
) # kernel_analyzer: ignore
|
|
||||||
xpos1, xpos2 = geom_xpos_in[worldid, geom1], geom_xpos_in[worldid, geom2]
|
xpos1, xpos2 = geom_xpos_in[worldid, geom1], geom_xpos_in[worldid, geom2]
|
||||||
xmat1, xmat2 = geom_xmat_in[worldid, geom1], geom_xmat_in[worldid, geom2]
|
xmat1, xmat2 = geom_xmat_in[worldid, geom1], geom_xmat_in[worldid, geom2]
|
||||||
|
|
||||||
@@ -757,6 +747,9 @@ def _narrowphase(m: Model, d: Data, ctx: CollisionContext):
|
|||||||
if m.has_sdf_geom:
|
if m.has_sdf_geom:
|
||||||
sdf_narrowphase(m, d, ctx)
|
sdf_narrowphase(m, d, ctx)
|
||||||
|
|
||||||
|
if m.nflex > 0:
|
||||||
|
flex_narrowphase(m, d)
|
||||||
|
|
||||||
|
|
||||||
@event_scope
|
@event_scope
|
||||||
def collision(m: Model, d: Data):
|
def collision(m: Model, d: Data):
|
||||||
|
|||||||
@@ -0,0 +1,834 @@
|
|||||||
|
# Copyright 2026 The Newton Developers
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
"""Flex collision detection (geom vs flex triangles)."""
|
||||||
|
|
||||||
|
import warp as wp
|
||||||
|
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src import collision_primitive_core
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.math import make_frame
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MAXVAL
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MINMU
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import Data
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import GeomType
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import Model
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import vec5
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import event_scope
|
||||||
|
|
||||||
|
wp.set_module_options({"enable_backward": False})
|
||||||
|
|
||||||
|
|
||||||
|
@wp.func
|
||||||
|
def _write_flex_contact(
|
||||||
|
# Data in:
|
||||||
|
naconmax_in: int,
|
||||||
|
# In:
|
||||||
|
dist: float,
|
||||||
|
pos: wp.vec3,
|
||||||
|
frame: wp.mat33,
|
||||||
|
margin: float,
|
||||||
|
condim: int,
|
||||||
|
friction: vec5,
|
||||||
|
solref: wp.vec2,
|
||||||
|
solimp: vec5,
|
||||||
|
geom: int,
|
||||||
|
flexid: int,
|
||||||
|
vertid: int,
|
||||||
|
worldid: int,
|
||||||
|
# Data out:
|
||||||
|
contact_dist_out: wp.array(dtype=float),
|
||||||
|
contact_pos_out: wp.array(dtype=wp.vec3),
|
||||||
|
contact_frame_out: wp.array(dtype=wp.mat33),
|
||||||
|
contact_includemargin_out: wp.array(dtype=float),
|
||||||
|
contact_friction_out: wp.array(dtype=vec5),
|
||||||
|
contact_solref_out: wp.array(dtype=wp.vec2),
|
||||||
|
contact_solreffriction_out: wp.array(dtype=wp.vec2),
|
||||||
|
contact_solimp_out: wp.array(dtype=vec5),
|
||||||
|
contact_dim_out: wp.array(dtype=int),
|
||||||
|
contact_geom_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_flex_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_vert_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_worldid_out: wp.array(dtype=int),
|
||||||
|
contact_type_out: wp.array(dtype=int),
|
||||||
|
contact_geomcollisionid_out: wp.array(dtype=int),
|
||||||
|
nacon_out: wp.array(dtype=int),
|
||||||
|
):
|
||||||
|
if dist >= margin or dist >= MJ_MAXVAL:
|
||||||
|
return
|
||||||
|
|
||||||
|
id_ = wp.atomic_add(nacon_out, 0, 1)
|
||||||
|
if id_ >= naconmax_in:
|
||||||
|
return
|
||||||
|
|
||||||
|
contact_dist_out[id_] = dist
|
||||||
|
contact_pos_out[id_] = pos
|
||||||
|
contact_frame_out[id_] = frame
|
||||||
|
contact_includemargin_out[id_] = margin
|
||||||
|
contact_friction_out[id_] = friction
|
||||||
|
contact_solref_out[id_] = solref
|
||||||
|
contact_solreffriction_out[id_] = wp.vec2(0.0, 0.0)
|
||||||
|
contact_solimp_out[id_] = solimp
|
||||||
|
contact_dim_out[id_] = condim
|
||||||
|
contact_geom_out[id_] = wp.vec2i(geom, -1)
|
||||||
|
contact_flex_out[id_] = wp.vec2i(-1, flexid)
|
||||||
|
contact_vert_out[id_] = wp.vec2i(-1, vertid)
|
||||||
|
contact_worldid_out[id_] = worldid
|
||||||
|
contact_type_out[id_] = 1
|
||||||
|
contact_geomcollisionid_out[id_] = 0
|
||||||
|
|
||||||
|
|
||||||
|
@wp.func
|
||||||
|
def _collide_geom_triangle(
|
||||||
|
# Data in:
|
||||||
|
naconmax_in: int,
|
||||||
|
# In:
|
||||||
|
gtype: int,
|
||||||
|
pos: wp.vec3,
|
||||||
|
rot: wp.mat33,
|
||||||
|
size_val: wp.vec3,
|
||||||
|
t1: wp.vec3,
|
||||||
|
t2: wp.vec3,
|
||||||
|
t3: wp.vec3,
|
||||||
|
tri_radius: float,
|
||||||
|
margin: float,
|
||||||
|
condim: int,
|
||||||
|
friction: vec5,
|
||||||
|
solref: wp.vec2,
|
||||||
|
solimp: vec5,
|
||||||
|
geomid: int,
|
||||||
|
flexid: int,
|
||||||
|
vertex_id: int,
|
||||||
|
worldid: int,
|
||||||
|
# Data out:
|
||||||
|
contact_dist_out: wp.array(dtype=float),
|
||||||
|
contact_pos_out: wp.array(dtype=wp.vec3),
|
||||||
|
contact_frame_out: wp.array(dtype=wp.mat33),
|
||||||
|
contact_includemargin_out: wp.array(dtype=float),
|
||||||
|
contact_friction_out: wp.array(dtype=vec5),
|
||||||
|
contact_solref_out: wp.array(dtype=wp.vec2),
|
||||||
|
contact_solreffriction_out: wp.array(dtype=wp.vec2),
|
||||||
|
contact_solimp_out: wp.array(dtype=vec5),
|
||||||
|
contact_dim_out: wp.array(dtype=int),
|
||||||
|
contact_geom_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_flex_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_vert_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_worldid_out: wp.array(dtype=int),
|
||||||
|
contact_type_out: wp.array(dtype=int),
|
||||||
|
contact_geomcollisionid_out: wp.array(dtype=int),
|
||||||
|
nacon_out: wp.array(dtype=int),
|
||||||
|
):
|
||||||
|
if gtype == int(GeomType.SPHERE):
|
||||||
|
sphere_radius = size_val[0]
|
||||||
|
dist, contact_pos, nrm = collision_primitive_core.sphere_triangle(pos, sphere_radius, t1, t2, t3, tri_radius)
|
||||||
|
if dist < margin:
|
||||||
|
_write_flex_contact(
|
||||||
|
naconmax_in,
|
||||||
|
dist,
|
||||||
|
contact_pos,
|
||||||
|
make_frame(nrm),
|
||||||
|
margin,
|
||||||
|
condim,
|
||||||
|
friction,
|
||||||
|
solref,
|
||||||
|
solimp,
|
||||||
|
geomid,
|
||||||
|
flexid,
|
||||||
|
vertex_id,
|
||||||
|
worldid,
|
||||||
|
contact_dist_out,
|
||||||
|
contact_pos_out,
|
||||||
|
contact_frame_out,
|
||||||
|
contact_includemargin_out,
|
||||||
|
contact_friction_out,
|
||||||
|
contact_solref_out,
|
||||||
|
contact_solreffriction_out,
|
||||||
|
contact_solimp_out,
|
||||||
|
contact_dim_out,
|
||||||
|
contact_geom_out,
|
||||||
|
contact_flex_out,
|
||||||
|
contact_vert_out,
|
||||||
|
contact_worldid_out,
|
||||||
|
contact_type_out,
|
||||||
|
contact_geomcollisionid_out,
|
||||||
|
nacon_out,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Capsule, box, cylinder all return up to 2 contacts - compute then share writing code
|
||||||
|
dists = wp.vec2(collision_primitive_core.MJ_MAXVAL, collision_primitive_core.MJ_MAXVAL)
|
||||||
|
poss = collision_primitive_core.mat23f(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
|
||||||
|
nrms = collision_primitive_core.mat23f(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
|
||||||
|
|
||||||
|
if gtype == int(GeomType.CAPSULE):
|
||||||
|
cap_radius = size_val[0]
|
||||||
|
cap_half_len = size_val[1]
|
||||||
|
cap_axis = wp.vec3(rot[0, 2], rot[1, 2], rot[2, 2])
|
||||||
|
dists, poss, nrms = collision_primitive_core.capsule_triangle(
|
||||||
|
pos, cap_axis, cap_radius, cap_half_len, t1, t2, t3, tri_radius
|
||||||
|
)
|
||||||
|
elif gtype == int(GeomType.BOX):
|
||||||
|
dists, poss, nrms = collision_primitive_core.box_triangle(pos, rot, size_val, t1, t2, t3, tri_radius)
|
||||||
|
elif gtype == int(GeomType.CYLINDER):
|
||||||
|
cyl_radius = size_val[0]
|
||||||
|
cyl_half_height = size_val[1]
|
||||||
|
cyl_axis = wp.vec3(rot[0, 2], rot[1, 2], rot[2, 2])
|
||||||
|
dists, poss, nrms = collision_primitive_core.cylinder_triangle(
|
||||||
|
pos, cyl_axis, cyl_radius, cyl_half_height, t1, t2, t3, tri_radius
|
||||||
|
)
|
||||||
|
|
||||||
|
# Write up to 2 contacts (shared code for capsule/box/cylinder)
|
||||||
|
if dists[0] < margin:
|
||||||
|
p1 = wp.vec3(poss[0, 0], poss[0, 1], poss[0, 2])
|
||||||
|
n1 = wp.vec3(nrms[0, 0], nrms[0, 1], nrms[0, 2])
|
||||||
|
_write_flex_contact(
|
||||||
|
naconmax_in,
|
||||||
|
dists[0],
|
||||||
|
p1,
|
||||||
|
make_frame(n1),
|
||||||
|
margin,
|
||||||
|
condim,
|
||||||
|
friction,
|
||||||
|
solref,
|
||||||
|
solimp,
|
||||||
|
geomid,
|
||||||
|
flexid,
|
||||||
|
vertex_id,
|
||||||
|
worldid,
|
||||||
|
contact_dist_out,
|
||||||
|
contact_pos_out,
|
||||||
|
contact_frame_out,
|
||||||
|
contact_includemargin_out,
|
||||||
|
contact_friction_out,
|
||||||
|
contact_solref_out,
|
||||||
|
contact_solreffriction_out,
|
||||||
|
contact_solimp_out,
|
||||||
|
contact_dim_out,
|
||||||
|
contact_geom_out,
|
||||||
|
contact_flex_out,
|
||||||
|
contact_vert_out,
|
||||||
|
contact_worldid_out,
|
||||||
|
contact_type_out,
|
||||||
|
contact_geomcollisionid_out,
|
||||||
|
nacon_out,
|
||||||
|
)
|
||||||
|
if dists[1] < margin:
|
||||||
|
p2 = wp.vec3(poss[1, 0], poss[1, 1], poss[1, 2])
|
||||||
|
n2 = wp.vec3(nrms[1, 0], nrms[1, 1], nrms[1, 2])
|
||||||
|
_write_flex_contact(
|
||||||
|
naconmax_in,
|
||||||
|
dists[1],
|
||||||
|
p2,
|
||||||
|
make_frame(n2),
|
||||||
|
margin,
|
||||||
|
condim,
|
||||||
|
friction,
|
||||||
|
solref,
|
||||||
|
solimp,
|
||||||
|
geomid,
|
||||||
|
flexid,
|
||||||
|
vertex_id,
|
||||||
|
worldid,
|
||||||
|
contact_dist_out,
|
||||||
|
contact_pos_out,
|
||||||
|
contact_frame_out,
|
||||||
|
contact_includemargin_out,
|
||||||
|
contact_friction_out,
|
||||||
|
contact_solref_out,
|
||||||
|
contact_solreffriction_out,
|
||||||
|
contact_solimp_out,
|
||||||
|
contact_dim_out,
|
||||||
|
contact_geom_out,
|
||||||
|
contact_flex_out,
|
||||||
|
contact_vert_out,
|
||||||
|
contact_worldid_out,
|
||||||
|
contact_type_out,
|
||||||
|
contact_geomcollisionid_out,
|
||||||
|
nacon_out,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@wp.kernel
|
||||||
|
def _flex_plane_narrowphase(
|
||||||
|
# Model:
|
||||||
|
ngeom: int,
|
||||||
|
nflexvert: int,
|
||||||
|
geom_type: wp.array(dtype=int),
|
||||||
|
geom_condim: wp.array(dtype=int),
|
||||||
|
geom_solref: wp.array2d(dtype=wp.vec2),
|
||||||
|
geom_solimp: wp.array2d(dtype=vec5),
|
||||||
|
geom_friction: wp.array2d(dtype=wp.vec3),
|
||||||
|
geom_margin: wp.array2d(dtype=float),
|
||||||
|
flex_condim: wp.array(dtype=int),
|
||||||
|
flex_friction: wp.array(dtype=wp.vec3),
|
||||||
|
flex_margin: wp.array(dtype=float),
|
||||||
|
flex_vertadr: wp.array(dtype=int),
|
||||||
|
flex_radius: wp.array(dtype=float),
|
||||||
|
flex_vertflexid: wp.array(dtype=int),
|
||||||
|
# Data in:
|
||||||
|
geom_xpos_in: wp.array2d(dtype=wp.vec3),
|
||||||
|
geom_xmat_in: wp.array2d(dtype=wp.mat33),
|
||||||
|
flexvert_xpos_in: wp.array2d(dtype=wp.vec3),
|
||||||
|
nworld_in: int,
|
||||||
|
naconmax_in: int,
|
||||||
|
# Data out:
|
||||||
|
contact_dist_out: wp.array(dtype=float),
|
||||||
|
contact_pos_out: wp.array(dtype=wp.vec3),
|
||||||
|
contact_frame_out: wp.array(dtype=wp.mat33),
|
||||||
|
contact_includemargin_out: wp.array(dtype=float),
|
||||||
|
contact_friction_out: wp.array(dtype=vec5),
|
||||||
|
contact_solref_out: wp.array(dtype=wp.vec2),
|
||||||
|
contact_solreffriction_out: wp.array(dtype=wp.vec2),
|
||||||
|
contact_solimp_out: wp.array(dtype=vec5),
|
||||||
|
contact_dim_out: wp.array(dtype=int),
|
||||||
|
contact_geom_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_flex_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_vert_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_worldid_out: wp.array(dtype=int),
|
||||||
|
contact_type_out: wp.array(dtype=int),
|
||||||
|
contact_geomcollisionid_out: wp.array(dtype=int),
|
||||||
|
nacon_out: wp.array(dtype=int),
|
||||||
|
):
|
||||||
|
worldid, vertid = wp.tid()
|
||||||
|
|
||||||
|
flexid = flex_vertflexid[vertid]
|
||||||
|
radius = flex_radius[flexid]
|
||||||
|
flex_margin_val = flex_margin[flexid]
|
||||||
|
flex_condim_val = flex_condim[flexid]
|
||||||
|
flex_fric = flex_friction[flexid]
|
||||||
|
# Convert global vertid to local vertex index within this flex
|
||||||
|
local_vertid = vertid - flex_vertadr[flexid]
|
||||||
|
|
||||||
|
vert = flexvert_xpos_in[worldid, vertid]
|
||||||
|
|
||||||
|
# TODO: Add a broadphase
|
||||||
|
for geomid in range(ngeom):
|
||||||
|
gtype = geom_type[geomid]
|
||||||
|
if gtype != int(GeomType.PLANE):
|
||||||
|
continue
|
||||||
|
|
||||||
|
plane_pos = geom_xpos_in[worldid, geomid]
|
||||||
|
plane_rot = geom_xmat_in[worldid, geomid]
|
||||||
|
plane_normal = wp.vec3(plane_rot[0, 2], plane_rot[1, 2], plane_rot[2, 2])
|
||||||
|
|
||||||
|
margin = geom_margin[worldid % geom_margin.shape[0], geomid] + flex_margin_val
|
||||||
|
|
||||||
|
diff = vert - plane_pos
|
||||||
|
signed_dist = wp.dot(diff, plane_normal)
|
||||||
|
dist = signed_dist - radius
|
||||||
|
|
||||||
|
if dist < margin:
|
||||||
|
geom_condim_val = geom_condim[geomid]
|
||||||
|
condim = wp.max(geom_condim_val, flex_condim_val)
|
||||||
|
solref = geom_solref[worldid % geom_solref.shape[0], geomid]
|
||||||
|
solimp = geom_solimp[worldid % geom_solimp.shape[0], geomid]
|
||||||
|
geom_fric = geom_friction[worldid % geom_friction.shape[0], geomid]
|
||||||
|
fric0 = wp.max(geom_fric[0], flex_fric[0])
|
||||||
|
fric1 = wp.max(geom_fric[1], flex_fric[1])
|
||||||
|
fric2 = wp.max(geom_fric[2], flex_fric[2])
|
||||||
|
friction = vec5(
|
||||||
|
wp.max(MJ_MINMU, fric0),
|
||||||
|
wp.max(MJ_MINMU, fric0),
|
||||||
|
wp.max(MJ_MINMU, fric1),
|
||||||
|
wp.max(MJ_MINMU, fric2),
|
||||||
|
wp.max(MJ_MINMU, fric2),
|
||||||
|
)
|
||||||
|
|
||||||
|
contact_pos = vert - plane_normal * (dist * 0.5 + radius)
|
||||||
|
_write_flex_contact(
|
||||||
|
naconmax_in,
|
||||||
|
dist,
|
||||||
|
contact_pos,
|
||||||
|
make_frame(plane_normal),
|
||||||
|
margin,
|
||||||
|
condim,
|
||||||
|
friction,
|
||||||
|
solref,
|
||||||
|
solimp,
|
||||||
|
geomid,
|
||||||
|
flexid,
|
||||||
|
local_vertid,
|
||||||
|
worldid,
|
||||||
|
contact_dist_out,
|
||||||
|
contact_pos_out,
|
||||||
|
contact_frame_out,
|
||||||
|
contact_includemargin_out,
|
||||||
|
contact_friction_out,
|
||||||
|
contact_solref_out,
|
||||||
|
contact_solreffriction_out,
|
||||||
|
contact_solimp_out,
|
||||||
|
contact_dim_out,
|
||||||
|
contact_geom_out,
|
||||||
|
contact_flex_out,
|
||||||
|
contact_vert_out,
|
||||||
|
contact_worldid_out,
|
||||||
|
contact_type_out,
|
||||||
|
contact_geomcollisionid_out,
|
||||||
|
nacon_out,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@wp.kernel
|
||||||
|
def _flex_narrowphase_dim2(
|
||||||
|
# Model:
|
||||||
|
ngeom: int,
|
||||||
|
nflex: int,
|
||||||
|
geom_type: wp.array(dtype=int),
|
||||||
|
geom_contype: wp.array(dtype=int),
|
||||||
|
geom_conaffinity: wp.array(dtype=int),
|
||||||
|
geom_condim: wp.array(dtype=int),
|
||||||
|
geom_solref: wp.array2d(dtype=wp.vec2),
|
||||||
|
geom_solimp: wp.array2d(dtype=vec5),
|
||||||
|
geom_size: wp.array2d(dtype=wp.vec3),
|
||||||
|
geom_friction: wp.array2d(dtype=wp.vec3),
|
||||||
|
geom_margin: wp.array2d(dtype=float),
|
||||||
|
flex_contype: wp.array(dtype=int),
|
||||||
|
flex_conaffinity: wp.array(dtype=int),
|
||||||
|
flex_margin: wp.array(dtype=float),
|
||||||
|
flex_dim: wp.array(dtype=int),
|
||||||
|
flex_vertadr: wp.array(dtype=int),
|
||||||
|
flex_elemadr: wp.array(dtype=int),
|
||||||
|
flex_elemnum: wp.array(dtype=int),
|
||||||
|
flex_elemdataadr: wp.array(dtype=int),
|
||||||
|
flex_elem: wp.array(dtype=int),
|
||||||
|
flex_radius: wp.array(dtype=float),
|
||||||
|
# Data in:
|
||||||
|
geom_xpos_in: wp.array2d(dtype=wp.vec3),
|
||||||
|
geom_xmat_in: wp.array2d(dtype=wp.mat33),
|
||||||
|
flexvert_xpos_in: wp.array2d(dtype=wp.vec3),
|
||||||
|
nworld_in: int,
|
||||||
|
naconmax_in: int,
|
||||||
|
# Data out:
|
||||||
|
contact_dist_out: wp.array(dtype=float),
|
||||||
|
contact_pos_out: wp.array(dtype=wp.vec3),
|
||||||
|
contact_frame_out: wp.array(dtype=wp.mat33),
|
||||||
|
contact_includemargin_out: wp.array(dtype=float),
|
||||||
|
contact_friction_out: wp.array(dtype=vec5),
|
||||||
|
contact_solref_out: wp.array(dtype=wp.vec2),
|
||||||
|
contact_solreffriction_out: wp.array(dtype=wp.vec2),
|
||||||
|
contact_solimp_out: wp.array(dtype=vec5),
|
||||||
|
contact_dim_out: wp.array(dtype=int),
|
||||||
|
contact_geom_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_flex_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_vert_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_worldid_out: wp.array(dtype=int),
|
||||||
|
contact_type_out: wp.array(dtype=int),
|
||||||
|
contact_geomcollisionid_out: wp.array(dtype=int),
|
||||||
|
nacon_out: wp.array(dtype=int),
|
||||||
|
):
|
||||||
|
worldid, elemid = wp.tid()
|
||||||
|
|
||||||
|
flexid = int(-1)
|
||||||
|
for i in range(nflex):
|
||||||
|
if flex_dim[i] != 2:
|
||||||
|
continue
|
||||||
|
elem_adr = flex_elemadr[i]
|
||||||
|
elem_num = flex_elemnum[i]
|
||||||
|
if elemid >= elem_adr and elemid < elem_adr + elem_num:
|
||||||
|
flexid = i
|
||||||
|
break
|
||||||
|
|
||||||
|
if flexid < 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
vert_adr = flex_vertadr[flexid]
|
||||||
|
tri_radius = flex_radius[flexid]
|
||||||
|
tri_margin = flex_margin[flexid]
|
||||||
|
|
||||||
|
elem_data_idx = flex_elemdataadr[flexid] + (elemid - flex_elemadr[flexid]) * 3
|
||||||
|
v0_local = flex_elem[elem_data_idx]
|
||||||
|
v1_local = flex_elem[elem_data_idx + 1]
|
||||||
|
v2_local = flex_elem[elem_data_idx + 2]
|
||||||
|
|
||||||
|
t1 = flexvert_xpos_in[worldid, vert_adr + v0_local]
|
||||||
|
t2 = flexvert_xpos_in[worldid, vert_adr + v1_local]
|
||||||
|
t3 = flexvert_xpos_in[worldid, vert_adr + v2_local]
|
||||||
|
|
||||||
|
# TODO: Add a broadphase
|
||||||
|
for geomid in range(ngeom):
|
||||||
|
gtype = geom_type[geomid]
|
||||||
|
if (
|
||||||
|
gtype != int(GeomType.SPHERE)
|
||||||
|
and gtype != int(GeomType.CAPSULE)
|
||||||
|
and gtype != int(GeomType.BOX)
|
||||||
|
and gtype != int(GeomType.CYLINDER)
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
|
||||||
|
g_contype = geom_contype[geomid]
|
||||||
|
g_conaffinity = geom_conaffinity[geomid]
|
||||||
|
f_contype = flex_contype[flexid]
|
||||||
|
f_conaffinity = flex_conaffinity[flexid]
|
||||||
|
if not ((g_contype & f_conaffinity) or (f_contype & g_conaffinity)):
|
||||||
|
continue
|
||||||
|
|
||||||
|
geom_margin_val = geom_margin[worldid % geom_margin.shape[0], geomid]
|
||||||
|
margin = geom_margin_val + tri_margin
|
||||||
|
|
||||||
|
geom_pos = geom_xpos_in[worldid, geomid]
|
||||||
|
geom_rot = geom_xmat_in[worldid, geomid]
|
||||||
|
geom_size_val = geom_size[worldid % geom_size.shape[0], geomid]
|
||||||
|
|
||||||
|
condim = geom_condim[geomid]
|
||||||
|
gf = geom_friction[worldid % geom_friction.shape[0], geomid]
|
||||||
|
friction = vec5(
|
||||||
|
wp.max(MJ_MINMU, gf[0]),
|
||||||
|
wp.max(MJ_MINMU, gf[0]),
|
||||||
|
wp.max(MJ_MINMU, gf[1]),
|
||||||
|
wp.max(MJ_MINMU, gf[2]),
|
||||||
|
wp.max(MJ_MINMU, gf[2]),
|
||||||
|
)
|
||||||
|
solref = geom_solref[worldid % geom_solref.shape[0], geomid]
|
||||||
|
solimp = geom_solimp[worldid % geom_solimp.shape[0], geomid]
|
||||||
|
|
||||||
|
_collide_geom_triangle(
|
||||||
|
naconmax_in,
|
||||||
|
gtype,
|
||||||
|
geom_pos,
|
||||||
|
geom_rot,
|
||||||
|
geom_size_val,
|
||||||
|
t1,
|
||||||
|
t2,
|
||||||
|
t3,
|
||||||
|
tri_radius,
|
||||||
|
margin,
|
||||||
|
condim,
|
||||||
|
friction,
|
||||||
|
solref,
|
||||||
|
solimp,
|
||||||
|
geomid,
|
||||||
|
flexid,
|
||||||
|
v0_local,
|
||||||
|
worldid,
|
||||||
|
contact_dist_out,
|
||||||
|
contact_pos_out,
|
||||||
|
contact_frame_out,
|
||||||
|
contact_includemargin_out,
|
||||||
|
contact_friction_out,
|
||||||
|
contact_solref_out,
|
||||||
|
contact_solreffriction_out,
|
||||||
|
contact_solimp_out,
|
||||||
|
contact_dim_out,
|
||||||
|
contact_geom_out,
|
||||||
|
contact_flex_out,
|
||||||
|
contact_vert_out,
|
||||||
|
contact_worldid_out,
|
||||||
|
contact_type_out,
|
||||||
|
contact_geomcollisionid_out,
|
||||||
|
nacon_out,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@wp.kernel
|
||||||
|
def _flex_narrowphase_dim3(
|
||||||
|
# Model:
|
||||||
|
ngeom: int,
|
||||||
|
nflex: int,
|
||||||
|
geom_type: wp.array(dtype=int),
|
||||||
|
geom_contype: wp.array(dtype=int),
|
||||||
|
geom_conaffinity: wp.array(dtype=int),
|
||||||
|
geom_condim: wp.array(dtype=int),
|
||||||
|
geom_solref: wp.array2d(dtype=wp.vec2),
|
||||||
|
geom_solimp: wp.array2d(dtype=vec5),
|
||||||
|
geom_size: wp.array2d(dtype=wp.vec3),
|
||||||
|
geom_friction: wp.array2d(dtype=wp.vec3),
|
||||||
|
geom_margin: wp.array2d(dtype=float),
|
||||||
|
flex_contype: wp.array(dtype=int),
|
||||||
|
flex_conaffinity: wp.array(dtype=int),
|
||||||
|
flex_margin: wp.array(dtype=float),
|
||||||
|
flex_dim: wp.array(dtype=int),
|
||||||
|
flex_vertadr: wp.array(dtype=int),
|
||||||
|
flex_shellnum: wp.array(dtype=int),
|
||||||
|
flex_shelldataadr: wp.array(dtype=int),
|
||||||
|
flex_shell: wp.array(dtype=int),
|
||||||
|
flex_radius: wp.array(dtype=float),
|
||||||
|
# Data in:
|
||||||
|
geom_xpos_in: wp.array2d(dtype=wp.vec3),
|
||||||
|
geom_xmat_in: wp.array2d(dtype=wp.mat33),
|
||||||
|
flexvert_xpos_in: wp.array2d(dtype=wp.vec3),
|
||||||
|
nworld_in: int,
|
||||||
|
naconmax_in: int,
|
||||||
|
# Data out:
|
||||||
|
contact_dist_out: wp.array(dtype=float),
|
||||||
|
contact_pos_out: wp.array(dtype=wp.vec3),
|
||||||
|
contact_frame_out: wp.array(dtype=wp.mat33),
|
||||||
|
contact_includemargin_out: wp.array(dtype=float),
|
||||||
|
contact_friction_out: wp.array(dtype=vec5),
|
||||||
|
contact_solref_out: wp.array(dtype=wp.vec2),
|
||||||
|
contact_solreffriction_out: wp.array(dtype=wp.vec2),
|
||||||
|
contact_solimp_out: wp.array(dtype=vec5),
|
||||||
|
contact_dim_out: wp.array(dtype=int),
|
||||||
|
contact_geom_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_flex_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_vert_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_worldid_out: wp.array(dtype=int),
|
||||||
|
contact_type_out: wp.array(dtype=int),
|
||||||
|
contact_geomcollisionid_out: wp.array(dtype=int),
|
||||||
|
nacon_out: wp.array(dtype=int),
|
||||||
|
):
|
||||||
|
worldid, shellid = wp.tid()
|
||||||
|
|
||||||
|
flexid = int(-1)
|
||||||
|
shell_offset = int(0)
|
||||||
|
for i in range(nflex):
|
||||||
|
if flex_dim[i] != 3:
|
||||||
|
continue
|
||||||
|
shell_num = flex_shellnum[i]
|
||||||
|
if shellid >= shell_offset and shellid < shell_offset + shell_num:
|
||||||
|
flexid = i
|
||||||
|
break
|
||||||
|
shell_offset += shell_num
|
||||||
|
|
||||||
|
if flexid < 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
vert_adr = flex_vertadr[flexid]
|
||||||
|
tri_radius = flex_radius[flexid]
|
||||||
|
tri_margin = flex_margin[flexid]
|
||||||
|
|
||||||
|
shell_adr = flex_shelldataadr[flexid]
|
||||||
|
local_shellid = shellid - shell_offset
|
||||||
|
shell_data_idx = shell_adr + local_shellid * 3
|
||||||
|
|
||||||
|
v0_local = flex_shell[shell_data_idx]
|
||||||
|
v1_local = flex_shell[shell_data_idx + 1]
|
||||||
|
v2_local = flex_shell[shell_data_idx + 2]
|
||||||
|
|
||||||
|
t1 = flexvert_xpos_in[worldid, vert_adr + v0_local]
|
||||||
|
t2 = flexvert_xpos_in[worldid, vert_adr + v1_local]
|
||||||
|
t3 = flexvert_xpos_in[worldid, vert_adr + v2_local]
|
||||||
|
|
||||||
|
# TODO: Add a broadphase
|
||||||
|
for geomid in range(ngeom):
|
||||||
|
gtype = geom_type[geomid]
|
||||||
|
if (
|
||||||
|
gtype != int(GeomType.SPHERE)
|
||||||
|
and gtype != int(GeomType.CAPSULE)
|
||||||
|
and gtype != int(GeomType.BOX)
|
||||||
|
and gtype != int(GeomType.CYLINDER)
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
|
||||||
|
g_contype = geom_contype[geomid]
|
||||||
|
g_conaffinity = geom_conaffinity[geomid]
|
||||||
|
f_contype = flex_contype[flexid]
|
||||||
|
f_conaffinity = flex_conaffinity[flexid]
|
||||||
|
if not ((g_contype & f_conaffinity) or (f_contype & g_conaffinity)):
|
||||||
|
continue
|
||||||
|
|
||||||
|
geom_margin_val = geom_margin[worldid % geom_margin.shape[0], geomid]
|
||||||
|
margin = geom_margin_val + tri_margin
|
||||||
|
|
||||||
|
geom_pos = geom_xpos_in[worldid, geomid]
|
||||||
|
geom_rot = geom_xmat_in[worldid, geomid]
|
||||||
|
geom_size_val = geom_size[worldid % geom_size.shape[0], geomid]
|
||||||
|
|
||||||
|
condim = geom_condim[geomid]
|
||||||
|
gf = geom_friction[worldid % geom_friction.shape[0], geomid]
|
||||||
|
friction = vec5(
|
||||||
|
wp.max(MJ_MINMU, gf[0]),
|
||||||
|
wp.max(MJ_MINMU, gf[0]),
|
||||||
|
wp.max(MJ_MINMU, gf[1]),
|
||||||
|
wp.max(MJ_MINMU, gf[2]),
|
||||||
|
wp.max(MJ_MINMU, gf[2]),
|
||||||
|
)
|
||||||
|
solref = geom_solref[worldid % geom_solref.shape[0], geomid]
|
||||||
|
solimp = geom_solimp[worldid % geom_solimp.shape[0], geomid]
|
||||||
|
|
||||||
|
_collide_geom_triangle(
|
||||||
|
naconmax_in,
|
||||||
|
gtype,
|
||||||
|
geom_pos,
|
||||||
|
geom_rot,
|
||||||
|
geom_size_val,
|
||||||
|
t1,
|
||||||
|
t2,
|
||||||
|
t3,
|
||||||
|
tri_radius,
|
||||||
|
margin,
|
||||||
|
condim,
|
||||||
|
friction,
|
||||||
|
solref,
|
||||||
|
solimp,
|
||||||
|
geomid,
|
||||||
|
flexid,
|
||||||
|
v0_local,
|
||||||
|
worldid,
|
||||||
|
contact_dist_out,
|
||||||
|
contact_pos_out,
|
||||||
|
contact_frame_out,
|
||||||
|
contact_includemargin_out,
|
||||||
|
contact_friction_out,
|
||||||
|
contact_solref_out,
|
||||||
|
contact_solreffriction_out,
|
||||||
|
contact_solimp_out,
|
||||||
|
contact_dim_out,
|
||||||
|
contact_geom_out,
|
||||||
|
contact_flex_out,
|
||||||
|
contact_vert_out,
|
||||||
|
contact_worldid_out,
|
||||||
|
contact_type_out,
|
||||||
|
contact_geomcollisionid_out,
|
||||||
|
nacon_out,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@event_scope
|
||||||
|
def flex_narrowphase(m: Model, d: Data):
|
||||||
|
"""Runs collision detection between geoms and flex elements."""
|
||||||
|
if m.nflex == 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
wp.launch(
|
||||||
|
_flex_narrowphase_dim2,
|
||||||
|
dim=(d.nworld, m.nflexelem),
|
||||||
|
inputs=[
|
||||||
|
m.ngeom,
|
||||||
|
m.nflex,
|
||||||
|
m.geom_type,
|
||||||
|
m.geom_contype,
|
||||||
|
m.geom_conaffinity,
|
||||||
|
m.geom_condim,
|
||||||
|
m.geom_solref,
|
||||||
|
m.geom_solimp,
|
||||||
|
m.geom_size,
|
||||||
|
m.geom_friction,
|
||||||
|
m.geom_margin,
|
||||||
|
m.flex_contype,
|
||||||
|
m.flex_conaffinity,
|
||||||
|
m.flex_margin,
|
||||||
|
m.flex_dim,
|
||||||
|
m.flex_vertadr,
|
||||||
|
m.flex_elemadr,
|
||||||
|
m.flex_elemnum,
|
||||||
|
m.flex_elemdataadr,
|
||||||
|
m.flex_elem,
|
||||||
|
m.flex_radius,
|
||||||
|
d.geom_xpos,
|
||||||
|
d.geom_xmat,
|
||||||
|
d.flexvert_xpos,
|
||||||
|
d.nworld,
|
||||||
|
d.naconmax,
|
||||||
|
],
|
||||||
|
outputs=[
|
||||||
|
d.contact.dist,
|
||||||
|
d.contact.pos,
|
||||||
|
d.contact.frame,
|
||||||
|
d.contact.includemargin,
|
||||||
|
d.contact.friction,
|
||||||
|
d.contact.solref,
|
||||||
|
d.contact.solreffriction,
|
||||||
|
d.contact.solimp,
|
||||||
|
d.contact.dim,
|
||||||
|
d.contact.geom,
|
||||||
|
d.contact.flex,
|
||||||
|
d.contact.vert,
|
||||||
|
d.contact.worldid,
|
||||||
|
d.contact.type,
|
||||||
|
d.contact.geomcollisionid,
|
||||||
|
d.nacon,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
wp.launch(
|
||||||
|
_flex_narrowphase_dim3,
|
||||||
|
dim=(d.nworld, m.nflexshelldata // 3),
|
||||||
|
inputs=[
|
||||||
|
m.ngeom,
|
||||||
|
m.nflex,
|
||||||
|
m.geom_type,
|
||||||
|
m.geom_contype,
|
||||||
|
m.geom_conaffinity,
|
||||||
|
m.geom_condim,
|
||||||
|
m.geom_solref,
|
||||||
|
m.geom_solimp,
|
||||||
|
m.geom_size,
|
||||||
|
m.geom_friction,
|
||||||
|
m.geom_margin,
|
||||||
|
m.flex_contype,
|
||||||
|
m.flex_conaffinity,
|
||||||
|
m.flex_margin,
|
||||||
|
m.flex_dim,
|
||||||
|
m.flex_vertadr,
|
||||||
|
m.flex_shellnum,
|
||||||
|
m.flex_shelldataadr,
|
||||||
|
m.flex_shell,
|
||||||
|
m.flex_radius,
|
||||||
|
d.geom_xpos,
|
||||||
|
d.geom_xmat,
|
||||||
|
d.flexvert_xpos,
|
||||||
|
d.nworld,
|
||||||
|
d.naconmax,
|
||||||
|
],
|
||||||
|
outputs=[
|
||||||
|
d.contact.dist,
|
||||||
|
d.contact.pos,
|
||||||
|
d.contact.frame,
|
||||||
|
d.contact.includemargin,
|
||||||
|
d.contact.friction,
|
||||||
|
d.contact.solref,
|
||||||
|
d.contact.solreffriction,
|
||||||
|
d.contact.solimp,
|
||||||
|
d.contact.dim,
|
||||||
|
d.contact.geom,
|
||||||
|
d.contact.flex,
|
||||||
|
d.contact.vert,
|
||||||
|
d.contact.worldid,
|
||||||
|
d.contact.type,
|
||||||
|
d.contact.geomcollisionid,
|
||||||
|
d.nacon,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
wp.launch(
|
||||||
|
_flex_plane_narrowphase,
|
||||||
|
dim=(d.nworld, m.nflexvert),
|
||||||
|
inputs=[
|
||||||
|
m.ngeom,
|
||||||
|
m.nflexvert,
|
||||||
|
m.geom_type,
|
||||||
|
m.geom_condim,
|
||||||
|
m.geom_solref,
|
||||||
|
m.geom_solimp,
|
||||||
|
m.geom_friction,
|
||||||
|
m.geom_margin,
|
||||||
|
m.flex_condim,
|
||||||
|
m.flex_friction,
|
||||||
|
m.flex_margin,
|
||||||
|
m.flex_vertadr,
|
||||||
|
m.flex_radius,
|
||||||
|
m.flex_vertflexid,
|
||||||
|
d.geom_xpos,
|
||||||
|
d.geom_xmat,
|
||||||
|
d.flexvert_xpos,
|
||||||
|
d.nworld,
|
||||||
|
d.naconmax,
|
||||||
|
],
|
||||||
|
outputs=[
|
||||||
|
d.contact.dist,
|
||||||
|
d.contact.pos,
|
||||||
|
d.contact.frame,
|
||||||
|
d.contact.includemargin,
|
||||||
|
d.contact.friction,
|
||||||
|
d.contact.solref,
|
||||||
|
d.contact.solreffriction,
|
||||||
|
d.contact.solimp,
|
||||||
|
d.contact.dim,
|
||||||
|
d.contact.geom,
|
||||||
|
d.contact.flex,
|
||||||
|
d.contact.vert,
|
||||||
|
d.contact.worldid,
|
||||||
|
d.contact.type,
|
||||||
|
d.contact.geomcollisionid,
|
||||||
|
d.nacon,
|
||||||
|
],
|
||||||
|
)
|
||||||
+10
-21
@@ -16,11 +16,12 @@
|
|||||||
import math
|
import math
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
|
import warp as wp
|
||||||
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import Geom
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import Geom
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import GeomType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import GeomType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import mat43
|
from mujoco.mjx.third_party.mujoco_warp._src.types import mat43
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import mat63
|
from mujoco.mjx.third_party.mujoco_warp._src.types import mat63
|
||||||
import warp as wp
|
|
||||||
|
|
||||||
# TODO(team): improve compile time to enable backward pass
|
# TODO(team): improve compile time to enable backward pass
|
||||||
wp.set_module_options({"enable_backward": False})
|
wp.set_module_options({"enable_backward": False})
|
||||||
@@ -581,16 +582,19 @@ def gjk(
|
|||||||
simplex_index2 = wp.vec4i()
|
simplex_index2 = wp.vec4i()
|
||||||
n = int(0)
|
n = int(0)
|
||||||
coordinates = wp.vec4() # barycentric coordinates
|
coordinates = wp.vec4() # barycentric coordinates
|
||||||
epsilon = wp.where(is_discrete, 0.0, 0.5 * tolerance * tolerance)
|
tol2 = tolerance * tolerance
|
||||||
|
epsilon = wp.where(is_discrete, 0.0, 0.5 * tol2)
|
||||||
|
|
||||||
# set initial guess
|
# set initial guess
|
||||||
x_k = x1_0 - x2_0
|
x_k = x1_0 - x2_0
|
||||||
|
xnorm_old = FLOAT_MAX
|
||||||
|
|
||||||
for k in range(gjk_iterations):
|
for _ in range(gjk_iterations):
|
||||||
xnorm = wp.dot(x_k, x_k)
|
xnorm = wp.dot(x_k, x_k)
|
||||||
# TODO(kbayes): determine new constant here
|
# TODO(kbayes): determine new constant here
|
||||||
if xnorm < 1e-12:
|
if xnorm < tol2 or wp.abs(xnorm_old - xnorm) < tol2:
|
||||||
break
|
break
|
||||||
|
xnorm_old = xnorm
|
||||||
dir_neg = x_k / wp.sqrt(xnorm)
|
dir_neg = x_k / wp.sqrt(xnorm)
|
||||||
|
|
||||||
# compute kth support point in geom1
|
# compute kth support point in geom1
|
||||||
@@ -663,13 +667,6 @@ def gjk(
|
|||||||
if n == 4:
|
if n == 4:
|
||||||
break
|
break
|
||||||
|
|
||||||
if k == gjk_iterations - 1:
|
|
||||||
wp.printf(
|
|
||||||
"Warning: opt.ccd_iterations, currently set to %d, needs to be"
|
|
||||||
" increased.\n",
|
|
||||||
gjk_iterations,
|
|
||||||
)
|
|
||||||
|
|
||||||
result = GJKResult()
|
result = GJKResult()
|
||||||
|
|
||||||
# compute the approximate witness points
|
# compute the approximate witness points
|
||||||
@@ -1205,7 +1202,6 @@ def _is_invalid_face(face: int) -> bool:
|
|||||||
def _epa(
|
def _epa(
|
||||||
# In:
|
# In:
|
||||||
tolerance: float,
|
tolerance: float,
|
||||||
gjk_iterations: int,
|
|
||||||
epa_iterations: int,
|
epa_iterations: int,
|
||||||
pt: Polytope,
|
pt: Polytope,
|
||||||
geom1: Geom,
|
geom1: Geom,
|
||||||
@@ -1226,7 +1222,7 @@ def _epa(
|
|||||||
# so iterations must be cap to limit the number of generated vertices
|
# so iterations must be cap to limit the number of generated vertices
|
||||||
# (one new vertex per iteration)
|
# (one new vertex per iteration)
|
||||||
epa_iterations = wp.min(epa_iterations, 1000)
|
epa_iterations = wp.min(epa_iterations, 1000)
|
||||||
for k in range(epa_iterations):
|
for _ in range(epa_iterations):
|
||||||
pidx = idx
|
pidx = idx
|
||||||
idx = int(-1)
|
idx = int(-1)
|
||||||
lower2 = float(FLOAT_MAX)
|
lower2 = float(FLOAT_MAX)
|
||||||
@@ -1325,13 +1321,6 @@ def _epa(
|
|||||||
# clear horizon
|
# clear horizon
|
||||||
pt.nhorizon = 0
|
pt.nhorizon = 0
|
||||||
|
|
||||||
if k == epa_iterations - 1:
|
|
||||||
wp.printf(
|
|
||||||
"Warning: opt.ccd_iterations, currently set to %d, needs to be"
|
|
||||||
" increased.\n",
|
|
||||||
gjk_iterations,
|
|
||||||
)
|
|
||||||
|
|
||||||
# return from valid face
|
# return from valid face
|
||||||
if idx > -1:
|
if idx > -1:
|
||||||
x1, x2, dist = _epa_witness(pt, geom1, geom2, geomtype1, geomtype2, idx)
|
x1, x2, dist = _epa_witness(pt, geom1, geom2, geomtype1, geomtype2, idx)
|
||||||
@@ -2347,7 +2336,7 @@ def ccd(
|
|||||||
if pt.status:
|
if pt.status:
|
||||||
return result.dist, 1, result.x1, result.x2, -1
|
return result.dist, 1, result.x1, result.x2, -1
|
||||||
|
|
||||||
dist, x1, x2, idx = _epa(tolerance, gjk_iterations, epa_iterations, pt, geom1, geom2, geomtype1, geomtype2, is_discrete)
|
dist, x1, x2, idx = _epa(tolerance, epa_iterations, pt, geom1, geom2, geomtype1, geomtype2, is_discrete)
|
||||||
if idx == -1:
|
if idx == -1:
|
||||||
return FLOAT_MAX, 0, wp.vec3(), wp.vec3(), -1
|
return FLOAT_MAX, 0, wp.vec3(), wp.vec3(), -1
|
||||||
|
|
||||||
|
|||||||
@@ -15,9 +15,11 @@
|
|||||||
|
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
|
import warp as wp
|
||||||
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import CollisionContext
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import CollisionContext
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import contact_params
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import Geom
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import Geom
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import contact_params
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import geom_collision_pair
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import geom_collision_pair
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import write_contact
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import write_contact
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_primitive_core import box_box
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_primitive_core import box_box
|
||||||
@@ -34,15 +36,14 @@ from mujoco.mjx.third_party.mujoco_warp._src.collision_primitive_core import sph
|
|||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_primitive_core import sphere_sphere
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_primitive_core import sphere_sphere
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.math import make_frame
|
from mujoco.mjx.third_party.mujoco_warp._src.math import make_frame
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.math import upper_trid_index
|
from mujoco.mjx.third_party.mujoco_warp._src.math import upper_trid_index
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MAXVAL
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import Data
|
from mujoco.mjx.third_party.mujoco_warp._src.types import Data
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import GeomType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import GeomType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import mat43
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MAXVAL
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import Model
|
from mujoco.mjx.third_party.mujoco_warp._src.types import Model
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import mat43
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import vec5
|
from mujoco.mjx.third_party.mujoco_warp._src.types import vec5
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import cache_kernel
|
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import cache_kernel
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import event_scope
|
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import event_scope
|
||||||
import warp as wp
|
|
||||||
|
|
||||||
wp.set_module_options({"enable_backward": False})
|
wp.set_module_options({"enable_backward": False})
|
||||||
|
|
||||||
@@ -304,6 +305,7 @@ def plane_sphere_wrapper(
|
|||||||
contact_solimp_out: wp.array(dtype=vec5),
|
contact_solimp_out: wp.array(dtype=vec5),
|
||||||
contact_dim_out: wp.array(dtype=int),
|
contact_dim_out: wp.array(dtype=int),
|
||||||
contact_geom_out: wp.array(dtype=wp.vec2i),
|
contact_geom_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_efc_address_out: wp.array2d(dtype=int),
|
||||||
contact_worldid_out: wp.array(dtype=int),
|
contact_worldid_out: wp.array(dtype=int),
|
||||||
contact_type_out: wp.array(dtype=int),
|
contact_type_out: wp.array(dtype=int),
|
||||||
contact_geomcollisionid_out: wp.array(dtype=int),
|
contact_geomcollisionid_out: wp.array(dtype=int),
|
||||||
@@ -339,6 +341,7 @@ def plane_sphere_wrapper(
|
|||||||
contact_solimp_out,
|
contact_solimp_out,
|
||||||
contact_dim_out,
|
contact_dim_out,
|
||||||
contact_geom_out,
|
contact_geom_out,
|
||||||
|
contact_efc_address_out,
|
||||||
contact_worldid_out,
|
contact_worldid_out,
|
||||||
contact_type_out,
|
contact_type_out,
|
||||||
contact_geomcollisionid_out,
|
contact_geomcollisionid_out,
|
||||||
@@ -374,6 +377,7 @@ def sphere_sphere_wrapper(
|
|||||||
contact_solimp_out: wp.array(dtype=vec5),
|
contact_solimp_out: wp.array(dtype=vec5),
|
||||||
contact_dim_out: wp.array(dtype=int),
|
contact_dim_out: wp.array(dtype=int),
|
||||||
contact_geom_out: wp.array(dtype=wp.vec2i),
|
contact_geom_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_efc_address_out: wp.array2d(dtype=int),
|
||||||
contact_worldid_out: wp.array(dtype=int),
|
contact_worldid_out: wp.array(dtype=int),
|
||||||
contact_type_out: wp.array(dtype=int),
|
contact_type_out: wp.array(dtype=int),
|
||||||
contact_geomcollisionid_out: wp.array(dtype=int),
|
contact_geomcollisionid_out: wp.array(dtype=int),
|
||||||
@@ -408,6 +412,7 @@ def sphere_sphere_wrapper(
|
|||||||
contact_solimp_out,
|
contact_solimp_out,
|
||||||
contact_dim_out,
|
contact_dim_out,
|
||||||
contact_geom_out,
|
contact_geom_out,
|
||||||
|
contact_efc_address_out,
|
||||||
contact_worldid_out,
|
contact_worldid_out,
|
||||||
contact_type_out,
|
contact_type_out,
|
||||||
contact_geomcollisionid_out,
|
contact_geomcollisionid_out,
|
||||||
@@ -443,6 +448,7 @@ def sphere_capsule_wrapper(
|
|||||||
contact_solimp_out: wp.array(dtype=vec5),
|
contact_solimp_out: wp.array(dtype=vec5),
|
||||||
contact_dim_out: wp.array(dtype=int),
|
contact_dim_out: wp.array(dtype=int),
|
||||||
contact_geom_out: wp.array(dtype=wp.vec2i),
|
contact_geom_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_efc_address_out: wp.array2d(dtype=int),
|
||||||
contact_worldid_out: wp.array(dtype=int),
|
contact_worldid_out: wp.array(dtype=int),
|
||||||
contact_type_out: wp.array(dtype=int),
|
contact_type_out: wp.array(dtype=int),
|
||||||
contact_geomcollisionid_out: wp.array(dtype=int),
|
contact_geomcollisionid_out: wp.array(dtype=int),
|
||||||
@@ -480,6 +486,7 @@ def sphere_capsule_wrapper(
|
|||||||
contact_solimp_out,
|
contact_solimp_out,
|
||||||
contact_dim_out,
|
contact_dim_out,
|
||||||
contact_geom_out,
|
contact_geom_out,
|
||||||
|
contact_efc_address_out,
|
||||||
contact_worldid_out,
|
contact_worldid_out,
|
||||||
contact_type_out,
|
contact_type_out,
|
||||||
contact_geomcollisionid_out,
|
contact_geomcollisionid_out,
|
||||||
@@ -515,6 +522,7 @@ def capsule_capsule_wrapper(
|
|||||||
contact_solimp_out: wp.array(dtype=vec5),
|
contact_solimp_out: wp.array(dtype=vec5),
|
||||||
contact_dim_out: wp.array(dtype=int),
|
contact_dim_out: wp.array(dtype=int),
|
||||||
contact_geom_out: wp.array(dtype=wp.vec2i),
|
contact_geom_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_efc_address_out: wp.array2d(dtype=int),
|
||||||
contact_worldid_out: wp.array(dtype=int),
|
contact_worldid_out: wp.array(dtype=int),
|
||||||
contact_type_out: wp.array(dtype=int),
|
contact_type_out: wp.array(dtype=int),
|
||||||
contact_geomcollisionid_out: wp.array(dtype=int),
|
contact_geomcollisionid_out: wp.array(dtype=int),
|
||||||
@@ -564,6 +572,7 @@ def capsule_capsule_wrapper(
|
|||||||
contact_solimp_out,
|
contact_solimp_out,
|
||||||
contact_dim_out,
|
contact_dim_out,
|
||||||
contact_geom_out,
|
contact_geom_out,
|
||||||
|
contact_efc_address_out,
|
||||||
contact_worldid_out,
|
contact_worldid_out,
|
||||||
contact_type_out,
|
contact_type_out,
|
||||||
contact_geomcollisionid_out,
|
contact_geomcollisionid_out,
|
||||||
@@ -599,6 +608,7 @@ def plane_capsule_wrapper(
|
|||||||
contact_solimp_out: wp.array(dtype=vec5),
|
contact_solimp_out: wp.array(dtype=vec5),
|
||||||
contact_dim_out: wp.array(dtype=int),
|
contact_dim_out: wp.array(dtype=int),
|
||||||
contact_geom_out: wp.array(dtype=wp.vec2i),
|
contact_geom_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_efc_address_out: wp.array2d(dtype=int),
|
||||||
contact_worldid_out: wp.array(dtype=int),
|
contact_worldid_out: wp.array(dtype=int),
|
||||||
contact_type_out: wp.array(dtype=int),
|
contact_type_out: wp.array(dtype=int),
|
||||||
contact_geomcollisionid_out: wp.array(dtype=int),
|
contact_geomcollisionid_out: wp.array(dtype=int),
|
||||||
@@ -644,6 +654,7 @@ def plane_capsule_wrapper(
|
|||||||
contact_solimp_out,
|
contact_solimp_out,
|
||||||
contact_dim_out,
|
contact_dim_out,
|
||||||
contact_geom_out,
|
contact_geom_out,
|
||||||
|
contact_efc_address_out,
|
||||||
contact_worldid_out,
|
contact_worldid_out,
|
||||||
contact_type_out,
|
contact_type_out,
|
||||||
contact_geomcollisionid_out,
|
contact_geomcollisionid_out,
|
||||||
@@ -679,6 +690,7 @@ def plane_ellipsoid_wrapper(
|
|||||||
contact_solimp_out: wp.array(dtype=vec5),
|
contact_solimp_out: wp.array(dtype=vec5),
|
||||||
contact_dim_out: wp.array(dtype=int),
|
contact_dim_out: wp.array(dtype=int),
|
||||||
contact_geom_out: wp.array(dtype=wp.vec2i),
|
contact_geom_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_efc_address_out: wp.array2d(dtype=int),
|
||||||
contact_worldid_out: wp.array(dtype=int),
|
contact_worldid_out: wp.array(dtype=int),
|
||||||
contact_type_out: wp.array(dtype=int),
|
contact_type_out: wp.array(dtype=int),
|
||||||
contact_geomcollisionid_out: wp.array(dtype=int),
|
contact_geomcollisionid_out: wp.array(dtype=int),
|
||||||
@@ -713,6 +725,7 @@ def plane_ellipsoid_wrapper(
|
|||||||
contact_solimp_out,
|
contact_solimp_out,
|
||||||
contact_dim_out,
|
contact_dim_out,
|
||||||
contact_geom_out,
|
contact_geom_out,
|
||||||
|
contact_efc_address_out,
|
||||||
contact_worldid_out,
|
contact_worldid_out,
|
||||||
contact_type_out,
|
contact_type_out,
|
||||||
contact_geomcollisionid_out,
|
contact_geomcollisionid_out,
|
||||||
@@ -748,6 +761,7 @@ def plane_box_wrapper(
|
|||||||
contact_solimp_out: wp.array(dtype=vec5),
|
contact_solimp_out: wp.array(dtype=vec5),
|
||||||
contact_dim_out: wp.array(dtype=int),
|
contact_dim_out: wp.array(dtype=int),
|
||||||
contact_geom_out: wp.array(dtype=wp.vec2i),
|
contact_geom_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_efc_address_out: wp.array2d(dtype=int),
|
||||||
contact_worldid_out: wp.array(dtype=int),
|
contact_worldid_out: wp.array(dtype=int),
|
||||||
contact_type_out: wp.array(dtype=int),
|
contact_type_out: wp.array(dtype=int),
|
||||||
contact_geomcollisionid_out: wp.array(dtype=int),
|
contact_geomcollisionid_out: wp.array(dtype=int),
|
||||||
@@ -784,6 +798,7 @@ def plane_box_wrapper(
|
|||||||
contact_solimp_out,
|
contact_solimp_out,
|
||||||
contact_dim_out,
|
contact_dim_out,
|
||||||
contact_geom_out,
|
contact_geom_out,
|
||||||
|
contact_efc_address_out,
|
||||||
contact_worldid_out,
|
contact_worldid_out,
|
||||||
contact_type_out,
|
contact_type_out,
|
||||||
contact_geomcollisionid_out,
|
contact_geomcollisionid_out,
|
||||||
@@ -819,6 +834,7 @@ def plane_convex_wrapper(
|
|||||||
contact_solimp_out: wp.array(dtype=vec5),
|
contact_solimp_out: wp.array(dtype=vec5),
|
||||||
contact_dim_out: wp.array(dtype=int),
|
contact_dim_out: wp.array(dtype=int),
|
||||||
contact_geom_out: wp.array(dtype=wp.vec2i),
|
contact_geom_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_efc_address_out: wp.array2d(dtype=int),
|
||||||
contact_worldid_out: wp.array(dtype=int),
|
contact_worldid_out: wp.array(dtype=int),
|
||||||
contact_type_out: wp.array(dtype=int),
|
contact_type_out: wp.array(dtype=int),
|
||||||
contact_geomcollisionid_out: wp.array(dtype=int),
|
contact_geomcollisionid_out: wp.array(dtype=int),
|
||||||
@@ -855,6 +871,7 @@ def plane_convex_wrapper(
|
|||||||
contact_solimp_out,
|
contact_solimp_out,
|
||||||
contact_dim_out,
|
contact_dim_out,
|
||||||
contact_geom_out,
|
contact_geom_out,
|
||||||
|
contact_efc_address_out,
|
||||||
contact_worldid_out,
|
contact_worldid_out,
|
||||||
contact_type_out,
|
contact_type_out,
|
||||||
contact_geomcollisionid_out,
|
contact_geomcollisionid_out,
|
||||||
@@ -890,6 +907,7 @@ def sphere_cylinder_wrapper(
|
|||||||
contact_solimp_out: wp.array(dtype=vec5),
|
contact_solimp_out: wp.array(dtype=vec5),
|
||||||
contact_dim_out: wp.array(dtype=int),
|
contact_dim_out: wp.array(dtype=int),
|
||||||
contact_geom_out: wp.array(dtype=wp.vec2i),
|
contact_geom_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_efc_address_out: wp.array2d(dtype=int),
|
||||||
contact_worldid_out: wp.array(dtype=int),
|
contact_worldid_out: wp.array(dtype=int),
|
||||||
contact_type_out: wp.array(dtype=int),
|
contact_type_out: wp.array(dtype=int),
|
||||||
contact_geomcollisionid_out: wp.array(dtype=int),
|
contact_geomcollisionid_out: wp.array(dtype=int),
|
||||||
@@ -934,6 +952,7 @@ def sphere_cylinder_wrapper(
|
|||||||
contact_solimp_out,
|
contact_solimp_out,
|
||||||
contact_dim_out,
|
contact_dim_out,
|
||||||
contact_geom_out,
|
contact_geom_out,
|
||||||
|
contact_efc_address_out,
|
||||||
contact_worldid_out,
|
contact_worldid_out,
|
||||||
contact_type_out,
|
contact_type_out,
|
||||||
contact_geomcollisionid_out,
|
contact_geomcollisionid_out,
|
||||||
@@ -969,6 +988,7 @@ def plane_cylinder_wrapper(
|
|||||||
contact_solimp_out: wp.array(dtype=vec5),
|
contact_solimp_out: wp.array(dtype=vec5),
|
||||||
contact_dim_out: wp.array(dtype=int),
|
contact_dim_out: wp.array(dtype=int),
|
||||||
contact_geom_out: wp.array(dtype=wp.vec2i),
|
contact_geom_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_efc_address_out: wp.array2d(dtype=int),
|
||||||
contact_worldid_out: wp.array(dtype=int),
|
contact_worldid_out: wp.array(dtype=int),
|
||||||
contact_type_out: wp.array(dtype=int),
|
contact_type_out: wp.array(dtype=int),
|
||||||
contact_geomcollisionid_out: wp.array(dtype=int),
|
contact_geomcollisionid_out: wp.array(dtype=int),
|
||||||
@@ -1015,6 +1035,7 @@ def plane_cylinder_wrapper(
|
|||||||
contact_solimp_out,
|
contact_solimp_out,
|
||||||
contact_dim_out,
|
contact_dim_out,
|
||||||
contact_geom_out,
|
contact_geom_out,
|
||||||
|
contact_efc_address_out,
|
||||||
contact_worldid_out,
|
contact_worldid_out,
|
||||||
contact_type_out,
|
contact_type_out,
|
||||||
contact_geomcollisionid_out,
|
contact_geomcollisionid_out,
|
||||||
@@ -1050,6 +1071,7 @@ def sphere_box_wrapper(
|
|||||||
contact_solimp_out: wp.array(dtype=vec5),
|
contact_solimp_out: wp.array(dtype=vec5),
|
||||||
contact_dim_out: wp.array(dtype=int),
|
contact_dim_out: wp.array(dtype=int),
|
||||||
contact_geom_out: wp.array(dtype=wp.vec2i),
|
contact_geom_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_efc_address_out: wp.array2d(dtype=int),
|
||||||
contact_worldid_out: wp.array(dtype=int),
|
contact_worldid_out: wp.array(dtype=int),
|
||||||
contact_type_out: wp.array(dtype=int),
|
contact_type_out: wp.array(dtype=int),
|
||||||
contact_geomcollisionid_out: wp.array(dtype=int),
|
contact_geomcollisionid_out: wp.array(dtype=int),
|
||||||
@@ -1083,6 +1105,7 @@ def sphere_box_wrapper(
|
|||||||
contact_solimp_out,
|
contact_solimp_out,
|
||||||
contact_dim_out,
|
contact_dim_out,
|
||||||
contact_geom_out,
|
contact_geom_out,
|
||||||
|
contact_efc_address_out,
|
||||||
contact_worldid_out,
|
contact_worldid_out,
|
||||||
contact_type_out,
|
contact_type_out,
|
||||||
contact_geomcollisionid_out,
|
contact_geomcollisionid_out,
|
||||||
@@ -1118,6 +1141,7 @@ def capsule_box_wrapper(
|
|||||||
contact_solimp_out: wp.array(dtype=vec5),
|
contact_solimp_out: wp.array(dtype=vec5),
|
||||||
contact_dim_out: wp.array(dtype=int),
|
contact_dim_out: wp.array(dtype=int),
|
||||||
contact_geom_out: wp.array(dtype=wp.vec2i),
|
contact_geom_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_efc_address_out: wp.array2d(dtype=int),
|
||||||
contact_worldid_out: wp.array(dtype=int),
|
contact_worldid_out: wp.array(dtype=int),
|
||||||
contact_type_out: wp.array(dtype=int),
|
contact_type_out: wp.array(dtype=int),
|
||||||
contact_geomcollisionid_out: wp.array(dtype=int),
|
contact_geomcollisionid_out: wp.array(dtype=int),
|
||||||
@@ -1166,6 +1190,7 @@ def capsule_box_wrapper(
|
|||||||
contact_solimp_out,
|
contact_solimp_out,
|
||||||
contact_dim_out,
|
contact_dim_out,
|
||||||
contact_geom_out,
|
contact_geom_out,
|
||||||
|
contact_efc_address_out,
|
||||||
contact_worldid_out,
|
contact_worldid_out,
|
||||||
contact_type_out,
|
contact_type_out,
|
||||||
contact_geomcollisionid_out,
|
contact_geomcollisionid_out,
|
||||||
@@ -1201,6 +1226,7 @@ def box_box_wrapper(
|
|||||||
contact_solimp_out: wp.array(dtype=vec5),
|
contact_solimp_out: wp.array(dtype=vec5),
|
||||||
contact_dim_out: wp.array(dtype=int),
|
contact_dim_out: wp.array(dtype=int),
|
||||||
contact_geom_out: wp.array(dtype=wp.vec2i),
|
contact_geom_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_efc_address_out: wp.array2d(dtype=int),
|
||||||
contact_worldid_out: wp.array(dtype=int),
|
contact_worldid_out: wp.array(dtype=int),
|
||||||
contact_type_out: wp.array(dtype=int),
|
contact_type_out: wp.array(dtype=int),
|
||||||
contact_geomcollisionid_out: wp.array(dtype=int),
|
contact_geomcollisionid_out: wp.array(dtype=int),
|
||||||
@@ -1245,6 +1271,7 @@ def box_box_wrapper(
|
|||||||
contact_solimp_out,
|
contact_solimp_out,
|
||||||
contact_dim_out,
|
contact_dim_out,
|
||||||
contact_geom_out,
|
contact_geom_out,
|
||||||
|
contact_efc_address_out,
|
||||||
contact_worldid_out,
|
contact_worldid_out,
|
||||||
contact_type_out,
|
contact_type_out,
|
||||||
contact_geomcollisionid_out,
|
contact_geomcollisionid_out,
|
||||||
@@ -1327,6 +1354,7 @@ def _primitive_narrowphase(primitive_collisions_types, primitive_collisions_func
|
|||||||
contact_solimp_out: wp.array(dtype=vec5),
|
contact_solimp_out: wp.array(dtype=vec5),
|
||||||
contact_dim_out: wp.array(dtype=int),
|
contact_dim_out: wp.array(dtype=int),
|
||||||
contact_geom_out: wp.array(dtype=wp.vec2i),
|
contact_geom_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_efc_address_out: wp.array2d(dtype=int),
|
||||||
contact_worldid_out: wp.array(dtype=int),
|
contact_worldid_out: wp.array(dtype=int),
|
||||||
contact_type_out: wp.array(dtype=int),
|
contact_type_out: wp.array(dtype=int),
|
||||||
contact_geomcollisionid_out: wp.array(dtype=int),
|
contact_geomcollisionid_out: wp.array(dtype=int),
|
||||||
@@ -1416,6 +1444,7 @@ def _primitive_narrowphase(primitive_collisions_types, primitive_collisions_func
|
|||||||
contact_solimp_out,
|
contact_solimp_out,
|
||||||
contact_dim_out,
|
contact_dim_out,
|
||||||
contact_geom_out,
|
contact_geom_out,
|
||||||
|
contact_efc_address_out,
|
||||||
contact_worldid_out,
|
contact_worldid_out,
|
||||||
contact_type_out,
|
contact_type_out,
|
||||||
contact_geomcollisionid_out,
|
contact_geomcollisionid_out,
|
||||||
@@ -1511,6 +1540,7 @@ def primitive_narrowphase(m: Model, d: Data, ctx: CollisionContext, collision_ta
|
|||||||
d.contact.solimp,
|
d.contact.solimp,
|
||||||
d.contact.dim,
|
d.contact.dim,
|
||||||
d.contact.geom,
|
d.contact.geom,
|
||||||
|
d.contact.efc_address,
|
||||||
d.contact.worldid,
|
d.contact.worldid,
|
||||||
d.contact.type,
|
d.contact.type,
|
||||||
d.contact.geomcollisionid,
|
d.contact.geomcollisionid,
|
||||||
|
|||||||
@@ -1489,3 +1489,507 @@ def capsule_box(
|
|||||||
mat23f(pos1[0], pos1[1], pos1[2], pos2[0], pos2[1], pos2[2]),
|
mat23f(pos1[0], pos1[1], pos1[2], pos2[0], pos2[1], pos2[2]),
|
||||||
mat23f(normal1[0], normal1[1], normal1[2], normal2[0], normal2[1], normal2[2]),
|
mat23f(normal1[0], normal1[1], normal1[2], normal2[0], normal2[1], normal2[2]),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@wp.func
|
||||||
|
def _tri_area_sign(p1: wp.vec2, p2: wp.vec2, p3: wp.vec2) -> float:
|
||||||
|
"""Sign of (signed) area of planar triangle."""
|
||||||
|
return wp.sign((p1[0] - p3[0]) * (p2[1] - p3[1]) - (p2[0] - p3[0]) * (p1[1] - p3[1]))
|
||||||
|
|
||||||
|
|
||||||
|
@wp.func
|
||||||
|
def _tri_point_segment(p: wp.vec2, u: wp.vec2, v: wp.vec2) -> wp.vec2:
|
||||||
|
"""Find nearest point to p within line segment (u, v)."""
|
||||||
|
uv = v - u
|
||||||
|
up = p - u
|
||||||
|
|
||||||
|
denom = wp.max(MJ_MINVAL, wp.dot(uv, uv))
|
||||||
|
a = wp.dot(uv, up) / denom
|
||||||
|
|
||||||
|
if a <= 0.0:
|
||||||
|
return u
|
||||||
|
elif a >= 1.0:
|
||||||
|
return v
|
||||||
|
else:
|
||||||
|
return u + a * uv
|
||||||
|
|
||||||
|
|
||||||
|
@wp.func
|
||||||
|
def sphere_triangle(
|
||||||
|
sphere_pos: wp.vec3,
|
||||||
|
sphere_radius: float,
|
||||||
|
t1: wp.vec3,
|
||||||
|
t2: wp.vec3,
|
||||||
|
t3: wp.vec3,
|
||||||
|
tri_radius: float,
|
||||||
|
) -> Tuple[float, wp.vec3, wp.vec3]:
|
||||||
|
"""Core contact geometry calculation for sphere-triangle collision.
|
||||||
|
|
||||||
|
Port of mjraw_SphereTriangle from engine_collision_primitive.c
|
||||||
|
|
||||||
|
Args:
|
||||||
|
sphere_pos: Center position of the sphere.
|
||||||
|
sphere_radius: Radius of the sphere.
|
||||||
|
t1: Triangle vertex positions.
|
||||||
|
t2: Triangle vertex positions.
|
||||||
|
t3: Triangle vertex positions.
|
||||||
|
tri_radius: Triangle (flex element) radius.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
- Contact distance (MJ_MAXVAL if no collision).
|
||||||
|
- Contact position.
|
||||||
|
- Contact normal vector.
|
||||||
|
"""
|
||||||
|
S = sphere_pos - t1
|
||||||
|
A = t2 - t1
|
||||||
|
B = t3 - t1
|
||||||
|
|
||||||
|
N = wp.normalize(wp.cross(A, B))
|
||||||
|
|
||||||
|
dstS = wp.dot(N, S)
|
||||||
|
|
||||||
|
P = S - dstS * N
|
||||||
|
|
||||||
|
V1 = wp.normalize(A)
|
||||||
|
lenA = wp.length(A)
|
||||||
|
V2 = wp.normalize(wp.cross(N, A))
|
||||||
|
|
||||||
|
o = wp.vec2(0.0, 0.0)
|
||||||
|
a = wp.vec2(lenA, 0.0)
|
||||||
|
b = wp.vec2(wp.dot(V1, B), wp.dot(V2, B))
|
||||||
|
p = wp.vec2(wp.dot(V1, P), wp.dot(V2, P))
|
||||||
|
|
||||||
|
sign1 = _tri_area_sign(p, o, a)
|
||||||
|
sign2 = _tri_area_sign(p, a, b)
|
||||||
|
sign3 = _tri_area_sign(p, b, o)
|
||||||
|
|
||||||
|
X = wp.vec3(0.0)
|
||||||
|
if sign1 == sign2 and sign2 == sign3:
|
||||||
|
X = P
|
||||||
|
else:
|
||||||
|
x0 = _tri_point_segment(p, o, a)
|
||||||
|
x1 = _tri_point_segment(p, a, b)
|
||||||
|
x2 = _tri_point_segment(p, b, o)
|
||||||
|
|
||||||
|
d0 = wp.length(p - x0)
|
||||||
|
d1 = wp.length(p - x1)
|
||||||
|
d2 = wp.length(p - x2)
|
||||||
|
|
||||||
|
if d0 < d1 and d0 < d2:
|
||||||
|
X = x0[0] * V1 + x0[1] * V2
|
||||||
|
elif d1 < d2:
|
||||||
|
X = x1[0] * V1 + x1[1] * V2
|
||||||
|
else:
|
||||||
|
X = x2[0] * V1 + x2[1] * V2
|
||||||
|
|
||||||
|
nrm = X - S
|
||||||
|
dst = wp.length(nrm)
|
||||||
|
|
||||||
|
if dst > MJ_MINVAL:
|
||||||
|
nrm = nrm / dst
|
||||||
|
else:
|
||||||
|
nrm = N
|
||||||
|
|
||||||
|
dist = dst - sphere_radius - tri_radius
|
||||||
|
pos = sphere_pos + nrm * (sphere_radius + 0.5 * dist)
|
||||||
|
|
||||||
|
return dist, pos, nrm
|
||||||
|
|
||||||
|
|
||||||
|
@wp.func
|
||||||
|
def box_triangle(
|
||||||
|
box_pos: wp.vec3,
|
||||||
|
box_rot: wp.mat33,
|
||||||
|
box_size: wp.vec3,
|
||||||
|
t1: wp.vec3,
|
||||||
|
t2: wp.vec3,
|
||||||
|
t3: wp.vec3,
|
||||||
|
tri_radius: float,
|
||||||
|
) -> Tuple[wp.vec2, mat23f, mat23f]:
|
||||||
|
"""Core contact geometry calculation for box-triangle collision.
|
||||||
|
|
||||||
|
Port of mjraw_BoxTriangle from engine_collision_primitive.c
|
||||||
|
|
||||||
|
Args:
|
||||||
|
box_pos: Center position of the box.
|
||||||
|
box_rot: Orientation matrix of the box.
|
||||||
|
box_size: Half-sizes of the box.
|
||||||
|
t1: Triangle vertex positions.
|
||||||
|
t2: Triangle vertex positions.
|
||||||
|
t3: Triangle vertex positions.
|
||||||
|
tri_radius: Triangle (flex element) radius.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
- wp.vec2 of distances for up to 2 contacts (MJ_MAXVAL if no collision).
|
||||||
|
- mat23f of contact positions (2 x vec3).
|
||||||
|
- mat23f of contact normals (2 x vec3).
|
||||||
|
"""
|
||||||
|
dist1 = MJ_MAXVAL
|
||||||
|
dist2 = MJ_MAXVAL
|
||||||
|
pos1 = wp.vec3(0.0)
|
||||||
|
pos2 = wp.vec3(0.0)
|
||||||
|
nrm1 = wp.vec3(0.0)
|
||||||
|
nrm2 = wp.vec3(0.0)
|
||||||
|
cnt = 0
|
||||||
|
|
||||||
|
box_rotT = wp.transpose(box_rot)
|
||||||
|
|
||||||
|
for vi in range(3):
|
||||||
|
vert = wp.vec3(0.0)
|
||||||
|
if vi == 0:
|
||||||
|
vert = t1
|
||||||
|
elif vi == 1:
|
||||||
|
vert = t2
|
||||||
|
else:
|
||||||
|
vert = t3
|
||||||
|
|
||||||
|
diff = vert - box_pos
|
||||||
|
local = box_rotT @ diff
|
||||||
|
|
||||||
|
maxaxis = 0
|
||||||
|
maxval = wp.abs(local[0]) - box_size[0]
|
||||||
|
for j in range(1, 3):
|
||||||
|
val = wp.abs(local[j]) - box_size[j]
|
||||||
|
if val > maxval:
|
||||||
|
maxval = val
|
||||||
|
maxaxis = j
|
||||||
|
|
||||||
|
inside = True
|
||||||
|
for j in range(3):
|
||||||
|
if wp.abs(local[j]) > box_size[j] + tri_radius:
|
||||||
|
inside = False
|
||||||
|
|
||||||
|
if inside and cnt < 2:
|
||||||
|
nrm_local = wp.vec3(0.0)
|
||||||
|
if maxaxis == 0:
|
||||||
|
nrm_local = wp.vec3(wp.sign(local[0]), 0.0, 0.0)
|
||||||
|
elif maxaxis == 1:
|
||||||
|
nrm_local = wp.vec3(0.0, wp.sign(local[1]), 0.0)
|
||||||
|
else:
|
||||||
|
nrm_local = wp.vec3(0.0, 0.0, wp.sign(local[2]))
|
||||||
|
|
||||||
|
nrm_global = box_rot @ nrm_local
|
||||||
|
d = maxval - tri_radius
|
||||||
|
offset = tri_radius + d * 0.5
|
||||||
|
p = vert - nrm_global * offset
|
||||||
|
|
||||||
|
if cnt == 0:
|
||||||
|
dist1 = d
|
||||||
|
pos1 = p
|
||||||
|
nrm1 = nrm_global
|
||||||
|
else:
|
||||||
|
dist2 = d
|
||||||
|
pos2 = p
|
||||||
|
nrm2 = nrm_global
|
||||||
|
cnt += 1
|
||||||
|
|
||||||
|
for i in range(8):
|
||||||
|
if cnt >= 2:
|
||||||
|
break
|
||||||
|
|
||||||
|
vec = wp.vec3(
|
||||||
|
wp.where(i & 1, box_size[0], -box_size[0]),
|
||||||
|
wp.where(i & 2, box_size[1], -box_size[1]),
|
||||||
|
wp.where(i & 4, box_size[2], -box_size[2]),
|
||||||
|
)
|
||||||
|
corner = box_rot @ vec + box_pos
|
||||||
|
|
||||||
|
d, p, n = sphere_triangle(corner, 0.0, t1, t2, t3, tri_radius)
|
||||||
|
if d < MJ_MAXVAL:
|
||||||
|
if cnt == 0:
|
||||||
|
dist1 = d
|
||||||
|
pos1 = p
|
||||||
|
nrm1 = n
|
||||||
|
elif cnt == 1:
|
||||||
|
dist2 = d
|
||||||
|
pos2 = p
|
||||||
|
nrm2 = n
|
||||||
|
cnt += 1
|
||||||
|
|
||||||
|
return (
|
||||||
|
wp.vec2(dist1, dist2),
|
||||||
|
mat23f(pos1[0], pos1[1], pos1[2], pos2[0], pos2[1], pos2[2]),
|
||||||
|
mat23f(nrm1[0], nrm1[1], nrm1[2], nrm2[0], nrm2[1], nrm2[2]),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@wp.func
|
||||||
|
def capsule_triangle(
|
||||||
|
capsule_pos: wp.vec3,
|
||||||
|
capsule_axis: wp.vec3,
|
||||||
|
capsule_radius: float,
|
||||||
|
capsule_half_length: float,
|
||||||
|
t1: wp.vec3,
|
||||||
|
t2: wp.vec3,
|
||||||
|
t3: wp.vec3,
|
||||||
|
tri_radius: float,
|
||||||
|
) -> Tuple[wp.vec2, mat23f, mat23f]:
|
||||||
|
"""Core contact geometry calculation for capsule-triangle collision.
|
||||||
|
|
||||||
|
Port of mjraw_CapsuleTriangle from engine_collision_primitive.c
|
||||||
|
|
||||||
|
Args:
|
||||||
|
capsule_pos: Center position of the capsule.
|
||||||
|
capsule_axis: Unit axis direction of the capsule.
|
||||||
|
capsule_radius: Radius of the capsule.
|
||||||
|
capsule_half_length: Half-length of the capsule cylinder.
|
||||||
|
t1: Triangle vertex positions.
|
||||||
|
t2: Triangle vertex positions.
|
||||||
|
t3: Triangle vertex positions.
|
||||||
|
tri_radius: Triangle (flex element) radius.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
- wp.vec2 of distances for up to 2 contacts (MJ_MAXVAL if no collision).
|
||||||
|
- mat23f of contact positions (2 x vec3).
|
||||||
|
- mat23f of contact normals (2 x vec3).
|
||||||
|
"""
|
||||||
|
dist1 = MJ_MAXVAL
|
||||||
|
dist2 = MJ_MAXVAL
|
||||||
|
pos1 = wp.vec3(0.0)
|
||||||
|
pos2 = wp.vec3(0.0)
|
||||||
|
nrm1 = wp.vec3(0.0)
|
||||||
|
nrm2 = wp.vec3(0.0)
|
||||||
|
cnt = 0
|
||||||
|
|
||||||
|
p1 = capsule_pos - capsule_axis * capsule_half_length
|
||||||
|
p2 = capsule_pos + capsule_axis * capsule_half_length
|
||||||
|
|
||||||
|
d, p, n = sphere_triangle(p1, capsule_radius, t1, t2, t3, tri_radius)
|
||||||
|
if d < MJ_MAXVAL:
|
||||||
|
dist1 = d
|
||||||
|
pos1 = p
|
||||||
|
nrm1 = n
|
||||||
|
cnt = 1
|
||||||
|
|
||||||
|
d, p, n = sphere_triangle(p2, capsule_radius, t1, t2, t3, tri_radius)
|
||||||
|
if d < MJ_MAXVAL and cnt < 2:
|
||||||
|
if cnt == 0:
|
||||||
|
dist1 = d
|
||||||
|
pos1 = p
|
||||||
|
nrm1 = n
|
||||||
|
else:
|
||||||
|
dist2 = d
|
||||||
|
pos2 = p
|
||||||
|
nrm2 = n
|
||||||
|
cnt += 1
|
||||||
|
|
||||||
|
ab = p2 - p1
|
||||||
|
ab_len_sq = 4.0 * capsule_half_length * capsule_half_length
|
||||||
|
|
||||||
|
for vi in range(3):
|
||||||
|
if cnt >= 2:
|
||||||
|
break
|
||||||
|
|
||||||
|
vert = wp.vec3(0.0)
|
||||||
|
if vi == 0:
|
||||||
|
vert = t1
|
||||||
|
elif vi == 1:
|
||||||
|
vert = t2
|
||||||
|
else:
|
||||||
|
vert = t3
|
||||||
|
|
||||||
|
vec = vert - p1
|
||||||
|
t_param = wp.dot(vec, ab) / wp.max(MJ_MINVAL, ab_len_sq)
|
||||||
|
|
||||||
|
if t_param > MJ_MINVAL and t_param < 1.0 - MJ_MINVAL:
|
||||||
|
closest = p1 + ab * t_param
|
||||||
|
diff = vert - closest
|
||||||
|
dist_raw = wp.length(diff)
|
||||||
|
|
||||||
|
if dist_raw > MJ_MINVAL:
|
||||||
|
nrm = diff / dist_raw
|
||||||
|
d = dist_raw - capsule_radius - tri_radius
|
||||||
|
p = (closest + vert + nrm * (capsule_radius - tri_radius)) * 0.5
|
||||||
|
|
||||||
|
if cnt == 0:
|
||||||
|
dist1 = d
|
||||||
|
pos1 = p
|
||||||
|
nrm1 = nrm
|
||||||
|
else:
|
||||||
|
dist2 = d
|
||||||
|
pos2 = p
|
||||||
|
nrm2 = nrm
|
||||||
|
cnt += 1
|
||||||
|
|
||||||
|
return (
|
||||||
|
wp.vec2(dist1, dist2),
|
||||||
|
mat23f(pos1[0], pos1[1], pos1[2], pos2[0], pos2[1], pos2[2]),
|
||||||
|
mat23f(nrm1[0], nrm1[1], nrm1[2], nrm2[0], nrm2[1], nrm2[2]),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@wp.func
|
||||||
|
def cylinder_triangle(
|
||||||
|
cylinder_pos: wp.vec3,
|
||||||
|
cylinder_axis: wp.vec3,
|
||||||
|
cylinder_radius: float,
|
||||||
|
cylinder_half_height: float,
|
||||||
|
t1: wp.vec3,
|
||||||
|
t2: wp.vec3,
|
||||||
|
t3: wp.vec3,
|
||||||
|
tri_radius: float,
|
||||||
|
) -> Tuple[wp.vec2, mat23f, mat23f]:
|
||||||
|
"""Core contact geometry calculation for cylinder-triangle collision.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
cylinder_pos: Center position of the cylinder.
|
||||||
|
cylinder_axis: Unit axis direction of the cylinder.
|
||||||
|
cylinder_radius: Radius of the cylinder.
|
||||||
|
cylinder_half_height: Half-height of the cylinder.
|
||||||
|
t1: Triangle vertex positions.
|
||||||
|
t2: Triangle vertex positions.
|
||||||
|
t3: Triangle vertex positions.
|
||||||
|
tri_radius: Triangle (flex element) radius.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
- wp.vec2 of distances for up to 2 contacts (MJ_MAXVAL if no collision).
|
||||||
|
- mat23f of contact positions (2 x vec3).
|
||||||
|
- mat23f of contact normals (2 x vec3).
|
||||||
|
"""
|
||||||
|
dist1 = MJ_MAXVAL
|
||||||
|
dist2 = MJ_MAXVAL
|
||||||
|
pos1 = wp.vec3(0.0)
|
||||||
|
pos2 = wp.vec3(0.0)
|
||||||
|
nrm1 = wp.vec3(0.0)
|
||||||
|
nrm2 = wp.vec3(0.0)
|
||||||
|
cnt = int(0)
|
||||||
|
|
||||||
|
p1 = cylinder_pos - cylinder_axis * cylinder_half_height
|
||||||
|
p2 = cylinder_pos + cylinder_axis * cylinder_half_height
|
||||||
|
|
||||||
|
ab = p2 - p1
|
||||||
|
ab_len_sq = 4.0 * cylinder_half_height * cylinder_half_height
|
||||||
|
|
||||||
|
for vi in range(3):
|
||||||
|
if cnt >= 2:
|
||||||
|
break
|
||||||
|
|
||||||
|
vert = wp.vec3(0.0)
|
||||||
|
if vi == 0:
|
||||||
|
vert = t1
|
||||||
|
elif vi == 1:
|
||||||
|
vert = t2
|
||||||
|
else:
|
||||||
|
vert = t3
|
||||||
|
|
||||||
|
vec = vert - p1
|
||||||
|
t_param = wp.dot(vec, ab) / wp.max(MJ_MINVAL, ab_len_sq)
|
||||||
|
|
||||||
|
if t_param > MJ_MINVAL and t_param < 1.0 - MJ_MINVAL:
|
||||||
|
closest = p1 + ab * t_param
|
||||||
|
diff = vert - closest
|
||||||
|
dist_raw = wp.length(diff)
|
||||||
|
|
||||||
|
if dist_raw < cylinder_radius + tri_radius:
|
||||||
|
if dist_raw > MJ_MINVAL:
|
||||||
|
nrm = diff / dist_raw
|
||||||
|
d = dist_raw - cylinder_radius - tri_radius
|
||||||
|
p = (closest + vert + nrm * (cylinder_radius - tri_radius)) * 0.5
|
||||||
|
else:
|
||||||
|
dist_to_side = cylinder_radius
|
||||||
|
dist_to_p2 = (1.0 - t_param) * wp.sqrt(ab_len_sq)
|
||||||
|
dist_to_p1 = t_param * wp.sqrt(ab_len_sq)
|
||||||
|
|
||||||
|
if dist_to_p2 < dist_to_side and dist_to_p2 < dist_to_p1:
|
||||||
|
nrm = cylinder_axis
|
||||||
|
d = -dist_to_p2 - tri_radius
|
||||||
|
p = vert
|
||||||
|
elif dist_to_p1 < dist_to_side:
|
||||||
|
nrm = -cylinder_axis
|
||||||
|
d = -dist_to_p1 - tri_radius
|
||||||
|
p = vert
|
||||||
|
else:
|
||||||
|
tri_normal = wp.normalize(wp.cross(t2 - t1, t3 - t1))
|
||||||
|
nrm = tri_normal
|
||||||
|
d = -cylinder_radius - tri_radius
|
||||||
|
p = closest
|
||||||
|
|
||||||
|
if cnt == 0:
|
||||||
|
dist1 = d
|
||||||
|
pos1 = p
|
||||||
|
nrm1 = nrm
|
||||||
|
else:
|
||||||
|
dist2 = d
|
||||||
|
pos2 = p
|
||||||
|
nrm2 = nrm
|
||||||
|
cnt += 1
|
||||||
|
elif t_param <= MJ_MINVAL:
|
||||||
|
diff = vert - p1
|
||||||
|
signed_dist = wp.dot(diff, cylinder_axis)
|
||||||
|
perp = diff - cylinder_axis * signed_dist
|
||||||
|
perp_len = wp.length(perp)
|
||||||
|
|
||||||
|
if perp_len < cylinder_radius:
|
||||||
|
d = -signed_dist - tri_radius
|
||||||
|
nrm = -cylinder_axis
|
||||||
|
p = vert - nrm * (tri_radius + d * 0.5)
|
||||||
|
if cnt == 0:
|
||||||
|
dist1 = d
|
||||||
|
pos1 = p
|
||||||
|
nrm1 = nrm
|
||||||
|
else:
|
||||||
|
dist2 = d
|
||||||
|
pos2 = p
|
||||||
|
nrm2 = nrm
|
||||||
|
cnt += 1
|
||||||
|
elif perp_len < cylinder_radius + tri_radius:
|
||||||
|
edge_dir = perp / perp_len
|
||||||
|
edge_point = p1 + edge_dir * cylinder_radius
|
||||||
|
diff_to_edge = vert - edge_point
|
||||||
|
dist_raw = wp.length(diff_to_edge)
|
||||||
|
if dist_raw > MJ_MINVAL:
|
||||||
|
nrm = diff_to_edge / dist_raw
|
||||||
|
d = dist_raw - tri_radius
|
||||||
|
p = vert - nrm * (tri_radius + d * 0.5)
|
||||||
|
if cnt == 0:
|
||||||
|
dist1 = d
|
||||||
|
pos1 = p
|
||||||
|
nrm1 = nrm
|
||||||
|
else:
|
||||||
|
dist2 = d
|
||||||
|
pos2 = p
|
||||||
|
nrm2 = nrm
|
||||||
|
cnt += 1
|
||||||
|
else:
|
||||||
|
diff = vert - p2
|
||||||
|
signed_dist = wp.dot(diff, cylinder_axis)
|
||||||
|
perp = diff - cylinder_axis * signed_dist
|
||||||
|
perp_len = wp.length(perp)
|
||||||
|
|
||||||
|
if perp_len < cylinder_radius:
|
||||||
|
d = signed_dist - tri_radius
|
||||||
|
nrm = cylinder_axis
|
||||||
|
p = vert - nrm * (tri_radius + d * 0.5)
|
||||||
|
if cnt == 0:
|
||||||
|
dist1 = d
|
||||||
|
pos1 = p
|
||||||
|
nrm1 = nrm
|
||||||
|
else:
|
||||||
|
dist2 = d
|
||||||
|
pos2 = p
|
||||||
|
nrm2 = nrm
|
||||||
|
cnt += 1
|
||||||
|
elif perp_len < cylinder_radius + tri_radius:
|
||||||
|
edge_dir = perp / perp_len
|
||||||
|
edge_point = p2 + edge_dir * cylinder_radius
|
||||||
|
diff_to_edge = vert - edge_point
|
||||||
|
dist_raw = wp.length(diff_to_edge)
|
||||||
|
if dist_raw > MJ_MINVAL:
|
||||||
|
nrm = diff_to_edge / dist_raw
|
||||||
|
d = dist_raw - tri_radius
|
||||||
|
p = vert - nrm * (tri_radius + d * 0.5)
|
||||||
|
if cnt == 0:
|
||||||
|
dist1 = d
|
||||||
|
pos1 = p
|
||||||
|
nrm1 = nrm
|
||||||
|
else:
|
||||||
|
dist2 = d
|
||||||
|
pos2 = p
|
||||||
|
nrm2 = nrm
|
||||||
|
cnt += 1
|
||||||
|
|
||||||
|
return (
|
||||||
|
wp.vec2(dist1, dist2),
|
||||||
|
mat23f(pos1[0], pos1[1], pos1[2], pos2[0], pos2[1], pos2[2]),
|
||||||
|
mat23f(nrm1[0], nrm1[1], nrm1[2], nrm2[0], nrm2[1], nrm2[2]),
|
||||||
|
)
|
||||||
|
|||||||
+62
-59
@@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
|
import warp as wp
|
||||||
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import CollisionContext
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import CollisionContext
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import contact_params
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import contact_params
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import geom_collision_pair
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_core import geom_collision_pair
|
||||||
@@ -27,9 +29,9 @@ from mujoco.mjx.third_party.mujoco_warp._src.types import Model
|
|||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import vec5
|
from mujoco.mjx.third_party.mujoco_warp._src.types import vec5
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import vec8
|
from mujoco.mjx.third_party.mujoco_warp._src.types import vec8
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import vec8i
|
from mujoco.mjx.third_party.mujoco_warp._src.types import vec8i
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import vec_pluginattr
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.util_misc import halton
|
from mujoco.mjx.third_party.mujoco_warp._src.util_misc import halton
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import event_scope
|
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import event_scope
|
||||||
import warp as wp
|
|
||||||
|
|
||||||
wp.set_module_options({"enable_backward": False})
|
wp.set_module_options({"enable_backward": False})
|
||||||
|
|
||||||
@@ -38,8 +40,8 @@ wp.set_module_options({"enable_backward": False})
|
|||||||
class OptimizationParams:
|
class OptimizationParams:
|
||||||
rel_mat: wp.mat33
|
rel_mat: wp.mat33
|
||||||
rel_pos: wp.vec3
|
rel_pos: wp.vec3
|
||||||
attr1: wp.vec3
|
attr1: vec_pluginattr
|
||||||
attr2: wp.vec3
|
attr2: vec_pluginattr
|
||||||
|
|
||||||
|
|
||||||
@wp.struct
|
@wp.struct
|
||||||
@@ -83,14 +85,18 @@ def get_sdf_params(
|
|||||||
oct_coeff: wp.array(dtype=vec8),
|
oct_coeff: wp.array(dtype=vec8),
|
||||||
mesh_octadr: wp.array(dtype=int),
|
mesh_octadr: wp.array(dtype=int),
|
||||||
plugin: wp.array(dtype=int),
|
plugin: wp.array(dtype=int),
|
||||||
plugin_attr: wp.array(dtype=wp.vec3f),
|
plugin_attr: wp.array(dtype=vec_pluginattr),
|
||||||
# In:
|
# In:
|
||||||
g_type: int,
|
g_type: int,
|
||||||
g_size: wp.vec3,
|
g_size: wp.vec3,
|
||||||
plugin_id: int,
|
plugin_id: int,
|
||||||
mesh_id: int,
|
mesh_id: int,
|
||||||
) -> Tuple[wp.vec3, int, VolumeData, MeshData]:
|
) -> Tuple[vec_pluginattr, int, VolumeData, MeshData]:
|
||||||
attributes = g_size
|
# default attributes from geom size, first 3 values copied
|
||||||
|
attributes = vec_pluginattr()
|
||||||
|
attributes[0] = g_size[0]
|
||||||
|
attributes[1] = g_size[1]
|
||||||
|
attributes[2] = g_size[2]
|
||||||
plugin_index = -1
|
plugin_index = -1
|
||||||
volume_data = VolumeData()
|
volume_data = VolumeData()
|
||||||
|
|
||||||
@@ -108,6 +114,16 @@ def get_sdf_params(
|
|||||||
volume_data.oct_coeff = oct_coeff
|
volume_data.oct_coeff = oct_coeff
|
||||||
volume_data.valid = True
|
volume_data.valid = True
|
||||||
|
|
||||||
|
elif g_type == GeomType.MESH and mesh_id != -1 and mesh_octadr[mesh_id] != -1:
|
||||||
|
octadr = mesh_octadr[mesh_id]
|
||||||
|
volume_data.center = oct_aabb[octadr, 0]
|
||||||
|
volume_data.half_size = oct_aabb[octadr, 1]
|
||||||
|
volume_data.root = octadr
|
||||||
|
volume_data.oct_aabb = oct_aabb
|
||||||
|
volume_data.oct_child = oct_child
|
||||||
|
volume_data.oct_coeff = oct_coeff
|
||||||
|
volume_data.valid = True
|
||||||
|
|
||||||
return attributes, plugin_index, volume_data, MeshData()
|
return attributes, plugin_index, volume_data, MeshData()
|
||||||
|
|
||||||
|
|
||||||
@@ -215,24 +231,28 @@ def grad_ellipsoid(p: wp.vec3, size: wp.vec3) -> wp.vec3:
|
|||||||
|
|
||||||
|
|
||||||
@wp.func
|
@wp.func
|
||||||
def user_sdf(p: wp.vec3, attr: wp.vec3, sdf_type: int) -> float:
|
def user_sdf(p: wp.vec3, attr: vec_pluginattr, sdf_type: int) -> float:
|
||||||
|
"""User-defined SDF function.
|
||||||
|
|
||||||
|
Access attributes via attr[i] where i is the attribute index (0 to _NPLUGINATTR-1).
|
||||||
|
"""
|
||||||
wp.printf("ERROR: user_sdf function must be implemented by user code\n")
|
wp.printf("ERROR: user_sdf function must be implemented by user code\n")
|
||||||
return 0.0
|
return 0.0
|
||||||
|
|
||||||
|
|
||||||
@wp.func
|
@wp.func
|
||||||
def user_sdf_grad(p: wp.vec3, attr: wp.vec3, sdf_type: int) -> wp.vec3:
|
def user_sdf_grad(p: wp.vec3, attr: vec_pluginattr, sdf_type: int) -> wp.vec3:
|
||||||
|
"""User-defined SDF gradient function.
|
||||||
|
|
||||||
|
Access attributes via attr[i] where i is the attribute index (0 to _NPLUGINATTR-1).
|
||||||
|
"""
|
||||||
wp.printf("ERROR: user_sdf_grad function must be implemented by user code\n")
|
wp.printf("ERROR: user_sdf_grad function must be implemented by user code\n")
|
||||||
return wp.vec3(0.0)
|
return wp.vec3(0.0)
|
||||||
|
|
||||||
|
|
||||||
@wp.func
|
@wp.func
|
||||||
def find_oct(
|
def find_oct(
|
||||||
oct_child: wp.array(dtype=vec8i),
|
oct_child: wp.array(dtype=vec8i), oct_aabb: wp.array2d(dtype=wp.vec3), p: wp.vec3, grad: bool, root: int
|
||||||
oct_aabb: wp.array2d(dtype=wp.vec3),
|
|
||||||
p: wp.vec3,
|
|
||||||
grad: bool,
|
|
||||||
root: int,
|
|
||||||
) -> Tuple[int, Tuple[vec8, vec8, vec8]]:
|
) -> Tuple[int, Tuple[vec8, vec8, vec8]]:
|
||||||
stack = root
|
stack = root
|
||||||
niter = int(100)
|
niter = int(100)
|
||||||
@@ -342,13 +362,7 @@ def box_project(center: wp.vec3, half_size: wp.vec3, xyz: wp.vec3) -> Tuple[floa
|
|||||||
@wp.func
|
@wp.func
|
||||||
def sample_volume_sdf(xyz: wp.vec3, volume_data: VolumeData) -> float:
|
def sample_volume_sdf(xyz: wp.vec3, volume_data: VolumeData) -> float:
|
||||||
dist0, point = box_project(volume_data.center, volume_data.half_size, xyz)
|
dist0, point = box_project(volume_data.center, volume_data.half_size, xyz)
|
||||||
node, weights = find_oct(
|
node, weights = find_oct(volume_data.oct_child, volume_data.oct_aabb, point, grad=False, root=volume_data.root)
|
||||||
volume_data.oct_child,
|
|
||||||
volume_data.oct_aabb,
|
|
||||||
point,
|
|
||||||
grad=False,
|
|
||||||
root=volume_data.root,
|
|
||||||
)
|
|
||||||
return dist0 + wp.dot(weights[0], volume_data.oct_coeff[node])
|
return dist0 + wp.dot(weights[0], volume_data.oct_coeff[node])
|
||||||
|
|
||||||
|
|
||||||
@@ -365,13 +379,7 @@ def sample_volume_grad(xyz: wp.vec3, volume_data: VolumeData) -> wp.vec3:
|
|||||||
grad_y = (sample_volume_sdf(xyz + dy, volume_data) - f) / h
|
grad_y = (sample_volume_sdf(xyz + dy, volume_data) - f) / h
|
||||||
grad_z = (sample_volume_sdf(xyz + dz, volume_data) - f) / h
|
grad_z = (sample_volume_sdf(xyz + dz, volume_data) - f) / h
|
||||||
return wp.vec3(grad_x, grad_y, grad_z)
|
return wp.vec3(grad_x, grad_y, grad_z)
|
||||||
node, weights = find_oct(
|
node, weights = find_oct(volume_data.oct_child, volume_data.oct_aabb, point, grad=True, root=volume_data.root)
|
||||||
volume_data.oct_child,
|
|
||||||
volume_data.oct_aabb,
|
|
||||||
point,
|
|
||||||
grad=True,
|
|
||||||
root=volume_data.root,
|
|
||||||
)
|
|
||||||
grad_x = wp.dot(weights[0], volume_data.oct_coeff[node])
|
grad_x = wp.dot(weights[0], volume_data.oct_coeff[node])
|
||||||
grad_y = wp.dot(weights[1], volume_data.oct_coeff[node])
|
grad_y = wp.dot(weights[1], volume_data.oct_coeff[node])
|
||||||
grad_z = wp.dot(weights[2], volume_data.oct_coeff[node])
|
grad_z = wp.dot(weights[2], volume_data.oct_coeff[node])
|
||||||
@@ -379,15 +387,17 @@ def sample_volume_grad(xyz: wp.vec3, volume_data: VolumeData) -> wp.vec3:
|
|||||||
|
|
||||||
|
|
||||||
@wp.func
|
@wp.func
|
||||||
def sdf(type: int, p: wp.vec3, attr: wp.vec3, sdf_type: int, volume_data: VolumeData, mesh_data: MeshData) -> float:
|
def sdf(type: int, p: wp.vec3, attr: vec_pluginattr, sdf_type: int, volume_data: VolumeData, mesh_data: MeshData) -> float:
|
||||||
|
# extract first 3 elements as vec3 for primitive sdf functions
|
||||||
|
attr_vec3 = wp.vec3(attr[0], attr[1], attr[2])
|
||||||
if type == GeomType.PLANE:
|
if type == GeomType.PLANE:
|
||||||
return p[2]
|
return p[2]
|
||||||
elif type == GeomType.SPHERE:
|
elif type == GeomType.SPHERE:
|
||||||
return sphere(p, attr)
|
return sphere(p, attr_vec3)
|
||||||
elif type == GeomType.BOX:
|
elif type == GeomType.BOX:
|
||||||
return box(p, attr)
|
return box(p, attr_vec3)
|
||||||
elif type == GeomType.ELLIPSOID:
|
elif type == GeomType.ELLIPSOID:
|
||||||
return ellipsoid(p, attr)
|
return ellipsoid(p, attr_vec3)
|
||||||
elif type == GeomType.MESH and mesh_data.valid:
|
elif type == GeomType.MESH and mesh_data.valid:
|
||||||
mesh_data.pnt = p
|
mesh_data.pnt = p
|
||||||
mesh_data.vec = -wp.normalize(p)
|
mesh_data.vec = -wp.normalize(p)
|
||||||
@@ -425,21 +435,27 @@ def sdf(type: int, p: wp.vec3, attr: wp.vec3, sdf_type: int, volume_data: Volume
|
|||||||
return sample_volume_sdf(p, volume_data)
|
return sample_volume_sdf(p, volume_data)
|
||||||
else:
|
else:
|
||||||
return user_sdf(p, attr, sdf_type)
|
return user_sdf(p, attr, sdf_type)
|
||||||
|
elif type == GeomType.MESH and volume_data.valid:
|
||||||
|
return sample_volume_sdf(p, volume_data)
|
||||||
wp.printf("ERROR: SDF type not implemented\n")
|
wp.printf("ERROR: SDF type not implemented\n")
|
||||||
return 0.0
|
return 0.0
|
||||||
|
|
||||||
|
|
||||||
@wp.func
|
@wp.func
|
||||||
def sdf_grad(type: int, p: wp.vec3, attr: wp.vec3, sdf_type: int, volume_data: VolumeData, mesh_data: MeshData) -> wp.vec3:
|
def sdf_grad(
|
||||||
|
type: int, p: wp.vec3, attr: vec_pluginattr, sdf_type: int, volume_data: VolumeData, mesh_data: MeshData
|
||||||
|
) -> wp.vec3:
|
||||||
|
# extract first 3 elements as vec3 for primitive sdf functions
|
||||||
|
attr_vec3 = wp.vec3(attr[0], attr[1], attr[2])
|
||||||
if type == GeomType.PLANE:
|
if type == GeomType.PLANE:
|
||||||
grad = wp.vec3(0.0, 0.0, 1.0)
|
grad = wp.vec3(0.0, 0.0, 1.0)
|
||||||
return grad
|
return grad
|
||||||
elif type == GeomType.SPHERE:
|
elif type == GeomType.SPHERE:
|
||||||
return grad_sphere(p)
|
return grad_sphere(p)
|
||||||
elif type == GeomType.BOX:
|
elif type == GeomType.BOX:
|
||||||
return grad_box(p, attr)
|
return grad_box(p, attr_vec3)
|
||||||
elif type == GeomType.ELLIPSOID:
|
elif type == GeomType.ELLIPSOID:
|
||||||
return grad_ellipsoid(p, attr)
|
return grad_ellipsoid(p, attr_vec3)
|
||||||
elif type == GeomType.MESH and mesh_data.valid:
|
elif type == GeomType.MESH and mesh_data.valid:
|
||||||
mesh_data.pnt = p
|
mesh_data.pnt = p
|
||||||
mesh_data.vec = -wp.normalize(p)
|
mesh_data.vec = -wp.normalize(p)
|
||||||
@@ -466,6 +482,8 @@ def sdf_grad(type: int, p: wp.vec3, attr: wp.vec3, sdf_type: int, volume_data: V
|
|||||||
return sample_volume_grad(p, volume_data)
|
return sample_volume_grad(p, volume_data)
|
||||||
else:
|
else:
|
||||||
return user_sdf_grad(p, attr, sdf_type)
|
return user_sdf_grad(p, attr, sdf_type)
|
||||||
|
elif type == GeomType.MESH and volume_data.valid:
|
||||||
|
return sample_volume_grad(p, volume_data)
|
||||||
wp.printf("ERROR: SDF grad type not implemented\n")
|
wp.printf("ERROR: SDF grad type not implemented\n")
|
||||||
return wp.vec3(0.0)
|
return wp.vec3(0.0)
|
||||||
|
|
||||||
@@ -476,8 +494,8 @@ def clearance(
|
|||||||
type1: int,
|
type1: int,
|
||||||
p1: wp.vec3,
|
p1: wp.vec3,
|
||||||
p2: wp.vec3,
|
p2: wp.vec3,
|
||||||
s1: wp.vec3,
|
s1: vec_pluginattr,
|
||||||
s2: wp.vec3,
|
s2: vec_pluginattr,
|
||||||
sdf_type1: int,
|
sdf_type1: int,
|
||||||
sdf_type2: int,
|
sdf_type2: int,
|
||||||
sfd_intersection: bool,
|
sfd_intersection: bool,
|
||||||
@@ -606,8 +624,8 @@ def gradient_descent(
|
|||||||
# In:
|
# In:
|
||||||
type1: int,
|
type1: int,
|
||||||
x0_initial: wp.vec3,
|
x0_initial: wp.vec3,
|
||||||
attr1: wp.vec3,
|
attr1: vec_pluginattr,
|
||||||
attr2: wp.vec3,
|
attr2: vec_pluginattr,
|
||||||
pos1: wp.vec3,
|
pos1: wp.vec3,
|
||||||
rot1: wp.mat33,
|
rot1: wp.mat33,
|
||||||
pos2: wp.vec3,
|
pos2: wp.vec3,
|
||||||
@@ -687,7 +705,7 @@ def _sdf_narrowphase(
|
|||||||
pair_gap: wp.array2d(dtype=float),
|
pair_gap: wp.array2d(dtype=float),
|
||||||
pair_friction: wp.array2d(dtype=vec5),
|
pair_friction: wp.array2d(dtype=vec5),
|
||||||
plugin: wp.array(dtype=int),
|
plugin: wp.array(dtype=int),
|
||||||
plugin_attr: wp.array(dtype=wp.vec3f),
|
plugin_attr: wp.array(dtype=vec_pluginattr),
|
||||||
geom_plugin_index: wp.array(dtype=int),
|
geom_plugin_index: wp.array(dtype=int),
|
||||||
# Data in:
|
# Data in:
|
||||||
geom_xpos_in: wp.array2d(dtype=wp.vec3),
|
geom_xpos_in: wp.array2d(dtype=wp.vec3),
|
||||||
@@ -711,6 +729,7 @@ def _sdf_narrowphase(
|
|||||||
contact_solimp_out: wp.array(dtype=vec5),
|
contact_solimp_out: wp.array(dtype=vec5),
|
||||||
contact_dim_out: wp.array(dtype=int),
|
contact_dim_out: wp.array(dtype=int),
|
||||||
contact_geom_out: wp.array(dtype=wp.vec2i),
|
contact_geom_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_efc_address_out: wp.array2d(dtype=int),
|
||||||
contact_worldid_out: wp.array(dtype=int),
|
contact_worldid_out: wp.array(dtype=int),
|
||||||
contact_type_out: wp.array(dtype=int),
|
contact_type_out: wp.array(dtype=int),
|
||||||
contact_geomcollisionid_out: wp.array(dtype=int),
|
contact_geomcollisionid_out: wp.array(dtype=int),
|
||||||
@@ -799,29 +818,11 @@ def _sdf_narrowphase(
|
|||||||
rot1 = geom1.rot
|
rot1 = geom1.rot
|
||||||
|
|
||||||
attr1, g1_plugin_id, volume_data1, mesh_data1 = get_sdf_params(
|
attr1, g1_plugin_id, volume_data1, mesh_data1 = get_sdf_params(
|
||||||
oct_child,
|
oct_child, oct_aabb, oct_coeff, mesh_octadr, plugin, plugin_attr, type1, geom1.size, g1_plugin, geom_dataid[g1]
|
||||||
oct_aabb,
|
|
||||||
oct_coeff,
|
|
||||||
mesh_octadr,
|
|
||||||
plugin,
|
|
||||||
plugin_attr,
|
|
||||||
type1,
|
|
||||||
geom1.size,
|
|
||||||
g1_plugin,
|
|
||||||
geom_dataid[g1],
|
|
||||||
)
|
)
|
||||||
|
|
||||||
attr2, g2_plugin_id, volume_data2, mesh_data2 = get_sdf_params(
|
attr2, g2_plugin_id, volume_data2, mesh_data2 = get_sdf_params(
|
||||||
oct_child,
|
oct_child, oct_aabb, oct_coeff, mesh_octadr, plugin, plugin_attr, type2, geom2.size, g2_plugin, geom_dataid[g2]
|
||||||
oct_aabb,
|
|
||||||
oct_coeff,
|
|
||||||
mesh_octadr,
|
|
||||||
plugin,
|
|
||||||
plugin_attr,
|
|
||||||
type2,
|
|
||||||
geom2.size,
|
|
||||||
g2_plugin,
|
|
||||||
geom_dataid[g2],
|
|
||||||
)
|
)
|
||||||
|
|
||||||
mesh_data1.nmeshface = nmeshface
|
mesh_data1.nmeshface = nmeshface
|
||||||
@@ -900,6 +901,7 @@ def _sdf_narrowphase(
|
|||||||
contact_solimp_out,
|
contact_solimp_out,
|
||||||
contact_dim_out,
|
contact_dim_out,
|
||||||
contact_geom_out,
|
contact_geom_out,
|
||||||
|
contact_efc_address_out,
|
||||||
contact_worldid_out,
|
contact_worldid_out,
|
||||||
contact_type_out,
|
contact_type_out,
|
||||||
contact_geomcollisionid_out,
|
contact_geomcollisionid_out,
|
||||||
@@ -977,6 +979,7 @@ def sdf_narrowphase(m: Model, d: Data, ctx: CollisionContext):
|
|||||||
d.contact.solimp,
|
d.contact.solimp,
|
||||||
d.contact.dim,
|
d.contact.dim,
|
||||||
d.contact.geom,
|
d.contact.geom,
|
||||||
|
d.contact.efc_address,
|
||||||
d.contact.worldid,
|
d.contact.worldid,
|
||||||
d.contact.type,
|
d.contact.type,
|
||||||
d.contact.geomcollisionid,
|
d.contact.geomcollisionid,
|
||||||
|
|||||||
+438
-232
File diff suppressed because it is too large
Load Diff
+132
-25
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
import warp as wp
|
import warp as wp
|
||||||
|
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.support import next_act
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import BiasType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import BiasType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import Data
|
from mujoco.mjx.third_party.mujoco_warp._src.types import Data
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import DisableBit
|
from mujoco.mjx.third_party.mujoco_warp._src.types import DisableBit
|
||||||
@@ -30,18 +31,24 @@ wp.set_module_options({"enable_backward": False})
|
|||||||
@wp.kernel
|
@wp.kernel
|
||||||
def _qderiv_actuator_passive_vel(
|
def _qderiv_actuator_passive_vel(
|
||||||
# Model:
|
# Model:
|
||||||
|
opt_timestep: wp.array(dtype=float),
|
||||||
actuator_dyntype: wp.array(dtype=int),
|
actuator_dyntype: wp.array(dtype=int),
|
||||||
actuator_gaintype: wp.array(dtype=int),
|
actuator_gaintype: wp.array(dtype=int),
|
||||||
actuator_biastype: wp.array(dtype=int),
|
actuator_biastype: wp.array(dtype=int),
|
||||||
actuator_actadr: wp.array(dtype=int),
|
actuator_actadr: wp.array(dtype=int),
|
||||||
actuator_actnum: wp.array(dtype=int),
|
actuator_actnum: wp.array(dtype=int),
|
||||||
actuator_forcelimited: wp.array(dtype=bool),
|
actuator_forcelimited: wp.array(dtype=bool),
|
||||||
|
actuator_actlimited: wp.array(dtype=bool),
|
||||||
|
actuator_dynprm: wp.array2d(dtype=vec10f),
|
||||||
actuator_gainprm: wp.array2d(dtype=vec10f),
|
actuator_gainprm: wp.array2d(dtype=vec10f),
|
||||||
actuator_biasprm: wp.array2d(dtype=vec10f),
|
actuator_biasprm: wp.array2d(dtype=vec10f),
|
||||||
|
actuator_actearly: wp.array(dtype=bool),
|
||||||
actuator_forcerange: wp.array2d(dtype=wp.vec2),
|
actuator_forcerange: wp.array2d(dtype=wp.vec2),
|
||||||
|
actuator_actrange: wp.array2d(dtype=wp.vec2),
|
||||||
# Data in:
|
# Data in:
|
||||||
act_in: wp.array2d(dtype=float),
|
act_in: wp.array2d(dtype=float),
|
||||||
ctrl_in: wp.array2d(dtype=float),
|
ctrl_in: wp.array2d(dtype=float),
|
||||||
|
act_dot_in: wp.array2d(dtype=float),
|
||||||
actuator_force_in: wp.array2d(dtype=float),
|
actuator_force_in: wp.array2d(dtype=float),
|
||||||
# Out:
|
# Out:
|
||||||
vel_out: wp.array2d(dtype=float),
|
vel_out: wp.array2d(dtype=float),
|
||||||
@@ -76,9 +83,24 @@ def _qderiv_actuator_passive_vel(
|
|||||||
vel = float(bias)
|
vel = float(bias)
|
||||||
if actuator_dyntype[actid] != DynType.NONE:
|
if actuator_dyntype[actid] != DynType.NONE:
|
||||||
if gain != 0.0:
|
if gain != 0.0:
|
||||||
act_first = actuator_actadr[actid]
|
act_adr = actuator_actadr[actid] + actuator_actnum[actid] - 1
|
||||||
act_last = act_first + actuator_actnum[actid] - 1
|
|
||||||
vel += gain * act_in[worldid, act_last]
|
# use next activation if actearly is set (matching forward pass)
|
||||||
|
if actuator_actearly[actid]:
|
||||||
|
act = next_act(
|
||||||
|
opt_timestep[worldid % opt_timestep.shape[0]],
|
||||||
|
actuator_dyntype[actid],
|
||||||
|
actuator_dynprm[worldid % actuator_dynprm.shape[0], actid],
|
||||||
|
actuator_actrange[worldid % actuator_actrange.shape[0], actid],
|
||||||
|
act_in[worldid, act_adr],
|
||||||
|
act_dot_in[worldid, act_adr],
|
||||||
|
1.0,
|
||||||
|
actuator_actlimited[actid],
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
act = act_in[worldid, act_adr]
|
||||||
|
|
||||||
|
vel += gain * act
|
||||||
else:
|
else:
|
||||||
if gain != 0.0:
|
if gain != 0.0:
|
||||||
vel += gain * ctrl_in[worldid, actid]
|
vel += gain * ctrl_in[worldid, actid]
|
||||||
@@ -95,10 +117,9 @@ def _nonzero_mask(x: float) -> float:
|
|||||||
|
|
||||||
|
|
||||||
@wp.kernel
|
@wp.kernel
|
||||||
def _qderiv_actuator_passive_actuation_sparse(
|
def _qderiv_actuator_passive_actuation_dense(
|
||||||
# Model:
|
# Model:
|
||||||
nu: int,
|
nu: int,
|
||||||
is_sparse: bool,
|
|
||||||
# Data in:
|
# Data in:
|
||||||
moment_rownnz_in: wp.array2d(dtype=int),
|
moment_rownnz_in: wp.array2d(dtype=int),
|
||||||
moment_rowadr_in: wp.array2d(dtype=int),
|
moment_rowadr_in: wp.array2d(dtype=int),
|
||||||
@@ -142,14 +163,65 @@ def _qderiv_actuator_passive_actuation_sparse(
|
|||||||
|
|
||||||
qderiv_contrib += moment_i * moment_j * vel
|
qderiv_contrib += moment_i * moment_j * vel
|
||||||
|
|
||||||
if is_sparse:
|
|
||||||
qDeriv_out[worldid, 0, elemid] = qderiv_contrib
|
|
||||||
else:
|
|
||||||
qDeriv_out[worldid, dofiid, dofjid] = qderiv_contrib
|
qDeriv_out[worldid, dofiid, dofjid] = qderiv_contrib
|
||||||
if dofiid != dofjid:
|
if dofiid != dofjid:
|
||||||
qDeriv_out[worldid, dofjid, dofiid] = qderiv_contrib
|
qDeriv_out[worldid, dofjid, dofiid] = qderiv_contrib
|
||||||
|
|
||||||
|
|
||||||
|
@wp.kernel
|
||||||
|
def _qderiv_actuator_passive_actuation_sparse(
|
||||||
|
# Model:
|
||||||
|
M_rownnz: wp.array(dtype=int),
|
||||||
|
M_rowadr: wp.array(dtype=int),
|
||||||
|
# Data in:
|
||||||
|
moment_rownnz_in: wp.array2d(dtype=int),
|
||||||
|
moment_rowadr_in: wp.array2d(dtype=int),
|
||||||
|
moment_colind_in: wp.array2d(dtype=int),
|
||||||
|
actuator_moment_in: wp.array2d(dtype=float),
|
||||||
|
# In:
|
||||||
|
vel_in: wp.array2d(dtype=float),
|
||||||
|
qMj: wp.array(dtype=int),
|
||||||
|
# Out:
|
||||||
|
qDeriv_out: wp.array3d(dtype=float),
|
||||||
|
):
|
||||||
|
worldid, actid = wp.tid()
|
||||||
|
|
||||||
|
vel = vel_in[worldid, actid]
|
||||||
|
if vel == 0.0:
|
||||||
|
return
|
||||||
|
|
||||||
|
rownnz = moment_rownnz_in[worldid, actid]
|
||||||
|
rowadr = moment_rowadr_in[worldid, actid]
|
||||||
|
|
||||||
|
for i in range(rownnz):
|
||||||
|
rowadri = rowadr + i
|
||||||
|
moment_i = actuator_moment_in[worldid, rowadri]
|
||||||
|
if moment_i == 0.0:
|
||||||
|
continue
|
||||||
|
dofi = moment_colind_in[worldid, rowadri]
|
||||||
|
|
||||||
|
for j in range(i + 1):
|
||||||
|
rowadrj = rowadr + j
|
||||||
|
moment_j = actuator_moment_in[worldid, rowadrj]
|
||||||
|
if moment_j == 0.0:
|
||||||
|
continue
|
||||||
|
dofj = moment_colind_in[worldid, rowadrj]
|
||||||
|
|
||||||
|
contrib = moment_i * moment_j * vel
|
||||||
|
|
||||||
|
# Search the corresponding elemid
|
||||||
|
# TODO: This could be precalculated for improved performance
|
||||||
|
row = dofi
|
||||||
|
col = dofj
|
||||||
|
row_startk = M_rowadr[row] - 1
|
||||||
|
row_nnz = M_rownnz[row]
|
||||||
|
for k in range(row_nnz):
|
||||||
|
row_startk += 1
|
||||||
|
if qMj[row_startk] == col:
|
||||||
|
wp.atomic_add(qDeriv_out[worldid, 0], row_startk, contrib)
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
@wp.kernel
|
@wp.kernel
|
||||||
def _qderiv_actuator_passive(
|
def _qderiv_actuator_passive(
|
||||||
# Model:
|
# Model:
|
||||||
@@ -176,7 +248,7 @@ def _qderiv_actuator_passive(
|
|||||||
else:
|
else:
|
||||||
qderiv = qDeriv_in[worldid, dofiid, dofjid]
|
qderiv = qDeriv_in[worldid, dofiid, dofjid]
|
||||||
|
|
||||||
if not opt_disableflags & DisableBit.DAMPER and dofiid == dofjid:
|
if not (opt_disableflags & DisableBit.DAMPER) and dofiid == dofjid:
|
||||||
qderiv -= dof_damping[worldid % dof_damping.shape[0], dofiid]
|
qderiv -= dof_damping[worldid % dof_damping.shape[0], dofiid]
|
||||||
|
|
||||||
qderiv *= opt_timestep[worldid % opt_timestep.shape[0]]
|
qderiv *= opt_timestep[worldid % opt_timestep.shape[0]]
|
||||||
@@ -196,10 +268,13 @@ def _qderiv_tendon_damping(
|
|||||||
# Model:
|
# Model:
|
||||||
ntendon: int,
|
ntendon: int,
|
||||||
opt_timestep: wp.array(dtype=float),
|
opt_timestep: wp.array(dtype=float),
|
||||||
|
ten_J_rownnz: wp.array(dtype=int),
|
||||||
|
ten_J_rowadr: wp.array(dtype=int),
|
||||||
|
ten_J_colind: wp.array(dtype=int),
|
||||||
tendon_damping: wp.array2d(dtype=float),
|
tendon_damping: wp.array2d(dtype=float),
|
||||||
is_sparse: bool,
|
is_sparse: bool,
|
||||||
# Data in:
|
# Data in:
|
||||||
ten_J_in: wp.array3d(dtype=float),
|
ten_J_in: wp.array2d(dtype=float),
|
||||||
# In:
|
# In:
|
||||||
qMi: wp.array(dtype=int),
|
qMi: wp.array(dtype=int),
|
||||||
qMj: wp.array(dtype=int),
|
qMj: wp.array(dtype=int),
|
||||||
@@ -213,7 +288,24 @@ def _qderiv_tendon_damping(
|
|||||||
qderiv = float(0.0)
|
qderiv = float(0.0)
|
||||||
tendon_damping_id = worldid % tendon_damping.shape[0]
|
tendon_damping_id = worldid % tendon_damping.shape[0]
|
||||||
for tenid in range(ntendon):
|
for tenid in range(ntendon):
|
||||||
qderiv -= ten_J_in[worldid, tenid, dofiid] * ten_J_in[worldid, tenid, dofjid] * tendon_damping[tendon_damping_id, tenid]
|
damping = tendon_damping[tendon_damping_id, tenid]
|
||||||
|
if damping == 0.0:
|
||||||
|
continue
|
||||||
|
|
||||||
|
rownnz = ten_J_rownnz[tenid]
|
||||||
|
rowadr = ten_J_rowadr[tenid]
|
||||||
|
Ji = float(0.0)
|
||||||
|
Jj = float(0.0)
|
||||||
|
for k in range(rownnz):
|
||||||
|
if Ji != 0.0 and Jj != 0.0:
|
||||||
|
break
|
||||||
|
sparseid = rowadr + k
|
||||||
|
colind = ten_J_colind[sparseid]
|
||||||
|
if colind == dofiid:
|
||||||
|
Ji = ten_J_in[worldid, sparseid]
|
||||||
|
if colind == dofjid:
|
||||||
|
Jj = ten_J_in[worldid, sparseid]
|
||||||
|
qderiv -= Ji * Jj * damping
|
||||||
|
|
||||||
qderiv *= opt_timestep[worldid % opt_timestep.shape[0]]
|
qderiv *= opt_timestep[worldid % opt_timestep.shape[0]]
|
||||||
|
|
||||||
@@ -242,41 +334,45 @@ def deriv_smooth_vel(m: Model, d: Data, out: wp.array2d(dtype=float)):
|
|||||||
if ~(m.opt.disableflags & (DisableBit.ACTUATION | DisableBit.DAMPER)):
|
if ~(m.opt.disableflags & (DisableBit.ACTUATION | DisableBit.DAMPER)):
|
||||||
# TODO(team): only clear elements not set by _qderiv_actuator_passive
|
# TODO(team): only clear elements not set by _qderiv_actuator_passive
|
||||||
out.zero_()
|
out.zero_()
|
||||||
if m.nu > 0 and not m.opt.disableflags & DisableBit.ACTUATION:
|
if m.nu > 0 and not (m.opt.disableflags & DisableBit.ACTUATION):
|
||||||
vel = wp.empty((d.nworld, m.nu), dtype=float)
|
vel = wp.empty((d.nworld, m.nu), dtype=float)
|
||||||
wp.launch(
|
wp.launch(
|
||||||
_qderiv_actuator_passive_vel,
|
_qderiv_actuator_passive_vel,
|
||||||
dim=(d.nworld, m.nu),
|
dim=(d.nworld, m.nu),
|
||||||
inputs=[
|
inputs=[
|
||||||
|
m.opt.timestep,
|
||||||
m.actuator_dyntype,
|
m.actuator_dyntype,
|
||||||
m.actuator_gaintype,
|
m.actuator_gaintype,
|
||||||
m.actuator_biastype,
|
m.actuator_biastype,
|
||||||
m.actuator_actadr,
|
m.actuator_actadr,
|
||||||
m.actuator_actnum,
|
m.actuator_actnum,
|
||||||
m.actuator_forcelimited,
|
m.actuator_forcelimited,
|
||||||
|
m.actuator_actlimited,
|
||||||
|
m.actuator_dynprm,
|
||||||
m.actuator_gainprm,
|
m.actuator_gainprm,
|
||||||
m.actuator_biasprm,
|
m.actuator_biasprm,
|
||||||
|
m.actuator_actearly,
|
||||||
m.actuator_forcerange,
|
m.actuator_forcerange,
|
||||||
|
m.actuator_actrange,
|
||||||
d.act,
|
d.act,
|
||||||
d.ctrl,
|
d.ctrl,
|
||||||
|
d.act_dot,
|
||||||
d.actuator_force,
|
d.actuator_force,
|
||||||
],
|
],
|
||||||
outputs=[vel],
|
outputs=[vel],
|
||||||
)
|
)
|
||||||
|
if m.is_sparse:
|
||||||
wp.launch(
|
wp.launch(
|
||||||
_qderiv_actuator_passive_actuation_sparse,
|
_qderiv_actuator_passive_actuation_sparse,
|
||||||
|
dim=(d.nworld, m.nu),
|
||||||
|
inputs=[m.M_rownnz, m.M_rowadr, d.moment_rownnz, d.moment_rowadr, d.moment_colind, d.actuator_moment, vel, qMj],
|
||||||
|
outputs=[out],
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
wp.launch(
|
||||||
|
_qderiv_actuator_passive_actuation_dense,
|
||||||
dim=(d.nworld, qMi.size),
|
dim=(d.nworld, qMi.size),
|
||||||
inputs=[
|
inputs=[m.nu, d.moment_rownnz, d.moment_rowadr, d.moment_colind, d.actuator_moment, vel, qMi, qMj],
|
||||||
m.nu,
|
|
||||||
m.is_sparse,
|
|
||||||
d.moment_rownnz,
|
|
||||||
d.moment_rowadr,
|
|
||||||
d.moment_colind,
|
|
||||||
d.actuator_moment,
|
|
||||||
vel,
|
|
||||||
qMi,
|
|
||||||
qMj,
|
|
||||||
],
|
|
||||||
outputs=[out],
|
outputs=[out],
|
||||||
)
|
)
|
||||||
wp.launch(
|
wp.launch(
|
||||||
@@ -298,11 +394,22 @@ def deriv_smooth_vel(m: Model, d: Data, out: wp.array2d(dtype=float)):
|
|||||||
# TODO(team): directly utilize qM for these settings
|
# TODO(team): directly utilize qM for these settings
|
||||||
wp.copy(out, d.qM)
|
wp.copy(out, d.qM)
|
||||||
|
|
||||||
if not m.opt.disableflags & DisableBit.DAMPER:
|
if not (m.opt.disableflags & DisableBit.DAMPER):
|
||||||
wp.launch(
|
wp.launch(
|
||||||
_qderiv_tendon_damping,
|
_qderiv_tendon_damping,
|
||||||
dim=(d.nworld, qMi.size),
|
dim=(d.nworld, qMi.size),
|
||||||
inputs=[m.ntendon, m.opt.timestep, m.tendon_damping, m.is_sparse, d.ten_J, qMi, qMj],
|
inputs=[
|
||||||
|
m.ntendon,
|
||||||
|
m.opt.timestep,
|
||||||
|
m.ten_J_rownnz,
|
||||||
|
m.ten_J_rowadr,
|
||||||
|
m.ten_J_colind,
|
||||||
|
m.tendon_damping,
|
||||||
|
m.is_sparse,
|
||||||
|
d.ten_J,
|
||||||
|
qMi,
|
||||||
|
qMj,
|
||||||
|
],
|
||||||
outputs=[out],
|
outputs=[out],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+58
-75
@@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
import warp as wp
|
||||||
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src import collision_driver
|
from mujoco.mjx.third_party.mujoco_warp._src import collision_driver
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src import constraint
|
from mujoco.mjx.third_party.mujoco_warp._src import constraint
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src import derivative
|
from mujoco.mjx.third_party.mujoco_warp._src import derivative
|
||||||
@@ -25,7 +27,9 @@ from mujoco.mjx.third_party.mujoco_warp._src import sensor
|
|||||||
from mujoco.mjx.third_party.mujoco_warp._src import smooth
|
from mujoco.mjx.third_party.mujoco_warp._src import smooth
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src import solver
|
from mujoco.mjx.third_party.mujoco_warp._src import solver
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src import util_misc
|
from mujoco.mjx.third_party.mujoco_warp._src import util_misc
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.support import next_act
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.support import xfrc_accumulate
|
from mujoco.mjx.third_party.mujoco_warp._src.support import xfrc_accumulate
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MINVAL
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import BiasType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import BiasType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import Data
|
from mujoco.mjx.third_party.mujoco_warp._src.types import Data
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import DisableBit
|
from mujoco.mjx.third_party.mujoco_warp._src.types import DisableBit
|
||||||
@@ -34,14 +38,12 @@ from mujoco.mjx.third_party.mujoco_warp._src.types import EnableBit
|
|||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import GainType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import GainType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import IntegratorType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import IntegratorType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import JointType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import JointType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MINVAL
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import Model
|
from mujoco.mjx.third_party.mujoco_warp._src.types import Model
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import TileSet
|
from mujoco.mjx.third_party.mujoco_warp._src.types import TileSet
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import TrnType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import TrnType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import vec10f
|
from mujoco.mjx.third_party.mujoco_warp._src.types import vec10f
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import cache_kernel
|
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import cache_kernel
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import event_scope
|
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import event_scope
|
||||||
import warp as wp
|
|
||||||
|
|
||||||
wp.set_module_options({"enable_backward": False})
|
wp.set_module_options({"enable_backward": False})
|
||||||
|
|
||||||
@@ -127,37 +129,6 @@ def _next_velocity(
|
|||||||
qvel_out[worldid, dofid] = qvel_in[worldid, dofid] + qacc_scale_in * qacc_in[worldid, dofid] * timestep
|
qvel_out[worldid, dofid] = qvel_in[worldid, dofid] + qacc_scale_in * qacc_in[worldid, dofid] * timestep
|
||||||
|
|
||||||
|
|
||||||
# TODO(team): kernel analyzer array slice?
|
|
||||||
@wp.func
|
|
||||||
def _next_act(
|
|
||||||
# Model:
|
|
||||||
opt_timestep: float, # kernel_analyzer: ignore
|
|
||||||
actuator_dyntype: int, # kernel_analyzer: ignore
|
|
||||||
actuator_dynprm: vec10f, # kernel_analyzer: ignore
|
|
||||||
actuator_actrange: wp.vec2, # kernel_analyzer: ignore
|
|
||||||
# Data In:
|
|
||||||
act_in: float, # kernel_analyzer: ignore
|
|
||||||
act_dot_in: float, # kernel_analyzer: ignore
|
|
||||||
# In:
|
|
||||||
act_dot_scale: float,
|
|
||||||
clamp: bool,
|
|
||||||
) -> float:
|
|
||||||
# advance actuation
|
|
||||||
if actuator_dyntype == DynType.FILTEREXACT:
|
|
||||||
tau = wp.max(MJ_MINVAL, actuator_dynprm[0])
|
|
||||||
act = act_in + act_dot_scale * act_dot_in * tau * (1.0 - wp.exp(-opt_timestep / tau))
|
|
||||||
elif actuator_dyntype == DynType.USER:
|
|
||||||
return act_in
|
|
||||||
else:
|
|
||||||
act = act_in + act_dot_scale * act_dot_in * opt_timestep
|
|
||||||
|
|
||||||
# clamp to actrange
|
|
||||||
if clamp:
|
|
||||||
act = wp.clamp(act, actuator_actrange[0], actuator_actrange[1])
|
|
||||||
|
|
||||||
return act
|
|
||||||
|
|
||||||
|
|
||||||
@wp.kernel
|
@wp.kernel
|
||||||
def _next_activation(
|
def _next_activation(
|
||||||
# Model:
|
# Model:
|
||||||
@@ -184,7 +155,7 @@ def _next_activation(
|
|||||||
actadr = actuator_actadr[uid]
|
actadr = actuator_actadr[uid]
|
||||||
actnum = actuator_actnum[uid]
|
actnum = actuator_actnum[uid]
|
||||||
for j in range(actadr, actadr + actnum):
|
for j in range(actadr, actadr + actnum):
|
||||||
act = _next_act(
|
act = next_act(
|
||||||
opt_timestep[opt_timestep_id],
|
opt_timestep[opt_timestep_id],
|
||||||
actuator_dyntype[uid],
|
actuator_dyntype[uid],
|
||||||
actuator_dynprm[actuator_dynprm_id, uid],
|
actuator_dynprm[actuator_dynprm_id, uid],
|
||||||
@@ -201,12 +172,16 @@ def _next_activation(
|
|||||||
def _next_time(
|
def _next_time(
|
||||||
# Model:
|
# Model:
|
||||||
opt_timestep: wp.array(dtype=float),
|
opt_timestep: wp.array(dtype=float),
|
||||||
|
is_sparse: bool,
|
||||||
# Data in:
|
# Data in:
|
||||||
nefc_in: wp.array(dtype=int),
|
nefc_in: wp.array(dtype=int),
|
||||||
time_in: wp.array(dtype=float),
|
time_in: wp.array(dtype=float),
|
||||||
|
efc_J_rownnz_in: wp.array2d(dtype=int),
|
||||||
|
efc_J_rowadr_in: wp.array2d(dtype=int),
|
||||||
nworld_in: int,
|
nworld_in: int,
|
||||||
naconmax_in: int,
|
naconmax_in: int,
|
||||||
njmax_in: int,
|
njmax_in: int,
|
||||||
|
njmax_nnz_in: int,
|
||||||
nacon_in: wp.array(dtype=int),
|
nacon_in: wp.array(dtype=int),
|
||||||
ncollision_in: wp.array(dtype=int),
|
ncollision_in: wp.array(dtype=int),
|
||||||
# Data out:
|
# Data out:
|
||||||
@@ -218,6 +193,11 @@ def _next_time(
|
|||||||
|
|
||||||
if nefc > njmax_in:
|
if nefc > njmax_in:
|
||||||
wp.printf("nefc overflow - please increase njmax to %u\n", nefc)
|
wp.printf("nefc overflow - please increase njmax to %u\n", nefc)
|
||||||
|
elif nefc > 0 and is_sparse:
|
||||||
|
efcid = wp.min(nefc, njmax_in) - 1
|
||||||
|
efc_nnz = efc_J_rowadr_in[worldid, efcid] + efc_J_rownnz_in[worldid, efcid]
|
||||||
|
if efc_nnz > njmax_nnz_in:
|
||||||
|
wp.printf("njmax_nnz overflow - please increase njmax_nnz to %u\n", efc_nnz)
|
||||||
|
|
||||||
if worldid == 0:
|
if worldid == 0:
|
||||||
ncollision = ncollision_in[0]
|
ncollision = ncollision_in[0]
|
||||||
@@ -274,7 +254,20 @@ def _advance(m: Model, d: Data, qacc: wp.array, qvel: Optional[wp.array] = None)
|
|||||||
wp.launch(
|
wp.launch(
|
||||||
_next_time,
|
_next_time,
|
||||||
dim=d.nworld,
|
dim=d.nworld,
|
||||||
inputs=[m.opt.timestep, d.nefc, d.time, d.nworld, d.naconmax, d.njmax, d.nacon, d.ncollision],
|
inputs=[
|
||||||
|
m.opt.timestep,
|
||||||
|
m.is_sparse,
|
||||||
|
d.nefc,
|
||||||
|
d.time,
|
||||||
|
d.efc.J_rownnz,
|
||||||
|
d.efc.J_rowadr,
|
||||||
|
d.nworld,
|
||||||
|
d.naconmax,
|
||||||
|
d.njmax,
|
||||||
|
d.njmax_nnz,
|
||||||
|
d.nacon,
|
||||||
|
d.ncollision,
|
||||||
|
],
|
||||||
outputs=[d.time],
|
outputs=[d.time],
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -294,9 +287,7 @@ def _euler_damp_qfrc_sparse(
|
|||||||
timestep = opt_timestep[worldid % opt_timestep.shape[0]]
|
timestep = opt_timestep[worldid % opt_timestep.shape[0]]
|
||||||
|
|
||||||
adr = dof_Madr[tid]
|
adr = dof_Madr[tid]
|
||||||
qM_integration_out[worldid, 0, adr] += (
|
qM_integration_out[worldid, 0, adr] += timestep * dof_damping[worldid % dof_damping.shape[0], tid]
|
||||||
timestep * dof_damping[worldid % dof_damping.shape[0], tid]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@cache_kernel
|
@cache_kernel
|
||||||
@@ -336,7 +327,7 @@ def _tile_euler_dense(tile: TileSet):
|
|||||||
def euler(m: Model, d: Data):
|
def euler(m: Model, d: Data):
|
||||||
"""Euler integrator, semi-implicit in velocity."""
|
"""Euler integrator, semi-implicit in velocity."""
|
||||||
# integrate damping implicitly
|
# integrate damping implicitly
|
||||||
if not m.opt.disableflags & (DisableBit.EULERDAMP | DisableBit.DAMPER):
|
if not (m.opt.disableflags & (DisableBit.EULERDAMP | DisableBit.DAMPER)):
|
||||||
qacc = wp.empty((d.nworld, m.nv), dtype=float)
|
qacc = wp.empty((d.nworld, m.nv), dtype=float)
|
||||||
if m.is_sparse:
|
if m.is_sparse:
|
||||||
qM = wp.clone(d.qM)
|
qM = wp.clone(d.qM)
|
||||||
@@ -571,50 +562,49 @@ def _actuator_velocity(
|
|||||||
actuator_velocity_out[worldid, actid] = vel
|
actuator_velocity_out[worldid, actid] = vel
|
||||||
|
|
||||||
|
|
||||||
@cache_kernel
|
@wp.kernel
|
||||||
def _tendon_velocity(nv: int):
|
def _tendon_velocity(
|
||||||
@wp.kernel(module="unique", enable_backward=False)
|
# Model:
|
||||||
def tendon_velocity(
|
ten_J_rownnz: wp.array(dtype=int),
|
||||||
|
ten_J_rowadr: wp.array(dtype=int),
|
||||||
|
ten_J_colind: wp.array(dtype=int),
|
||||||
# Data in:
|
# Data in:
|
||||||
qvel_in: wp.array2d(dtype=float),
|
qvel_in: wp.array2d(dtype=float),
|
||||||
ten_J_in: wp.array3d(dtype=float),
|
ten_J_in: wp.array2d(dtype=float),
|
||||||
# Data out:
|
# Data out:
|
||||||
ten_velocity_out: wp.array2d(dtype=float),
|
ten_velocity_out: wp.array2d(dtype=float),
|
||||||
):
|
):
|
||||||
worldid, tenid = wp.tid()
|
worldid, tenid = wp.tid()
|
||||||
ten_J_tile = wp.tile_load(ten_J_in[worldid, tenid], shape=wp.static(nv))
|
|
||||||
qvel_tile = wp.tile_load(qvel_in[worldid], shape=wp.static(nv))
|
|
||||||
ten_J_qvel_tile = wp.tile_map(wp.mul, ten_J_tile, qvel_tile)
|
|
||||||
ten_velocity_tile = wp.tile_reduce(wp.add, ten_J_qvel_tile)
|
|
||||||
ten_velocity_out[worldid, tenid] = ten_velocity_tile[0]
|
|
||||||
|
|
||||||
return tendon_velocity
|
velocity = float(0.0)
|
||||||
|
rownnz = ten_J_rownnz[tenid]
|
||||||
|
rowadr = ten_J_rowadr[tenid]
|
||||||
|
for i in range(rownnz):
|
||||||
|
sparseid = rowadr + i
|
||||||
|
J = ten_J_in[worldid, sparseid]
|
||||||
|
if J != 0.0:
|
||||||
|
colind = ten_J_colind[sparseid]
|
||||||
|
velocity += J * qvel_in[worldid, colind]
|
||||||
|
|
||||||
|
ten_velocity_out[worldid, tenid] = velocity
|
||||||
|
|
||||||
|
|
||||||
@event_scope
|
@event_scope
|
||||||
def fwd_velocity(m: Model, d: Data):
|
def fwd_velocity(m: Model, d: Data):
|
||||||
"""Velocity-dependent computations."""
|
"""Velocity-dependent computations."""
|
||||||
wp.launch_tiled(
|
wp.launch(
|
||||||
_actuator_velocity,
|
_actuator_velocity,
|
||||||
dim=(d.nworld, m.nu),
|
dim=(d.nworld, m.nu),
|
||||||
inputs=[
|
inputs=[d.qvel, d.moment_rownnz, d.moment_rowadr, d.moment_colind, d.actuator_moment],
|
||||||
d.qvel,
|
|
||||||
d.moment_rownnz,
|
|
||||||
d.moment_rowadr,
|
|
||||||
d.moment_colind,
|
|
||||||
d.actuator_moment,
|
|
||||||
],
|
|
||||||
outputs=[d.actuator_velocity],
|
outputs=[d.actuator_velocity],
|
||||||
block_dim=m.block_dim.actuator_velocity,
|
block_dim=m.block_dim.actuator_velocity,
|
||||||
)
|
)
|
||||||
|
|
||||||
# TODO(team): sparse version
|
wp.launch(
|
||||||
wp.launch_tiled(
|
_tendon_velocity,
|
||||||
_tendon_velocity(m.nv),
|
|
||||||
dim=(d.nworld, m.ntendon),
|
dim=(d.nworld, m.ntendon),
|
||||||
inputs=[d.qvel, d.ten_J],
|
inputs=[m.ten_J_rownnz, m.ten_J_rowadr, m.ten_J_colind, d.qvel, d.ten_J],
|
||||||
outputs=[d.ten_velocity],
|
outputs=[d.ten_velocity],
|
||||||
block_dim=m.block_dim.tendon_velocity,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
smooth.com_vel(m, d)
|
smooth.com_vel(m, d)
|
||||||
@@ -693,7 +683,7 @@ def _actuator_force(
|
|||||||
if dyntype == DynType.INTEGRATOR or dyntype == DynType.NONE:
|
if dyntype == DynType.INTEGRATOR or dyntype == DynType.NONE:
|
||||||
act = act_in[worldid, act_last]
|
act = act_in[worldid, act_last]
|
||||||
|
|
||||||
ctrl_act = _next_act(
|
ctrl_act = next_act(
|
||||||
opt_timestep[worldid % opt_timestep.shape[0]],
|
opt_timestep[worldid % opt_timestep.shape[0]],
|
||||||
dyntype,
|
dyntype,
|
||||||
dynprm,
|
dynprm,
|
||||||
@@ -720,9 +710,7 @@ def _actuator_force(
|
|||||||
gain = gainprm[0] + gainprm[1] * length + gainprm[2] * velocity
|
gain = gainprm[0] + gainprm[1] * length + gainprm[2] * velocity
|
||||||
elif gaintype == GainType.MUSCLE:
|
elif gaintype == GainType.MUSCLE:
|
||||||
acc0 = actuator_acc0[worldid % actuator_acc0.shape[0], uid]
|
acc0 = actuator_acc0[worldid % actuator_acc0.shape[0], uid]
|
||||||
lengthrange = actuator_lengthrange[
|
lengthrange = actuator_lengthrange[worldid % actuator_lengthrange.shape[0], uid]
|
||||||
worldid % actuator_lengthrange.shape[0], uid
|
|
||||||
]
|
|
||||||
gain = util_misc.muscle_gain(length, velocity, lengthrange, acc0, gainprm)
|
gain = util_misc.muscle_gain(length, velocity, lengthrange, acc0, gainprm)
|
||||||
# GainType.USER: gain stays 0, modified by act_gain_callback
|
# GainType.USER: gain stays 0, modified by act_gain_callback
|
||||||
|
|
||||||
@@ -735,9 +723,7 @@ def _actuator_force(
|
|||||||
bias = biasprm[0] + biasprm[1] * length + biasprm[2] * velocity
|
bias = biasprm[0] + biasprm[1] * length + biasprm[2] * velocity
|
||||||
elif biastype == BiasType.MUSCLE:
|
elif biastype == BiasType.MUSCLE:
|
||||||
acc0 = actuator_acc0[worldid % actuator_acc0.shape[0], uid]
|
acc0 = actuator_acc0[worldid % actuator_acc0.shape[0], uid]
|
||||||
lengthrange = actuator_lengthrange[
|
lengthrange = actuator_lengthrange[worldid % actuator_lengthrange.shape[0], uid]
|
||||||
worldid % actuator_lengthrange.shape[0], uid
|
|
||||||
]
|
|
||||||
bias = util_misc.muscle_bias(length, lengthrange, acc0, biasprm)
|
bias = util_misc.muscle_bias(length, lengthrange, acc0, biasprm)
|
||||||
|
|
||||||
force = gain * ctrl_act + bias
|
force = gain * ctrl_act + bias
|
||||||
@@ -812,10 +798,7 @@ def _qfrc_actuator(
|
|||||||
for i in range(rownnz):
|
for i in range(rownnz):
|
||||||
sparseid = rowadr + i
|
sparseid = rowadr + i
|
||||||
colind = moment_colind_in[worldid, sparseid]
|
colind = moment_colind_in[worldid, sparseid]
|
||||||
qfrc = (
|
qfrc = actuator_moment_in[worldid, sparseid] * actuator_force_in[worldid, actid]
|
||||||
actuator_moment_in[worldid, sparseid]
|
|
||||||
* actuator_force_in[worldid, actid]
|
|
||||||
)
|
|
||||||
wp.atomic_add(qfrc_actuator_out[worldid], colind, qfrc)
|
wp.atomic_add(qfrc_actuator_out[worldid], colind, qfrc)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+387
-259
@@ -14,24 +14,24 @@
|
|||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|
||||||
import dataclasses
|
import dataclasses
|
||||||
from typing import Any, Optional, Sequence
|
|
||||||
import warnings
|
import warnings
|
||||||
|
from typing import Any, Optional, Sequence
|
||||||
|
|
||||||
import mujoco
|
import mujoco
|
||||||
|
import numpy as np
|
||||||
|
import warp as wp
|
||||||
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src import bvh
|
from mujoco.mjx.third_party.mujoco_warp._src import bvh
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src import math as mjmath
|
from mujoco.mjx.third_party.mujoco_warp._src import math as mjmath
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src import render_util
|
from mujoco.mjx.third_party.mujoco_warp._src import render_util
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src import smooth
|
from mujoco.mjx.third_party.mujoco_warp._src import smooth
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src import types
|
from mujoco.mjx.third_party.mujoco_warp._src import types
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src import warp_util
|
from mujoco.mjx.third_party.mujoco_warp._src import warp_util
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import BiasType
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MINVAL
|
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MINVAL
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import SPARSE_CONSTRAINT_JACOBIAN
|
from mujoco.mjx.third_party.mujoco_warp._src.types import BiasType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import TrnType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import TrnType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import vec10
|
from mujoco.mjx.third_party.mujoco_warp._src.types import vec10
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.util_pkg import check_version
|
from mujoco.mjx.third_party.mujoco_warp._src.util_pkg import check_version
|
||||||
import numpy as np
|
|
||||||
import warp as wp
|
|
||||||
|
|
||||||
|
|
||||||
def _create_array(data: Any, spec: wp.array, sizes: dict[str, int]) -> wp.array | None:
|
def _create_array(data: Any, spec: wp.array, sizes: dict[str, int]) -> wp.array | None:
|
||||||
@@ -114,9 +114,6 @@ def put_model(mjm: mujoco.MjModel) -> types.Model:
|
|||||||
if unsupported:
|
if unsupported:
|
||||||
raise NotImplementedError(f"{mj_type(unsupported).name} is unsupported.")
|
raise NotImplementedError(f"{mj_type(unsupported).name} is unsupported.")
|
||||||
|
|
||||||
if ((mjm.flex_contype != 0) | (mjm.flex_conaffinity != 0)).any():
|
|
||||||
raise NotImplementedError("Flex collisions are not implemented.")
|
|
||||||
|
|
||||||
if mjm.opt.noslip_iterations > 0:
|
if mjm.opt.noslip_iterations > 0:
|
||||||
raise NotImplementedError(f"noslip solver not implemented.")
|
raise NotImplementedError(f"noslip solver not implemented.")
|
||||||
|
|
||||||
@@ -226,6 +223,8 @@ def put_model(mjm: mujoco.MjModel) -> types.Model:
|
|||||||
m.is_sparse = is_sparse(mjm)
|
m.is_sparse = is_sparse(mjm)
|
||||||
m.has_fluid = mjm.opt.wind.any() or mjm.opt.density > 0 or mjm.opt.viscosity > 0
|
m.has_fluid = mjm.opt.wind.any() or mjm.opt.density > 0 or mjm.opt.viscosity > 0
|
||||||
|
|
||||||
|
m.max_ten_J_rownnz = int(mjm.ten_J_rownnz.max()) if mjm.ntendon else 0
|
||||||
|
|
||||||
# body ids grouped by tree level (depth-based traversal)
|
# body ids grouped by tree level (depth-based traversal)
|
||||||
bodies, body_depth = {}, np.zeros(mjm.nbody, dtype=int) - 1
|
bodies, body_depth = {}, np.zeros(mjm.nbody, dtype=int) - 1
|
||||||
for i in range(mjm.nbody):
|
for i in range(mjm.nbody):
|
||||||
@@ -364,6 +363,46 @@ def put_model(mjm: mujoco.MjModel) -> types.Model:
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# check for unsupported margin + multicontact / box-box CCD combinations
|
||||||
|
use_multiccd = mjm.opt.enableflags & types.EnableBit.MULTICCD
|
||||||
|
nativeccd_disabled = mjm.opt.disableflags & types.DisableBit.NATIVECCD
|
||||||
|
BOX = int(mujoco.mjtGeom.mjGEOM_BOX)
|
||||||
|
MESH = int(mujoco.mjtGeom.mjGEOM_MESH)
|
||||||
|
|
||||||
|
has_boxbox = m.geom_pair_type_count[geom_trid_index(BOX, BOX)] > 0
|
||||||
|
has_multiccd_pairs = has_boxbox or (
|
||||||
|
use_multiccd
|
||||||
|
and (m.geom_pair_type_count[geom_trid_index(BOX, MESH)] > 0 or m.geom_pair_type_count[geom_trid_index(MESH, MESH)] > 0)
|
||||||
|
)
|
||||||
|
|
||||||
|
if has_multiccd_pairs:
|
||||||
|
|
||||||
|
def _check_margin(name, t1, t2, margin):
|
||||||
|
if use_multiccd:
|
||||||
|
raise NotImplementedError(
|
||||||
|
f"{name} has non-zero margin ({margin}) with MULTICCD enabled. Set margin to 0 or disable MULTICCD."
|
||||||
|
)
|
||||||
|
if t1 == BOX and t2 == BOX and not nativeccd_disabled:
|
||||||
|
raise NotImplementedError(
|
||||||
|
f"{name} has non-zero margin ({margin}) with NATIVECCD enabled. Set margin to 0 or disable NATIVECCD."
|
||||||
|
)
|
||||||
|
|
||||||
|
geom_name = lambda g: mujoco.mj_id2name(mjm, mujoco.mjtObj.mjOBJ_GEOM, g) or str(g)
|
||||||
|
|
||||||
|
for idx in np.nonzero(nxn_include & (nxn_pairid_contact == -1))[0]:
|
||||||
|
g1, g2 = int(geom1[idx]), int(geom2[idx])
|
||||||
|
t1, t2 = int(mjm.geom_type[g1]), int(mjm.geom_type[g2])
|
||||||
|
m1, m2 = float(mjm.geom_margin[g1]), float(mjm.geom_margin[g2])
|
||||||
|
if (m1 or m2) and t1 in (BOX, MESH) and t2 in (BOX, MESH):
|
||||||
|
_check_margin(f"geom pair ({geom_name(g1)}, {geom_name(g2)})", t1, t2, (m1, m2))
|
||||||
|
|
||||||
|
for pid in range(mjm.npair):
|
||||||
|
g1, g2 = int(mjm.pair_geom1[pid]), int(mjm.pair_geom2[pid])
|
||||||
|
t1, t2 = int(mjm.geom_type[g1]), int(mjm.geom_type[g2])
|
||||||
|
pm = float(mjm.pair_margin[pid])
|
||||||
|
if pm and t1 in (BOX, MESH) and t2 in (BOX, MESH):
|
||||||
|
_check_margin(f"pair {pid} ({geom_name(g1)}, {geom_name(g2)})", t1, t2, pm)
|
||||||
|
|
||||||
m.nmaxpolygon = np.append(mjm.mesh_polyvertnum, 0).max()
|
m.nmaxpolygon = np.append(mjm.mesh_polyvertnum, 0).max()
|
||||||
m.nmaxmeshdeg = np.append(mjm.mesh_polymapnum, 0).max()
|
m.nmaxmeshdeg = np.append(mjm.mesh_polymapnum, 0).max()
|
||||||
|
|
||||||
@@ -390,9 +429,11 @@ def put_model(mjm: mujoco.MjModel) -> types.Model:
|
|||||||
current = []
|
current = []
|
||||||
else:
|
else:
|
||||||
current.append(v)
|
current.append(v)
|
||||||
# Pad with zeros if less than 3
|
if len(attr_values) > types._NPLUGINATTR:
|
||||||
attr_values += [0.0] * (3 - len(attr_values))
|
raise ValueError(f"Plugin has {len(attr_values)} attributes, which exceeds the maximum of {types._NPLUGINATTR}. ")
|
||||||
m.plugin_attr.append(attr_values[:3])
|
# pad with zeros to _NPLUGINATTR
|
||||||
|
attr_values += [0.0] * (types._NPLUGINATTR - len(attr_values))
|
||||||
|
m.plugin_attr.append(attr_values[: types._NPLUGINATTR])
|
||||||
|
|
||||||
# equality constraint addresses
|
# equality constraint addresses
|
||||||
m.eq_connect_adr = np.nonzero(mjm.eq_type == types.EqType.CONNECT)[0]
|
m.eq_connect_adr = np.nonzero(mjm.eq_type == types.EqType.CONNECT)[0]
|
||||||
@@ -542,6 +583,15 @@ def put_model(mjm: mujoco.MjModel) -> types.Model:
|
|||||||
Madr_ki -= 1
|
Madr_ki -= 1
|
||||||
m.qLD_updates = tuple(wp.array(qLD_updates[i], dtype=wp.vec3i) for i in sorted(qLD_updates))
|
m.qLD_updates = tuple(wp.array(qLD_updates[i], dtype=wp.vec3i) for i in sorted(qLD_updates))
|
||||||
|
|
||||||
|
# Build concatenated updates for fused kernel
|
||||||
|
all_updates_flat = []
|
||||||
|
level_offsets = [0]
|
||||||
|
for level in sorted(qLD_updates):
|
||||||
|
all_updates_flat.extend(qLD_updates[level])
|
||||||
|
level_offsets.append(len(all_updates_flat))
|
||||||
|
m.qLD_all_updates = all_updates_flat if all_updates_flat else [(0, 0, 0)]
|
||||||
|
m.qLD_level_offsets = level_offsets
|
||||||
|
|
||||||
# indices for sparse qM_fullm (used in solver)
|
# indices for sparse qM_fullm (used in solver)
|
||||||
m.qM_fullm_i, m.qM_fullm_j = [], []
|
m.qM_fullm_i, m.qM_fullm_j = [], []
|
||||||
for i in range(mjm.nv):
|
for i in range(mjm.nv):
|
||||||
@@ -631,9 +681,168 @@ def _default_njmax(mjm: mujoco.MjModel, mjd: Optional[mujoco.MjData] = None) ->
|
|||||||
return int(valid_sizes[np.searchsorted(valid_sizes, njmax)])
|
return int(valid_sizes[np.searchsorted(valid_sizes, njmax)])
|
||||||
|
|
||||||
|
|
||||||
def _resolve_batch_size(
|
def _body_pair_nnz(mjm: mujoco.MjModel, body1: int, body2: int) -> int:
|
||||||
na: int | None, n: int | None, nworld: int, default: int
|
"""Returns the number of unique DOFs in the kinematic tree union of two bodies."""
|
||||||
) -> int:
|
body1 = mjm.body_weldid[body1]
|
||||||
|
body2 = mjm.body_weldid[body2]
|
||||||
|
da1 = mjm.body_dofadr[body1] + mjm.body_dofnum[body1] - 1
|
||||||
|
da2 = mjm.body_dofadr[body2] + mjm.body_dofnum[body2] - 1
|
||||||
|
nnz = 0
|
||||||
|
while da1 >= 0 or da2 >= 0:
|
||||||
|
da = max(da1, da2)
|
||||||
|
if da1 == da:
|
||||||
|
da1 = mjm.dof_parentid[da1]
|
||||||
|
if da2 == da:
|
||||||
|
da2 = mjm.dof_parentid[da2]
|
||||||
|
nnz += 1
|
||||||
|
return nnz
|
||||||
|
|
||||||
|
|
||||||
|
def _default_njmax_nnz(mjm: mujoco.MjModel, nconmax: int, njmax: int) -> int:
|
||||||
|
"""Returns a heuristic estimate for the number of non-zeros in the sparse constraint Jacobian.
|
||||||
|
|
||||||
|
Assumes all equality, friction, and limit constraints are active and computes
|
||||||
|
their non-zeros. For contacts, assumes njmax contact rows at the maximum
|
||||||
|
body-pair non-zeros from all enabled collision pairs.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
mjm: The model containing kinematic and dynamic information (host).
|
||||||
|
nconmax: Maximum number of contacts per world.
|
||||||
|
njmax: Maximum number of constraint rows per world.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Estimated number of non-zeros in the constraint Jacobian.
|
||||||
|
"""
|
||||||
|
total_nnz = 0
|
||||||
|
|
||||||
|
def _eq_bodies(i):
|
||||||
|
"""Returns body pair for equality constraint i."""
|
||||||
|
obj1id, obj2id = mjm.eq_obj1id[i], mjm.eq_obj2id[i]
|
||||||
|
if mjm.eq_objtype[i] == mujoco.mjtObj.mjOBJ_SITE:
|
||||||
|
return mjm.site_bodyid[obj1id], mjm.site_bodyid[obj2id]
|
||||||
|
return obj1id, obj2id
|
||||||
|
|
||||||
|
# equality constraints (assume all active)
|
||||||
|
for i in range(mjm.neq):
|
||||||
|
eq_type = mjm.eq_type[i]
|
||||||
|
|
||||||
|
if eq_type == mujoco.mjtEq.mjEQ_CONNECT:
|
||||||
|
total_nnz += 3 * _body_pair_nnz(mjm, *_eq_bodies(i))
|
||||||
|
|
||||||
|
elif eq_type == mujoco.mjtEq.mjEQ_WELD:
|
||||||
|
total_nnz += 6 * _body_pair_nnz(mjm, *_eq_bodies(i))
|
||||||
|
|
||||||
|
elif eq_type == mujoco.mjtEq.mjEQ_JOINT:
|
||||||
|
total_nnz += 2 if mjm.eq_obj2id[i] >= 0 else 1
|
||||||
|
|
||||||
|
elif eq_type == mujoco.mjtEq.mjEQ_TENDON:
|
||||||
|
obj1id = mjm.eq_obj1id[i]
|
||||||
|
obj2id = mjm.eq_obj2id[i]
|
||||||
|
rownnz1 = mjm.ten_J_rownnz[obj1id] if obj1id < mjm.ntendon else 0
|
||||||
|
if obj2id >= 0 and obj2id < mjm.ntendon:
|
||||||
|
rowadr1 = mjm.ten_J_rowadr[obj1id]
|
||||||
|
rowadr2 = mjm.ten_J_rowadr[obj2id]
|
||||||
|
rownnz2 = mjm.ten_J_rownnz[obj2id]
|
||||||
|
cols = set()
|
||||||
|
for j in range(rownnz1):
|
||||||
|
cols.add(mjm.ten_J_colind[rowadr1 + j])
|
||||||
|
for j in range(rownnz2):
|
||||||
|
cols.add(mjm.ten_J_colind[rowadr2 + j])
|
||||||
|
total_nnz += len(cols)
|
||||||
|
else:
|
||||||
|
total_nnz += rownnz1
|
||||||
|
|
||||||
|
elif eq_type == mujoco.mjtEq.mjEQ_FLEX:
|
||||||
|
obj1id = mjm.eq_obj1id[i]
|
||||||
|
if obj1id < mjm.nflex:
|
||||||
|
edge_start = mjm.flex_edgeadr[obj1id]
|
||||||
|
edge_count = mjm.flex_edgenum[obj1id]
|
||||||
|
for e in range(edge_count):
|
||||||
|
total_nnz += mjm.flexedge_J_rownnz[edge_start + e]
|
||||||
|
|
||||||
|
# friction constraints
|
||||||
|
total_nnz += (mjm.dof_frictionloss > 0).sum()
|
||||||
|
for i in range(mjm.ntendon):
|
||||||
|
if mjm.tendon_frictionloss[i] > 0:
|
||||||
|
total_nnz += mjm.ten_J_rownnz[i]
|
||||||
|
|
||||||
|
# limit constraints (assume all active)
|
||||||
|
for i in range(mjm.njnt):
|
||||||
|
if mjm.jnt_limited[i]:
|
||||||
|
jnt_type = mjm.jnt_type[i]
|
||||||
|
if jnt_type == mujoco.mjtJoint.mjJNT_BALL:
|
||||||
|
total_nnz += 3
|
||||||
|
elif jnt_type in (mujoco.mjtJoint.mjJNT_SLIDE, mujoco.mjtJoint.mjJNT_HINGE):
|
||||||
|
total_nnz += 1
|
||||||
|
for i in range(mjm.ntendon):
|
||||||
|
if mjm.tendon_limited[i]:
|
||||||
|
total_nnz += mjm.ten_J_rownnz[i]
|
||||||
|
|
||||||
|
# contact constraints: njmax rows at max body-pair non-zeros
|
||||||
|
max_contact_nnz = 0
|
||||||
|
|
||||||
|
# contact pairs
|
||||||
|
for i in range(mjm.npair):
|
||||||
|
g1, g2 = mjm.pair_geom1[i], mjm.pair_geom2[i]
|
||||||
|
b1, b2 = mjm.geom_bodyid[g1], mjm.geom_bodyid[g2]
|
||||||
|
max_contact_nnz = max(max_contact_nnz, _body_pair_nnz(mjm, b1, b2))
|
||||||
|
|
||||||
|
# filter geom-geom pairs (unique body pairs, filtered)
|
||||||
|
body_pair_seen = set()
|
||||||
|
for i in range(mjm.ngeom):
|
||||||
|
bi = mjm.geom_bodyid[i]
|
||||||
|
cti, cai = mjm.geom_contype[i], mjm.geom_conaffinity[i]
|
||||||
|
for j in range(i + 1, mjm.ngeom):
|
||||||
|
bj = mjm.geom_bodyid[j]
|
||||||
|
if bi == bj:
|
||||||
|
continue
|
||||||
|
if mjm.body_weldid[bi] == 0 and mjm.body_weldid[bj] == 0:
|
||||||
|
continue
|
||||||
|
bp = (min(bi, bj), max(bi, bj))
|
||||||
|
if bp in body_pair_seen:
|
||||||
|
continue
|
||||||
|
ctj, caj = mjm.geom_contype[j], mjm.geom_conaffinity[j]
|
||||||
|
if not ((cti & caj) or (ctj & cai)):
|
||||||
|
continue
|
||||||
|
body_pair_seen.add(bp)
|
||||||
|
max_contact_nnz = max(max_contact_nnz, _body_pair_nnz(mjm, bi, bj))
|
||||||
|
|
||||||
|
# flex vertex contacts
|
||||||
|
for fi in range(mjm.nflex):
|
||||||
|
fct = mjm.flex_contype[fi]
|
||||||
|
fca = mjm.flex_conaffinity[fi]
|
||||||
|
|
||||||
|
vert_start = mjm.flex_vertadr[fi]
|
||||||
|
vert_count = mjm.flex_vertnum[fi]
|
||||||
|
flex_bodies = {mjm.flex_vertbodyid[vert_start + v] for v in range(vert_count)}
|
||||||
|
|
||||||
|
geom_bodies = set()
|
||||||
|
for g in range(mjm.ngeom):
|
||||||
|
ct, ca = mjm.geom_contype[g], mjm.geom_conaffinity[g]
|
||||||
|
if (fct & ca) or (ct & fca):
|
||||||
|
geom_bodies.add(mjm.geom_bodyid[g])
|
||||||
|
|
||||||
|
for fb in flex_bodies:
|
||||||
|
for gb in geom_bodies:
|
||||||
|
if fb != gb:
|
||||||
|
max_contact_nnz = max(max_contact_nnz, _body_pair_nnz(mjm, fb, gb))
|
||||||
|
|
||||||
|
# flex self-collision
|
||||||
|
if mjm.flex_selfcollide[fi]:
|
||||||
|
flex_body_list = sorted(flex_bodies)
|
||||||
|
for idx1 in range(len(flex_body_list)):
|
||||||
|
for idx2 in range(idx1 + 1, len(flex_body_list)):
|
||||||
|
max_contact_nnz = max(
|
||||||
|
max_contact_nnz,
|
||||||
|
_body_pair_nnz(mjm, flex_body_list[idx1], flex_body_list[idx2]),
|
||||||
|
)
|
||||||
|
|
||||||
|
total_nnz += njmax * max_contact_nnz
|
||||||
|
|
||||||
|
return int(min(max(total_nnz, 1), njmax * mjm.nv))
|
||||||
|
|
||||||
|
|
||||||
|
def _resolve_batch_size(na: int | None, n: int | None, nworld: int, default: int) -> int:
|
||||||
if na is not None:
|
if na is not None:
|
||||||
return na
|
return na
|
||||||
if n is not None:
|
if n is not None:
|
||||||
@@ -647,6 +856,7 @@ def make_data(
|
|||||||
nconmax: Optional[int] = None,
|
nconmax: Optional[int] = None,
|
||||||
nccdmax: Optional[int] = None,
|
nccdmax: Optional[int] = None,
|
||||||
njmax: Optional[int] = None,
|
njmax: Optional[int] = None,
|
||||||
|
njmax_nnz: Optional[int] = None,
|
||||||
naconmax: Optional[int] = None,
|
naconmax: Optional[int] = None,
|
||||||
naccdmax: Optional[int] = None,
|
naccdmax: Optional[int] = None,
|
||||||
) -> types.Data:
|
) -> types.Data:
|
||||||
@@ -660,6 +870,7 @@ def make_data(
|
|||||||
nccdmax: Number of CCD contacts to allocate per world. Same semantics as nconmax.
|
nccdmax: Number of CCD contacts to allocate per world. Same semantics as nconmax.
|
||||||
njmax: Number of constraints to allocate per world. Constraint arrays are
|
njmax: Number of constraints to allocate per world. Constraint arrays are
|
||||||
batched by world: no world may have more than njmax constraints.
|
batched by world: no world may have more than njmax constraints.
|
||||||
|
njmax_nnz: Number of non-zeros in constraint Jacobian (sparse). Defaults to njmax * nv.
|
||||||
naconmax: Number of contacts to allocate for all worlds. Overrides nconmax.
|
naconmax: Number of contacts to allocate for all worlds. Overrides nconmax.
|
||||||
naccdmax: Maximum number of CCD contacts. Defaults to naconmax.
|
naccdmax: Maximum number of CCD contacts. Defaults to naconmax.
|
||||||
|
|
||||||
@@ -709,20 +920,32 @@ def make_data(
|
|||||||
sizes["naconmax"] = naconmax
|
sizes["naconmax"] = naconmax
|
||||||
sizes["njmax"] = njmax
|
sizes["njmax"] = njmax
|
||||||
|
|
||||||
|
if njmax_nnz is None:
|
||||||
|
if is_sparse(mjm):
|
||||||
|
njmax_nnz = _default_njmax_nnz(mjm, nconmax, njmax)
|
||||||
|
else:
|
||||||
|
njmax_nnz = njmax * mjm.nv
|
||||||
|
|
||||||
contact = types.Contact(**{f.name: _create_array(None, f.type, sizes) for f in dataclasses.fields(types.Contact)})
|
contact = types.Contact(**{f.name: _create_array(None, f.type, sizes) for f in dataclasses.fields(types.Contact)})
|
||||||
|
contact.efc_address = wp.array(np.full((naconmax, sizes["nmaxpyramid"]), -1, dtype=int), dtype=int)
|
||||||
efc = types.Constraint(**{f.name: _create_array(None, f.type, sizes) for f in dataclasses.fields(types.Constraint)})
|
efc = types.Constraint(**{f.name: _create_array(None, f.type, sizes) for f in dataclasses.fields(types.Constraint)})
|
||||||
|
|
||||||
if SPARSE_CONSTRAINT_JACOBIAN:
|
if is_sparse(mjm):
|
||||||
efc.J_rownnz = wp.zeros((nworld, njmax), dtype=int)
|
efc.J_rownnz = wp.zeros((nworld, njmax), dtype=int)
|
||||||
efc.J_rowadr = wp.zeros((nworld, njmax), dtype=int)
|
efc.J_rowadr = wp.zeros((nworld, njmax), dtype=int)
|
||||||
efc.J_colind = wp.zeros((nworld, 1, njmax * mjm.nv), dtype=int)
|
efc.J_colind = wp.zeros((nworld, 1, njmax_nnz), dtype=int)
|
||||||
efc.J = wp.zeros((nworld, 1, njmax * mjm.nv), dtype=float)
|
efc.J = wp.zeros((nworld, 1, njmax_nnz), dtype=float)
|
||||||
else:
|
else:
|
||||||
efc.J_rownnz = wp.zeros((nworld, 0), dtype=int)
|
efc.J_rownnz = wp.zeros((nworld, 0), dtype=int)
|
||||||
efc.J_rowadr = wp.zeros((nworld, 0), dtype=int)
|
efc.J_rowadr = wp.zeros((nworld, 0), dtype=int)
|
||||||
efc.J_colind = wp.zeros((nworld, 0, 0), dtype=int)
|
efc.J_colind = wp.zeros((nworld, 0, 0), dtype=int)
|
||||||
efc.J = wp.zeros((nworld, sizes["njmax_pad"], sizes["nv_pad"]), dtype=float)
|
efc.J = wp.zeros((nworld, sizes["njmax_pad"], sizes["nv_pad"]), dtype=float)
|
||||||
|
|
||||||
|
contact_kwargs = {}
|
||||||
|
for f in dataclasses.fields(types.Contact):
|
||||||
|
contact_kwargs[f.name] = _create_array(None, f.type, sizes)
|
||||||
|
contact = types.Contact(**contact_kwargs)
|
||||||
|
|
||||||
# world body and static geom (attached to the world) poses are precomputed
|
# world body and static geom (attached to the world) poses are precomputed
|
||||||
# this speeds up scenes with many static geoms (e.g. terrains)
|
# this speeds up scenes with many static geoms (e.g. terrains)
|
||||||
# TODO(team): remove this when we introduce dof islands + sleeping
|
# TODO(team): remove this when we introduce dof islands + sleeping
|
||||||
@@ -734,9 +957,7 @@ def make_data(
|
|||||||
mocap_id = mjm.body_mocapid[mocap_body]
|
mocap_id = mjm.body_mocapid[mocap_body]
|
||||||
|
|
||||||
d_kwargs = {
|
d_kwargs = {
|
||||||
"qpos": wp.array(
|
"qpos": wp.array(np.tile(mjm.qpos0, nworld), shape=(nworld, mjm.nq), dtype=float),
|
||||||
np.tile(mjm.qpos0, nworld), shape=(nworld, mjm.nq), dtype=float
|
|
||||||
),
|
|
||||||
"contact": contact,
|
"contact": contact,
|
||||||
"efc": efc,
|
"efc": efc,
|
||||||
"nworld": nworld,
|
"nworld": nworld,
|
||||||
@@ -744,52 +965,23 @@ def make_data(
|
|||||||
"naccdmax": naccdmax,
|
"naccdmax": naccdmax,
|
||||||
"njmax": njmax,
|
"njmax": njmax,
|
||||||
"njmax_pad": sizes["njmax_pad"],
|
"njmax_pad": sizes["njmax_pad"],
|
||||||
|
"njmax_nnz": njmax_nnz,
|
||||||
"qM": None,
|
"qM": None,
|
||||||
"qLD": None,
|
"qLD": None,
|
||||||
# world body
|
# world body
|
||||||
"xquat": wp.array(
|
"xquat": wp.array(np.tile(mjd.xquat, (nworld, 1)), shape=(nworld, mjm.nbody), dtype=wp.quat),
|
||||||
np.tile(mjd.xquat, (nworld, 1)),
|
"xmat": wp.array(np.tile(mjd.xmat, (nworld, 1)), shape=(nworld, mjm.nbody), dtype=wp.mat33),
|
||||||
shape=(nworld, mjm.nbody),
|
"ximat": wp.array(np.tile(mjd.ximat, (nworld, 1)), shape=(nworld, mjm.nbody), dtype=wp.mat33),
|
||||||
dtype=wp.quat,
|
|
||||||
),
|
|
||||||
"xmat": wp.array(
|
|
||||||
np.tile(mjd.xmat, (nworld, 1)),
|
|
||||||
shape=(nworld, mjm.nbody),
|
|
||||||
dtype=wp.mat33,
|
|
||||||
),
|
|
||||||
"ximat": wp.array(
|
|
||||||
np.tile(mjd.ximat, (nworld, 1)),
|
|
||||||
shape=(nworld, mjm.nbody),
|
|
||||||
dtype=wp.mat33,
|
|
||||||
),
|
|
||||||
# static geoms
|
# static geoms
|
||||||
"geom_xpos": wp.array(
|
"geom_xpos": wp.array(np.tile(mjd.geom_xpos, (nworld, 1)), shape=(nworld, mjm.ngeom), dtype=wp.vec3),
|
||||||
np.tile(mjd.geom_xpos, (nworld, 1)),
|
"geom_xmat": wp.array(np.tile(mjd.geom_xmat, (nworld, 1)), shape=(nworld, mjm.ngeom), dtype=wp.mat33),
|
||||||
shape=(nworld, mjm.ngeom),
|
|
||||||
dtype=wp.vec3,
|
|
||||||
),
|
|
||||||
"geom_xmat": wp.array(
|
|
||||||
np.tile(mjd.geom_xmat, (nworld, 1)),
|
|
||||||
shape=(nworld, mjm.ngeom),
|
|
||||||
dtype=wp.mat33,
|
|
||||||
),
|
|
||||||
# mocap
|
# mocap
|
||||||
"mocap_pos": wp.array(
|
"mocap_pos": wp.array(np.tile(mjm.body_pos[mocap_body[mocap_id]], (nworld, 1)), shape=(nworld, mjm.nmocap), dtype=wp.vec3),
|
||||||
np.tile(mjm.body_pos[mocap_body[mocap_id]], (nworld, 1)),
|
|
||||||
shape=(nworld, mjm.nmocap),
|
|
||||||
dtype=wp.vec3,
|
|
||||||
),
|
|
||||||
"mocap_quat": wp.array(
|
"mocap_quat": wp.array(
|
||||||
np.tile(mjm.body_quat[mocap_body[mocap_id]], (nworld, 1)),
|
np.tile(mjm.body_quat[mocap_body[mocap_id]], (nworld, 1)), shape=(nworld, mjm.nmocap), dtype=wp.quat
|
||||||
shape=(nworld, mjm.nmocap),
|
|
||||||
dtype=wp.quat,
|
|
||||||
),
|
),
|
||||||
# equality constraints
|
# equality constraints
|
||||||
"eq_active": wp.array(
|
"eq_active": wp.array(np.tile(mjm.eq_active0.astype(bool), (nworld, 1)), shape=(nworld, mjm.neq), dtype=bool),
|
||||||
np.tile(mjm.eq_active0.astype(bool), (nworld, 1)),
|
|
||||||
shape=(nworld, mjm.neq),
|
|
||||||
dtype=bool,
|
|
||||||
),
|
|
||||||
# island arrays
|
# island arrays
|
||||||
"nisland": None,
|
"nisland": None,
|
||||||
"tree_island": None,
|
"tree_island": None,
|
||||||
@@ -822,6 +1014,7 @@ def put_data(
|
|||||||
nconmax: Optional[int] = None,
|
nconmax: Optional[int] = None,
|
||||||
nccdmax: Optional[int] = None,
|
nccdmax: Optional[int] = None,
|
||||||
njmax: Optional[int] = None,
|
njmax: Optional[int] = None,
|
||||||
|
njmax_nnz: Optional[int] = None,
|
||||||
naconmax: Optional[int] = None,
|
naconmax: Optional[int] = None,
|
||||||
naccdmax: Optional[int] = None,
|
naccdmax: Optional[int] = None,
|
||||||
) -> types.Data:
|
) -> types.Data:
|
||||||
@@ -836,6 +1029,7 @@ def put_data(
|
|||||||
nccdmax: Number of CCD contacts to allocate per world. Same semantics as nconmax.
|
nccdmax: Number of CCD contacts to allocate per world. Same semantics as nconmax.
|
||||||
njmax: Number of constraints to allocate per world. Constraint arrays are
|
njmax: Number of constraints to allocate per world. Constraint arrays are
|
||||||
batched by world: no world may have more than njmax constraints.
|
batched by world: no world may have more than njmax constraints.
|
||||||
|
njmax_nnz: Number of non-zeros in constraint Jacobian (sparse). Defaults to njmax * nv.
|
||||||
naconmax: Number of contacts to allocate for all worlds. Overrides nconmax.
|
naconmax: Number of contacts to allocate for all worlds. Overrides nconmax.
|
||||||
naccdmax: Maximum number of CCD contacts. Defaults to naconmax.
|
naccdmax: Maximum number of CCD contacts. Defaults to naconmax.
|
||||||
|
|
||||||
@@ -898,6 +1092,12 @@ def put_data(
|
|||||||
sizes["naconmax"] = naconmax
|
sizes["naconmax"] = naconmax
|
||||||
sizes["njmax"] = njmax
|
sizes["njmax"] = njmax
|
||||||
|
|
||||||
|
if njmax_nnz is None:
|
||||||
|
if is_sparse(mjm):
|
||||||
|
njmax_nnz = _default_njmax_nnz(mjm, nconmax, njmax)
|
||||||
|
else:
|
||||||
|
njmax_nnz = njmax * mjm.nv
|
||||||
|
|
||||||
# ensure static geom positions are computed
|
# ensure static geom positions are computed
|
||||||
# TODO: remove once MjData creation semantics are fixed
|
# TODO: remove once MjData creation semantics are fixed
|
||||||
mujoco.mj_kinematics(mjm, mjd)
|
mujoco.mj_kinematics(mjm, mjd)
|
||||||
@@ -915,7 +1115,7 @@ def put_data(
|
|||||||
|
|
||||||
contact = types.Contact(**contact_kwargs)
|
contact = types.Contact(**contact_kwargs)
|
||||||
|
|
||||||
contact.efc_address = np.zeros((naconmax, sizes["nmaxpyramid"]), dtype=int)
|
contact.efc_address = np.full((naconmax, sizes["nmaxpyramid"]), -1, dtype=int)
|
||||||
for i in range(mjd.ncon):
|
for i in range(mjd.ncon):
|
||||||
efc_address = mjd.contact.efc_address[i]
|
efc_address = mjd.contact.efc_address[i]
|
||||||
if efc_address == -1:
|
if efc_address == -1:
|
||||||
@@ -945,43 +1145,28 @@ def put_data(
|
|||||||
|
|
||||||
efc = types.Constraint(**efc_kwargs)
|
efc = types.Constraint(**efc_kwargs)
|
||||||
|
|
||||||
if SPARSE_CONSTRAINT_JACOBIAN:
|
if is_sparse(mjm):
|
||||||
# TODO(team): process efc_J sparsity structure for nv row shift
|
J_rownnz = np.zeros(njmax, dtype=np.int32)
|
||||||
efc.J_rownnz = wp.array(
|
J_rowadr = np.zeros(njmax, dtype=np.int32)
|
||||||
np.full((nworld, njmax), mjm.nv, dtype=int), dtype=int
|
J_colind = np.zeros(njmax_nnz, dtype=np.int32)
|
||||||
)
|
J = np.zeros(njmax_nnz, dtype=np.float64)
|
||||||
efc.J_rowadr = wp.array(
|
|
||||||
np.tile(
|
|
||||||
np.arange(0, njmax * mjm.nv, mjm.nv)
|
|
||||||
if mjm.nv
|
|
||||||
else np.zeros(njmax, dtype=int),
|
|
||||||
(nworld, 1),
|
|
||||||
),
|
|
||||||
dtype=int,
|
|
||||||
)
|
|
||||||
efc.J_colind = wp.array(
|
|
||||||
np.tile(np.arange(mjm.nv), (nworld, njmax)).reshape((nworld, 1, -1)),
|
|
||||||
dtype=int,
|
|
||||||
)
|
|
||||||
|
|
||||||
mj_efc_J = np.zeros((mjd.nefc, mjm.nv))
|
|
||||||
if mjd.nefc:
|
if mjd.nefc:
|
||||||
if mujoco.mj_isSparse(mjm):
|
if mujoco.mj_isSparse(mjm):
|
||||||
mujoco.mju_sparse2dense(
|
J_rownnz[: mjd.nefc] = mjd.efc_J_rownnz[: mjd.nefc]
|
||||||
mj_efc_J,
|
J_rowadr[: mjd.nefc] = mjd.efc_J_rowadr[: mjd.nefc]
|
||||||
mjd.efc_J,
|
nnz = int(mjd.efc_J_rownnz[: mjd.nefc].sum())
|
||||||
mjd.efc_J_rownnz,
|
J_colind[:nnz] = mjd.efc_J_colind[:nnz]
|
||||||
mjd.efc_J_rowadr,
|
J[:nnz] = mjd.efc_J[:nnz]
|
||||||
mjd.efc_J_colind,
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
mj_efc_J = mjd.efc_J.reshape((mjd.nefc, mjm.nv))
|
dense_J = mjd.efc_J.reshape((-1, mjm.nv))[: mjd.nefc]
|
||||||
efc_J = np.zeros((njmax, mjm.nv), dtype=float)
|
mujoco.mju_dense2sparse(
|
||||||
efc_J[: mjd.nefc, : mjm.nv] = mj_efc_J
|
J[: mjd.nefc * mjm.nv], dense_J, J_rownnz[: mjd.nefc], J_rowadr[: mjd.nefc], J_colind[: mjd.nefc * mjm.nv]
|
||||||
efc.J = wp.array(
|
|
||||||
np.tile(efc_J.reshape(-1), (nworld, 1, 1)).reshape((nworld, 1, -1)),
|
|
||||||
dtype=float,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
efc.J_rownnz = wp.array(np.tile(J_rownnz, (nworld, 1)), dtype=int)
|
||||||
|
efc.J_rowadr = wp.array(np.tile(J_rowadr, (nworld, 1)), dtype=int)
|
||||||
|
efc.J_colind = wp.array(np.tile(J_colind, (nworld, 1)).reshape((nworld, 1, -1)), dtype=int)
|
||||||
|
efc.J = wp.array(np.tile(J, (nworld, 1)).reshape((nworld, 1, -1)), dtype=float)
|
||||||
else:
|
else:
|
||||||
efc.J_rownnz = wp.zeros((nworld, 0), dtype=int)
|
efc.J_rownnz = wp.zeros((nworld, 0), dtype=int)
|
||||||
efc.J_rowadr = wp.zeros((nworld, 0), dtype=int)
|
efc.J_rowadr = wp.zeros((nworld, 0), dtype=int)
|
||||||
@@ -990,13 +1175,7 @@ def put_data(
|
|||||||
mj_efc_J = np.zeros((mjd.nefc, mjm.nv))
|
mj_efc_J = np.zeros((mjd.nefc, mjm.nv))
|
||||||
if mjd.nefc:
|
if mjd.nefc:
|
||||||
if mujoco.mj_isSparse(mjm):
|
if mujoco.mj_isSparse(mjm):
|
||||||
mujoco.mju_sparse2dense(
|
mujoco.mju_sparse2dense(mj_efc_J, mjd.efc_J, mjd.efc_J_rownnz, mjd.efc_J_rowadr, mjd.efc_J_colind)
|
||||||
mj_efc_J,
|
|
||||||
mjd.efc_J,
|
|
||||||
mjd.efc_J_rownnz,
|
|
||||||
mjd.efc_J_rowadr,
|
|
||||||
mjd.efc_J_colind,
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
mj_efc_J = mjd.efc_J.reshape((mjd.nefc, mjm.nv))
|
mj_efc_J = mjd.efc_J.reshape((mjd.nefc, mjm.nv))
|
||||||
efc_J = np.zeros((nworld, sizes["njmax_pad"], sizes["nv_pad"]), dtype=float)
|
efc_J = np.zeros((nworld, sizes["njmax_pad"], sizes["nv_pad"]), dtype=float)
|
||||||
@@ -1012,11 +1191,11 @@ def put_data(
|
|||||||
"naccdmax": naccdmax,
|
"naccdmax": naccdmax,
|
||||||
"njmax": njmax,
|
"njmax": njmax,
|
||||||
"njmax_pad": sizes["njmax_pad"],
|
"njmax_pad": sizes["njmax_pad"],
|
||||||
|
"njmax_nnz": njmax_nnz,
|
||||||
# fields set after initialization:
|
# fields set after initialization:
|
||||||
"solver_niter": None,
|
"solver_niter": None,
|
||||||
"qM": None,
|
"qM": None,
|
||||||
"qLD": None,
|
"qLD": None,
|
||||||
"ten_J": None,
|
|
||||||
"nacon": None,
|
"nacon": None,
|
||||||
# island arrays
|
# island arrays
|
||||||
"nisland": None,
|
"nisland": None,
|
||||||
@@ -1050,29 +1229,6 @@ def put_data(
|
|||||||
d.nisland = wp.array(np.full(nworld, mjd.nisland), dtype=int)
|
d.nisland = wp.array(np.full(nworld, mjd.nisland), dtype=int)
|
||||||
d.tree_island = wp.array(np.tile(mjd.tree_island, (nworld, 1)), dtype=int)
|
d.tree_island = wp.array(np.tile(mjd.tree_island, (nworld, 1)), dtype=int)
|
||||||
|
|
||||||
ten_J = np.zeros((mjm.ntendon, mjm.nv))
|
|
||||||
if mujoco.mj_isSparse(mjm) or check_version("mujoco>=3.5.1.dev872479828"):
|
|
||||||
if mjm.ntendon:
|
|
||||||
if check_version("mujoco>=3.5.1.dev875093374"):
|
|
||||||
mujoco.mju_sparse2dense(
|
|
||||||
ten_J,
|
|
||||||
mjd.ten_J.reshape(-1),
|
|
||||||
mjm.ten_J_rownnz,
|
|
||||||
mjm.ten_J_rowadr,
|
|
||||||
mjm.ten_J_colind.reshape(-1),
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
mujoco.mju_sparse2dense(
|
|
||||||
ten_J,
|
|
||||||
mjd.ten_J.reshape(-1),
|
|
||||||
mjd.ten_J_rownnz,
|
|
||||||
mjd.ten_J_rowadr,
|
|
||||||
mjd.ten_J_colind.reshape(-1),
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
ten_J = mjd.ten_J.reshape((mjm.ntendon, mjm.nv))
|
|
||||||
d.ten_J = wp.array(np.full((nworld, mjm.ntendon, mjm.nv), ten_J), dtype=float)
|
|
||||||
|
|
||||||
d.nacon = wp.array([mjd.ncon * nworld], dtype=int)
|
d.nacon = wp.array([mjd.ncon * nworld], dtype=int)
|
||||||
|
|
||||||
return d
|
return d
|
||||||
@@ -1233,7 +1389,7 @@ def get_data_into(
|
|||||||
mujoco.mj_factorM(mjm, result)
|
mujoco.mj_factorM(mjm, result)
|
||||||
|
|
||||||
if nefc > 0:
|
if nefc > 0:
|
||||||
if SPARSE_CONSTRAINT_JACOBIAN:
|
if is_sparse(mjm):
|
||||||
efc_J = np.zeros((nefc, mjm.nv))
|
efc_J = np.zeros((nefc, mjm.nv))
|
||||||
mujoco.mju_sparse2dense(
|
mujoco.mju_sparse2dense(
|
||||||
efc_J,
|
efc_J,
|
||||||
@@ -1276,24 +1432,7 @@ def get_data_into(
|
|||||||
|
|
||||||
# tendon
|
# tendon
|
||||||
result.ten_length[:] = d.ten_length.numpy()[world_id]
|
result.ten_length[:] = d.ten_length.numpy()[world_id]
|
||||||
if check_version("mujoco>=3.5.1.dev869712136"):
|
if mjm.ntendon > 0:
|
||||||
ten_J = d.ten_J.numpy()[world_id]
|
|
||||||
if check_version("mujoco>=3.5.1.dev875093374"):
|
|
||||||
ten_J_rownnz = mjm.ten_J_rownnz
|
|
||||||
ten_J_rowadr = mjm.ten_J_rowadr
|
|
||||||
ten_J_colind = mjm.ten_J_colind.reshape(-1)
|
|
||||||
else:
|
|
||||||
ten_J_rownnz = result.ten_J_rownnz
|
|
||||||
ten_J_rowadr = result.ten_J_rowadr
|
|
||||||
ten_J_colind = result.ten_J_colind.reshape(-1)
|
|
||||||
mujoco.mju_dense2sparse(
|
|
||||||
result.ten_J,
|
|
||||||
ten_J,
|
|
||||||
ten_J_rownnz,
|
|
||||||
ten_J_rowadr,
|
|
||||||
ten_J_colind,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
result.ten_J[:] = d.ten_J.numpy()[world_id]
|
result.ten_J[:] = d.ten_J.numpy()[world_id]
|
||||||
result.ten_wrapadr[:] = d.ten_wrapadr.numpy()[world_id]
|
result.ten_wrapadr[:] = d.ten_wrapadr.numpy()[world_id]
|
||||||
result.ten_wrapnum[:] = d.ten_wrapnum.numpy()[world_id]
|
result.ten_wrapnum[:] = d.ten_wrapnum.numpy()[world_id]
|
||||||
@@ -1428,12 +1567,8 @@ def reset_data(m: types.Model, d: types.Data, reset: Optional[wp.array] = None):
|
|||||||
mocapid = body_mocapid[bodyid]
|
mocapid = body_mocapid[bodyid]
|
||||||
|
|
||||||
if mocapid >= 0:
|
if mocapid >= 0:
|
||||||
mocap_pos_out[worldid, mocapid] = body_pos[
|
mocap_pos_out[worldid, mocapid] = body_pos[worldid % body_pos.shape[0], bodyid]
|
||||||
worldid % body_pos.shape[0], bodyid
|
mocap_quat_out[worldid, mocapid] = body_quat[worldid % body_quat.shape[0], bodyid]
|
||||||
]
|
|
||||||
mocap_quat_out[worldid, mocapid] = body_quat[
|
|
||||||
worldid % body_quat.shape[0], bodyid
|
|
||||||
]
|
|
||||||
|
|
||||||
@wp.kernel(module="unique", enable_backward=False)
|
@wp.kernel(module="unique", enable_backward=False)
|
||||||
def reset_contact(
|
def reset_contact(
|
||||||
@@ -1453,6 +1588,8 @@ def reset_data(m: types.Model, d: types.Data, reset: Optional[wp.array] = None):
|
|||||||
contact_solimp_out: wp.array(dtype=types.vec5),
|
contact_solimp_out: wp.array(dtype=types.vec5),
|
||||||
contact_dim_out: wp.array(dtype=int),
|
contact_dim_out: wp.array(dtype=int),
|
||||||
contact_geom_out: wp.array(dtype=wp.vec2i),
|
contact_geom_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_flex_out: wp.array(dtype=wp.vec2i),
|
||||||
|
contact_vert_out: wp.array(dtype=wp.vec2i),
|
||||||
contact_efc_address_out: wp.array2d(dtype=int),
|
contact_efc_address_out: wp.array2d(dtype=int),
|
||||||
contact_worldid_out: wp.array(dtype=int),
|
contact_worldid_out: wp.array(dtype=int),
|
||||||
contact_type_out: wp.array(dtype=int),
|
contact_type_out: wp.array(dtype=int),
|
||||||
@@ -1479,8 +1616,10 @@ def reset_data(m: types.Model, d: types.Data, reset: Optional[wp.array] = None):
|
|||||||
contact_solimp_out[conid] = types.vec5(0.0, 0.0, 0.0, 0.0, 0.0)
|
contact_solimp_out[conid] = types.vec5(0.0, 0.0, 0.0, 0.0, 0.0)
|
||||||
contact_dim_out[conid] = 0
|
contact_dim_out[conid] = 0
|
||||||
contact_geom_out[conid] = wp.vec2i(0, 0)
|
contact_geom_out[conid] = wp.vec2i(0, 0)
|
||||||
|
contact_flex_out[conid] = wp.vec2i(0, 0)
|
||||||
|
contact_vert_out[conid] = wp.vec2i(0, 0)
|
||||||
for i in range(nefcaddress):
|
for i in range(nefcaddress):
|
||||||
contact_efc_address_out[conid, i] = 0
|
contact_efc_address_out[conid, i] = -1
|
||||||
contact_worldid_out[conid] = 0
|
contact_worldid_out[conid] = 0
|
||||||
contact_type_out[conid] = 0
|
contact_type_out[conid] = 0
|
||||||
contact_geomcollisionid_out[conid] = 0
|
contact_geomcollisionid_out[conid] = 0
|
||||||
@@ -1519,6 +1658,8 @@ def reset_data(m: types.Model, d: types.Data, reset: Optional[wp.array] = None):
|
|||||||
d.contact.solimp,
|
d.contact.solimp,
|
||||||
d.contact.dim,
|
d.contact.dim,
|
||||||
d.contact.geom,
|
d.contact.geom,
|
||||||
|
d.contact.flex,
|
||||||
|
d.contact.vert,
|
||||||
d.contact.efc_address,
|
d.contact.efc_address,
|
||||||
d.contact.worldid,
|
d.contact.worldid,
|
||||||
d.contact.type,
|
d.contact.type,
|
||||||
@@ -1812,28 +1953,45 @@ def _finalize_body_invweight0(
|
|||||||
@wp.kernel
|
@wp.kernel
|
||||||
def _copy_tendon_jacobian(
|
def _copy_tendon_jacobian(
|
||||||
tenid_target: int,
|
tenid_target: int,
|
||||||
ten_J_in: wp.array3d(dtype=float),
|
ten_J_rownnz: wp.array(dtype=int),
|
||||||
|
ten_J_rowadr: wp.array(dtype=int),
|
||||||
|
ten_J_colind: wp.array(dtype=int),
|
||||||
|
ten_J_in: wp.array2d(dtype=float),
|
||||||
ten_J_vec_out: wp.array2d(dtype=float),
|
ten_J_vec_out: wp.array2d(dtype=float),
|
||||||
):
|
):
|
||||||
worldid = wp.tid()
|
worldid = wp.tid()
|
||||||
nv = ten_J_in.shape[2]
|
nv = ten_J_in.shape[2]
|
||||||
for i in range(nv):
|
rownnz = ten_J_rownnz[tenid_target]
|
||||||
ten_J_vec_out[worldid, i] = ten_J_in[worldid, tenid_target, i]
|
rowadr = ten_J_rowadr[tenid_target]
|
||||||
|
for i in range(rownnz):
|
||||||
|
colind = ten_J_colind[rowadr + i]
|
||||||
|
ten_J_vec_out[worldid, colind] = ten_J_in[worldid, rowadr + i]
|
||||||
|
|
||||||
|
|
||||||
@wp.kernel
|
@wp.kernel
|
||||||
def _compute_tendon_dot_product(
|
def _compute_tendon_dot_product(
|
||||||
|
# Model:
|
||||||
|
ten_J_rownnz: wp.array(dtype=int),
|
||||||
|
ten_J_rowadr: wp.array(dtype=int),
|
||||||
|
ten_J_colind: wp.array(dtype=int),
|
||||||
|
# In:
|
||||||
tenid_target: int,
|
tenid_target: int,
|
||||||
nv: int,
|
ten_J_in: wp.array2d(dtype=float),
|
||||||
ten_J_in: wp.array3d(dtype=float),
|
|
||||||
result_vec_in: wp.array2d(dtype=float),
|
result_vec_in: wp.array2d(dtype=float),
|
||||||
|
# Out:
|
||||||
tendon_invweight0_out: wp.array2d(dtype=float),
|
tendon_invweight0_out: wp.array2d(dtype=float),
|
||||||
):
|
):
|
||||||
worldid = wp.tid()
|
worldid = wp.tid()
|
||||||
tendon_invweight0_id = worldid % tendon_invweight0_out.shape[0]
|
tendon_invweight0_id = worldid % tendon_invweight0_out.shape[0]
|
||||||
dot_prod = float(0.0)
|
dot_prod = float(0.0)
|
||||||
for i in range(nv):
|
|
||||||
dot_prod += ten_J_in[worldid, tenid_target, i] * result_vec_in[worldid, i]
|
rownnz = ten_J_rownnz[tenid_target]
|
||||||
|
rowadr = ten_J_rowadr[tenid_target]
|
||||||
|
for i in range(rownnz):
|
||||||
|
sparseid = rowadr + i
|
||||||
|
colind = ten_J_colind[sparseid]
|
||||||
|
dot_prod += ten_J_in[worldid, sparseid] * result_vec_in[worldid, colind]
|
||||||
|
|
||||||
tendon_invweight0_out[tendon_invweight0_id, tenid_target] = dot_prod
|
tendon_invweight0_out[tendon_invweight0_id, tenid_target] = dot_prod
|
||||||
|
|
||||||
|
|
||||||
@@ -2167,16 +2325,22 @@ def set_const_0(m: types.Model, d: types.Data):
|
|||||||
|
|
||||||
# tendon_invweight0[t] = J_t * inv(M) * J_t'
|
# tendon_invweight0[t] = J_t * inv(M) * J_t'
|
||||||
if m.ntendon > 0:
|
if m.ntendon > 0:
|
||||||
ten_J_vec = wp.zeros((d.nworld, m.nv), dtype=float)
|
ten_J_vec = wp.empty((d.nworld, m.nv), dtype=float)
|
||||||
ten_result_vec = wp.zeros((d.nworld, m.nv), dtype=float)
|
ten_result_vec = wp.empty((d.nworld, m.nv), dtype=float)
|
||||||
|
|
||||||
for tenid in range(m.ntendon):
|
for tenid in range(m.ntendon):
|
||||||
wp.launch(_copy_tendon_jacobian, dim=d.nworld, inputs=[tenid, d.ten_J], outputs=[ten_J_vec])
|
ten_J_vec.zero_()
|
||||||
|
wp.launch(
|
||||||
|
_copy_tendon_jacobian,
|
||||||
|
dim=d.nworld,
|
||||||
|
inputs=[tenid, m.ten_J_rownnz, m.ten_J_rowadr, m.ten_J_colind, d.ten_J],
|
||||||
|
outputs=[ten_J_vec],
|
||||||
|
)
|
||||||
smooth.solve_m(m, d, ten_result_vec, ten_J_vec)
|
smooth.solve_m(m, d, ten_result_vec, ten_J_vec)
|
||||||
wp.launch(
|
wp.launch(
|
||||||
_compute_tendon_dot_product,
|
_compute_tendon_dot_product,
|
||||||
dim=d.nworld,
|
dim=d.nworld,
|
||||||
inputs=[tenid, m.nv, d.ten_J, ten_result_vec],
|
inputs=[m.ten_J_rownnz, m.ten_J_rowadr, m.ten_J_colind, tenid, d.ten_J, ten_result_vec],
|
||||||
outputs=[m.tendon_invweight0],
|
outputs=[m.tendon_invweight0],
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -2203,13 +2367,7 @@ def set_const_0(m: types.Model, d: types.Data):
|
|||||||
wp.launch(
|
wp.launch(
|
||||||
_copy_actuator_moment,
|
_copy_actuator_moment,
|
||||||
dim=d.nworld,
|
dim=d.nworld,
|
||||||
inputs=[
|
inputs=[actid, d.moment_rownnz, d.moment_rowadr, d.moment_colind, d.actuator_moment],
|
||||||
actid,
|
|
||||||
d.moment_rownnz,
|
|
||||||
d.moment_rowadr,
|
|
||||||
d.moment_colind,
|
|
||||||
d.actuator_moment,
|
|
||||||
],
|
|
||||||
outputs=[act_moment_vec],
|
outputs=[act_moment_vec],
|
||||||
)
|
)
|
||||||
smooth.solve_m(m, d, act_result_vec, act_moment_vec)
|
smooth.solve_m(m, d, act_result_vec, act_moment_vec)
|
||||||
@@ -2255,16 +2413,12 @@ def set_const(m: types.Model, d: types.Data):
|
|||||||
Field | Notes
|
Field | Notes
|
||||||
---------------------------------|----------------------------------------------
|
---------------------------------|----------------------------------------------
|
||||||
qpos0, qpos_spring |
|
qpos0, qpos_spring |
|
||||||
body_mass, body_inertia, | Mass and inertia are usually scaled
|
body_mass, body_inertia, | Mass and inertia are usually scaled together
|
||||||
together
|
|
||||||
body_ipos, body_iquat | since inertia is sum(m * r^2).
|
body_ipos, body_iquat | since inertia is sum(m * r^2).
|
||||||
body_pos, body_quat | Unsafe for static bodies (invalidates
|
body_pos, body_quat | Unsafe for static bodies (invalidates BVH).
|
||||||
BVH).
|
body_gravcomp | If changing from 0 to >0 bodies, required.
|
||||||
body_gravcomp | If changing from 0 to >0 bodies,
|
|
||||||
required.
|
|
||||||
dof_armature |
|
dof_armature |
|
||||||
eq_data | For connect/weld, offsets computed if not
|
eq_data | For connect/weld, offsets computed if not set.
|
||||||
set.
|
|
||||||
hfield_size |
|
hfield_size |
|
||||||
tendon_stiffness, tendon_damping | Only if changing from/to zero.
|
tendon_stiffness, tendon_damping | Only if changing from/to zero.
|
||||||
actuator_gainprm, actuator_biasprm | For position actuators with dampratio.
|
actuator_gainprm, actuator_biasprm | For position actuators with dampratio.
|
||||||
@@ -2486,6 +2640,7 @@ def create_render_context(
|
|||||||
cam_res: list[tuple[int, int]] | tuple[int, int] | None = None,
|
cam_res: list[tuple[int, int]] | tuple[int, int] | None = None,
|
||||||
render_rgb: list[bool] | bool | None = None,
|
render_rgb: list[bool] | bool | None = None,
|
||||||
render_depth: list[bool] | bool | None = None,
|
render_depth: list[bool] | bool | None = None,
|
||||||
|
render_seg: list[bool] | bool | None = None,
|
||||||
use_textures: bool = True,
|
use_textures: bool = True,
|
||||||
use_shadows: bool = False,
|
use_shadows: bool = False,
|
||||||
enabled_geom_groups: list[int] = [0, 1, 2],
|
enabled_geom_groups: list[int] = [0, 1, 2],
|
||||||
@@ -2502,6 +2657,8 @@ def create_render_context(
|
|||||||
MuJoCo model values.
|
MuJoCo model values.
|
||||||
render_rgb: Whether to render RGB images. If None, uses the MuJoCo model values.
|
render_rgb: Whether to render RGB images. If None, uses the MuJoCo model values.
|
||||||
render_depth: Whether to render depth images. If None, uses the MuJoCo model values.
|
render_depth: Whether to render depth images. If None, uses the MuJoCo model values.
|
||||||
|
render_seg: Whether to render segmentation (per-pixel geom IDs). If None,
|
||||||
|
uses the MuJoCo model values.
|
||||||
use_textures: Whether to use textures.
|
use_textures: Whether to use textures.
|
||||||
use_shadows: Whether to use shadows.
|
use_shadows: Whether to use shadows.
|
||||||
enabled_geom_groups: The geom groups to render.
|
enabled_geom_groups: The geom groups to render.
|
||||||
@@ -2517,10 +2674,13 @@ def create_render_context(
|
|||||||
mjd = mujoco.MjData(mjm)
|
mjd = mujoco.MjData(mjm)
|
||||||
mujoco.mj_forward(mjm, mjd)
|
mujoco.mj_forward(mjm, mjd)
|
||||||
|
|
||||||
# TODO(team): remove after mjwarp depends on warp-lang >= 1.12 in pyproject.toml
|
constructor = "sah"
|
||||||
if use_textures and not hasattr(wp, "Texture2D"):
|
if check_version("warp>=1.13.0.dev20260325"):
|
||||||
warnings.warn("Textures require warp >= 1.12. Disabling textures.")
|
# TODO: The cubql constructor and is_cubql_available exist only in
|
||||||
use_textures = False
|
# recent Warp 1.13+ builds, modify this after warp is updated to 1.13+.
|
||||||
|
_cubql_avail = getattr(wp, "is_cubql_available", None)
|
||||||
|
if callable(_cubql_avail) and _cubql_avail():
|
||||||
|
constructor = "cubql"
|
||||||
|
|
||||||
# Mesh BVHs
|
# Mesh BVHs
|
||||||
nmesh = mjm.nmesh
|
nmesh = mjm.nmesh
|
||||||
@@ -2534,7 +2694,7 @@ def create_render_context(
|
|||||||
mesh_bounds_size = [wp.vec3(0.0, 0.0, 0.0) for _ in range(nmesh)]
|
mesh_bounds_size = [wp.vec3(0.0, 0.0, 0.0) for _ in range(nmesh)]
|
||||||
|
|
||||||
for mid in used_mesh_id:
|
for mid in used_mesh_id:
|
||||||
mesh, half = bvh.build_mesh_bvh(mjm, mid)
|
mesh, half = bvh.build_mesh_bvh(mjm, mid, constructor=constructor)
|
||||||
mesh_registry[mesh.id] = mesh
|
mesh_registry[mesh.id] = mesh
|
||||||
mesh_bvh_id[mid] = mesh.id
|
mesh_bvh_id[mid] = mesh.id
|
||||||
mesh_bounds_size[mid] = half
|
mesh_bounds_size[mid] = half
|
||||||
@@ -2551,7 +2711,7 @@ def create_render_context(
|
|||||||
hfield_bounds_size = [wp.vec3(0.0, 0.0, 0.0) for _ in range(nhfield)]
|
hfield_bounds_size = [wp.vec3(0.0, 0.0, 0.0) for _ in range(nhfield)]
|
||||||
|
|
||||||
for hid in used_hfield_id:
|
for hid in used_hfield_id:
|
||||||
hmesh, hhalf = bvh.build_hfield_bvh(mjm, hid)
|
hmesh, hhalf = bvh.build_hfield_bvh(mjm, hid, constructor=constructor)
|
||||||
hfield_registry[hmesh.id] = hmesh
|
hfield_registry[hmesh.id] = hmesh
|
||||||
hfield_bvh_id[hid] = hmesh.id
|
hfield_bvh_id[hid] = hmesh.id
|
||||||
hfield_bounds_size[hid] = hhalf
|
hfield_bounds_size[hid] = hhalf
|
||||||
@@ -2560,65 +2720,33 @@ def create_render_context(
|
|||||||
hfield_bounds_size_arr = wp.array(hfield_bounds_size, dtype=wp.vec3)
|
hfield_bounds_size_arr = wp.array(hfield_bounds_size, dtype=wp.vec3)
|
||||||
|
|
||||||
# Flex BVHs
|
# Flex BVHs
|
||||||
flex_bvh_id = wp.uint64(0)
|
|
||||||
flex_group_root = wp.zeros(nworld, dtype=int)
|
|
||||||
flex_mesh = None
|
|
||||||
flex_face_point = None
|
|
||||||
flex_elemdataadr = None
|
|
||||||
flex_shell = None
|
|
||||||
flex_shelldataadr = None
|
|
||||||
flex_faceadr = None
|
|
||||||
flex_nface = 0
|
|
||||||
flex_radius = None
|
|
||||||
flex_workadr = None
|
|
||||||
flex_worknum = None
|
|
||||||
flex_nwork = 0
|
|
||||||
|
|
||||||
if mjm.nflex > 0:
|
|
||||||
(
|
|
||||||
fmesh,
|
|
||||||
face_point,
|
|
||||||
flex_group_roots,
|
|
||||||
flex_shell_data,
|
|
||||||
flex_faceadr_data,
|
|
||||||
flex_nface,
|
|
||||||
) = bvh.build_flex_bvh(mjm, mjd, nworld)
|
|
||||||
|
|
||||||
flex_mesh = fmesh
|
|
||||||
flex_bvh_id = fmesh.id
|
|
||||||
flex_face_point = face_point
|
|
||||||
flex_group_root = flex_group_roots
|
|
||||||
flex_elemdataadr = wp.array(mjm.flex_elemdataadr, dtype=int)
|
|
||||||
flex_shell = flex_shell_data
|
|
||||||
flex_shelldataadr = wp.array(mjm.flex_shelldataadr, dtype=int)
|
|
||||||
flex_faceadr = wp.array(flex_faceadr_data, dtype=int)
|
|
||||||
flex_radius = wp.array(mjm.flex_radius, dtype=float)
|
|
||||||
|
|
||||||
# precompute work item layout for unified refit kernel
|
|
||||||
nflex = mjm.nflex
|
nflex = mjm.nflex
|
||||||
workadr = np.zeros(nflex, dtype=np.int32)
|
flex_registry = {}
|
||||||
worknum = np.zeros(nflex, dtype=np.int32)
|
|
||||||
cumsum = 0
|
# Scene BVH flex primitives: 1D → one capsule per edge, 2D/3D → one box per flex
|
||||||
|
flex_geom_flexid = []
|
||||||
|
flex_geom_edgeid = []
|
||||||
|
flex_bvh_id = np.full(nflex, 0, dtype=wp.uint64)
|
||||||
|
flex_group_root = np.zeros((nflex, nworld), dtype=int)
|
||||||
|
|
||||||
for f in range(nflex):
|
for f in range(nflex):
|
||||||
workadr[f] = cumsum
|
if mjm.flex_dim[f] == 1:
|
||||||
if mjm.flex_dim[f] == 2:
|
edge_adr = mjm.flex_edgeadr[f]
|
||||||
worknum[f] = mjm.flex_elemnum[f] + mjm.flex_shellnum[f]
|
flex_geom_flexid.extend([f] * mjm.flex_edgenum[f])
|
||||||
|
flex_geom_edgeid.extend([edge_adr + e for e in range(mjm.flex_edgenum[f])])
|
||||||
|
flex_group_root[f] = np.zeros(nworld, dtype=int)
|
||||||
else:
|
else:
|
||||||
worknum[f] = mjm.flex_shellnum[f]
|
flex_geom_flexid.append(f)
|
||||||
cumsum += worknum[f]
|
flex_geom_edgeid.append(-1)
|
||||||
flex_workadr = wp.array(workadr, dtype=int)
|
fmesh, group_root = bvh.build_flex_bvh(mjm, mjd, nworld, f)
|
||||||
flex_worknum = wp.array(worknum, dtype=int)
|
flex_registry[f] = fmesh
|
||||||
flex_nwork = int(cumsum)
|
flex_bvh_id[f] = fmesh.id
|
||||||
|
flex_group_root[f] = group_root.numpy()
|
||||||
|
|
||||||
textures_registry = []
|
textures_registry = []
|
||||||
# TODO: remove after mjwarp depends on warp-lang >= 1.12 in pyproject.toml
|
|
||||||
if hasattr(wp, "Texture2D"):
|
|
||||||
for i in range(mjm.ntex):
|
for i in range(mjm.ntex):
|
||||||
textures_registry.append(render_util.create_warp_texture(mjm, i))
|
textures_registry.append(render_util.create_warp_texture(mjm, i))
|
||||||
textures = wp.array(textures_registry, dtype=wp.Texture2D)
|
textures = wp.array(textures_registry, dtype=wp.Texture2D)
|
||||||
else:
|
|
||||||
# Dummy array when texture support isn't available (warp < 1.12)
|
|
||||||
textures = wp.zeros(1, dtype=int)
|
|
||||||
|
|
||||||
# Filter active cameras
|
# Filter active cameras
|
||||||
if cam_active is not None:
|
if cam_active is not None:
|
||||||
@@ -2642,31 +2770,31 @@ def create_render_context(
|
|||||||
cam_res_arr = wp.array(active_cam_res, dtype=wp.vec2i)
|
cam_res_arr = wp.array(active_cam_res, dtype=wp.vec2i)
|
||||||
|
|
||||||
if render_rgb is None:
|
if render_rgb is None:
|
||||||
render_rgb = [
|
render_rgb = [mjm.cam_output[i] & mujoco.mjtCamOutBit.mjCAMOUT_RGB for i in active_cam_indices]
|
||||||
mjm.cam_output[i] & mujoco.mjtCamOutBit.mjCAMOUT_RGB
|
|
||||||
for i in active_cam_indices
|
|
||||||
]
|
|
||||||
elif isinstance(render_rgb, bool):
|
elif isinstance(render_rgb, bool):
|
||||||
render_rgb = [render_rgb] * ncam
|
render_rgb = [render_rgb] * ncam
|
||||||
|
|
||||||
if render_depth is None:
|
if render_depth is None:
|
||||||
render_depth = [
|
render_depth = [mjm.cam_output[i] & mujoco.mjtCamOutBit.mjCAMOUT_DEPTH for i in active_cam_indices]
|
||||||
mjm.cam_output[i] & mujoco.mjtCamOutBit.mjCAMOUT_DEPTH
|
|
||||||
for i in active_cam_indices
|
|
||||||
]
|
|
||||||
if isinstance(render_depth, bool):
|
if isinstance(render_depth, bool):
|
||||||
render_depth = [render_depth] * ncam
|
render_depth = [render_depth] * ncam
|
||||||
|
|
||||||
assert len(render_rgb) == ncam and len(render_depth) == ncam, (
|
if render_seg is None:
|
||||||
"render_rgb and render_depth must be a bool or a list of bools with"
|
render_seg = [mjm.cam_output[i] & mujoco.mjtCamOutBit.mjCAMOUT_SEG for i in active_cam_indices]
|
||||||
f" length {ncam}"
|
elif isinstance(render_seg, bool):
|
||||||
|
render_seg = [render_seg] * ncam
|
||||||
|
|
||||||
|
assert len(render_rgb) == ncam and len(render_depth) == ncam and len(render_seg) == ncam, (
|
||||||
|
f"render_rgb, render_depth, and render_seg must be a bool or a list of bools with length {ncam}"
|
||||||
)
|
)
|
||||||
|
|
||||||
rgb_adr = -1 * np.ones(ncam, dtype=int)
|
rgb_adr = -1 * np.ones(ncam, dtype=int)
|
||||||
depth_adr = -1 * np.ones(ncam, dtype=int)
|
depth_adr = -1 * np.ones(ncam, dtype=int)
|
||||||
|
seg_adr = -1 * np.ones(ncam, dtype=int)
|
||||||
cam_res_np = cam_res_arr.numpy()
|
cam_res_np = cam_res_arr.numpy()
|
||||||
ri = 0
|
ri = 0
|
||||||
di = 0
|
di = 0
|
||||||
|
si = 0
|
||||||
total = 0
|
total = 0
|
||||||
|
|
||||||
for idx in range(ncam):
|
for idx in range(ncam):
|
||||||
@@ -2676,6 +2804,9 @@ def create_render_context(
|
|||||||
if render_depth[idx]:
|
if render_depth[idx]:
|
||||||
depth_adr[idx] = di
|
depth_adr[idx] = di
|
||||||
di += cam_res_np[idx][0] * cam_res_np[idx][1]
|
di += cam_res_np[idx][0] * cam_res_np[idx][1]
|
||||||
|
if render_seg[idx]:
|
||||||
|
seg_adr[idx] = si
|
||||||
|
si += cam_res_np[idx][0] * cam_res_np[idx][1]
|
||||||
|
|
||||||
total += cam_res_np[idx][0] * cam_res_np[idx][1]
|
total += cam_res_np[idx][0] * cam_res_np[idx][1]
|
||||||
|
|
||||||
@@ -2729,26 +2860,20 @@ def create_render_context(
|
|||||||
hfield_registry=hfield_registry,
|
hfield_registry=hfield_registry,
|
||||||
hfield_bvh_id=hfield_bvh_id_arr,
|
hfield_bvh_id=hfield_bvh_id_arr,
|
||||||
hfield_bounds_size=hfield_bounds_size_arr,
|
hfield_bounds_size=hfield_bounds_size_arr,
|
||||||
flex_mesh=flex_mesh,
|
flex_mesh_registry=flex_registry,
|
||||||
flex_rgba=wp.array(mjm.flex_rgba, dtype=wp.vec4),
|
flex_rgba=wp.array(mjm.flex_rgba, dtype=wp.vec4),
|
||||||
flex_bvh_id=flex_bvh_id,
|
flex_bvh_id=wp.array(flex_bvh_id, dtype=wp.uint64),
|
||||||
flex_face_point=flex_face_point,
|
flex_group_root=wp.array(flex_group_root, dtype=int),
|
||||||
flex_faceadr=flex_faceadr,
|
|
||||||
flex_nface=flex_nface,
|
|
||||||
flex_nwork=flex_nwork,
|
|
||||||
flex_group_root=flex_group_root,
|
|
||||||
flex_elemdataadr=flex_elemdataadr,
|
|
||||||
flex_shell=flex_shell,
|
|
||||||
flex_shelldataadr=flex_shelldataadr,
|
|
||||||
flex_radius=flex_radius,
|
|
||||||
flex_workadr=flex_workadr,
|
|
||||||
flex_worknum=flex_worknum,
|
|
||||||
flex_render_smooth=flex_render_smooth,
|
flex_render_smooth=flex_render_smooth,
|
||||||
|
bvh_nflexgeom=len(flex_geom_flexid),
|
||||||
|
flex_dim_np=mjm.flex_dim,
|
||||||
|
flex_geom_flexid=wp.array(flex_geom_flexid, dtype=int),
|
||||||
|
flex_geom_edgeid=wp.array(flex_geom_edgeid, dtype=int),
|
||||||
bvh=None,
|
bvh=None,
|
||||||
bvh_id=None,
|
bvh_id=None,
|
||||||
lower=wp.zeros(nworld * bvh_ngeom, dtype=wp.vec3),
|
lower=wp.zeros(nworld * (bvh_ngeom + len(flex_geom_flexid)), dtype=wp.vec3),
|
||||||
upper=wp.zeros(nworld * bvh_ngeom, dtype=wp.vec3),
|
upper=wp.zeros(nworld * (bvh_ngeom + len(flex_geom_flexid)), dtype=wp.vec3),
|
||||||
group=wp.zeros(nworld * bvh_ngeom, dtype=int),
|
group=wp.zeros(nworld * (bvh_ngeom + len(flex_geom_flexid)), dtype=int),
|
||||||
group_root=wp.zeros(nworld, dtype=int),
|
group_root=wp.zeros(nworld, dtype=int),
|
||||||
ray=ray,
|
ray=ray,
|
||||||
rgb_data=wp.zeros((nworld, ri), dtype=wp.uint32),
|
rgb_data=wp.zeros((nworld, ri), dtype=wp.uint32),
|
||||||
@@ -2757,6 +2882,9 @@ def create_render_context(
|
|||||||
depth_adr=wp.array(depth_adr, dtype=int),
|
depth_adr=wp.array(depth_adr, dtype=int),
|
||||||
render_rgb=wp.array(render_rgb, dtype=bool),
|
render_rgb=wp.array(render_rgb, dtype=bool),
|
||||||
render_depth=wp.array(render_depth, dtype=bool),
|
render_depth=wp.array(render_depth, dtype=bool),
|
||||||
|
seg_data=wp.zeros((nworld, max(si, 1)), dtype=int),
|
||||||
|
seg_adr=wp.array(seg_adr, dtype=int),
|
||||||
|
render_seg=wp.array(render_seg, dtype=bool),
|
||||||
znear=znear,
|
znear=znear,
|
||||||
total_rays=int(total),
|
total_rays=int(total),
|
||||||
)
|
)
|
||||||
|
|||||||
+2
-1
@@ -13,12 +13,13 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|
||||||
|
import warp as wp
|
||||||
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src import types
|
from mujoco.mjx.third_party.mujoco_warp._src import types
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import ConstraintType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import ConstraintType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import EqType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import EqType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import ObjType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import ObjType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import event_scope
|
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import event_scope
|
||||||
import warp as wp
|
|
||||||
|
|
||||||
|
|
||||||
@wp.kernel
|
@wp.kernel
|
||||||
|
|||||||
@@ -83,6 +83,35 @@ def quat_to_mat(quat: wp.quat) -> wp.mat33:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@wp.func
|
||||||
|
def quat_z2vec(vec: wp.vec3) -> wp.quat:
|
||||||
|
"""Compute quaternion performing rotation from z-axis to given vector."""
|
||||||
|
quat = wp.quat(0.0, 0.0, 0.0, 1.0)
|
||||||
|
|
||||||
|
# normalize vector; if too small, no rotation
|
||||||
|
norm = wp.length(vec)
|
||||||
|
if norm < types.MJ_MINVAL:
|
||||||
|
return quat
|
||||||
|
vec = vec / norm
|
||||||
|
|
||||||
|
axis = wp.vec3(-vec[1], vec[0], 0.0)
|
||||||
|
a = wp.length(axis)
|
||||||
|
|
||||||
|
# almost parallel
|
||||||
|
if a < types.MJ_MINVAL:
|
||||||
|
# opposite: 180 deg rotation around x axis
|
||||||
|
if vec[2] < 0.0:
|
||||||
|
quat = wp.quat(1.0, 0.0, 0.0, 0.0)
|
||||||
|
return quat
|
||||||
|
|
||||||
|
# make quaternion from angle and axis
|
||||||
|
axis = axis / a
|
||||||
|
angle = wp.atan2(a, vec[2])
|
||||||
|
quat = axis_angle_to_quat(axis, angle)
|
||||||
|
|
||||||
|
return quat
|
||||||
|
|
||||||
|
|
||||||
@wp.func
|
@wp.func
|
||||||
def quat_inv(quat: wp.quat) -> wp.quat:
|
def quat_inv(quat: wp.quat) -> wp.quat:
|
||||||
return wp.quat(quat[0], -quat[1], -quat[2], -quat[3])
|
return wp.quat(quat[0], -quat[1], -quat[2], -quat[3])
|
||||||
|
|||||||
+33
-12
@@ -89,8 +89,8 @@ def _spring_damper_dof_passive(
|
|||||||
stiffness = jnt_stiffness[worldid % jnt_stiffness.shape[0], jntid]
|
stiffness = jnt_stiffness[worldid % jnt_stiffness.shape[0], jntid]
|
||||||
damping = dof_damping[worldid % dof_damping.shape[0], dofid]
|
damping = dof_damping[worldid % dof_damping.shape[0], dofid]
|
||||||
|
|
||||||
has_stiffness = stiffness != 0.0 and not opt_disableflags & DisableBit.SPRING
|
has_stiffness = stiffness != 0.0 and not (opt_disableflags & DisableBit.SPRING)
|
||||||
has_damping = damping != 0.0 and not opt_disableflags & DisableBit.DAMPER
|
has_damping = damping != 0.0 and not (opt_disableflags & DisableBit.DAMPER)
|
||||||
|
|
||||||
if not has_stiffness:
|
if not has_stiffness:
|
||||||
qfrc_spring_out[worldid, dofid] = 0.0
|
qfrc_spring_out[worldid, dofid] = 0.0
|
||||||
@@ -182,11 +182,14 @@ def _spring_damper_dof_passive(
|
|||||||
@wp.kernel
|
@wp.kernel
|
||||||
def _spring_damper_tendon_passive(
|
def _spring_damper_tendon_passive(
|
||||||
# Model:
|
# Model:
|
||||||
|
ten_J_rownnz: wp.array(dtype=int),
|
||||||
|
ten_J_rowadr: wp.array(dtype=int),
|
||||||
|
ten_J_colind: wp.array(dtype=int),
|
||||||
tendon_stiffness: wp.array2d(dtype=float),
|
tendon_stiffness: wp.array2d(dtype=float),
|
||||||
tendon_damping: wp.array2d(dtype=float),
|
tendon_damping: wp.array2d(dtype=float),
|
||||||
tendon_lengthspring: wp.array2d(dtype=wp.vec2),
|
tendon_lengthspring: wp.array2d(dtype=wp.vec2),
|
||||||
# Data in:
|
# Data in:
|
||||||
ten_J_in: wp.array3d(dtype=float),
|
ten_J_in: wp.array2d(dtype=float),
|
||||||
ten_length_in: wp.array2d(dtype=float),
|
ten_length_in: wp.array2d(dtype=float),
|
||||||
ten_velocity_in: wp.array2d(dtype=float),
|
ten_velocity_in: wp.array2d(dtype=float),
|
||||||
# In:
|
# In:
|
||||||
@@ -196,7 +199,7 @@ def _spring_damper_tendon_passive(
|
|||||||
qfrc_spring_out: wp.array2d(dtype=float),
|
qfrc_spring_out: wp.array2d(dtype=float),
|
||||||
qfrc_damper_out: wp.array2d(dtype=float),
|
qfrc_damper_out: wp.array2d(dtype=float),
|
||||||
):
|
):
|
||||||
worldid, tenid, dofid = wp.tid()
|
worldid, tenid, dofid_sparse = wp.tid()
|
||||||
|
|
||||||
stiffness = tendon_stiffness[worldid % tendon_stiffness.shape[0], tenid]
|
stiffness = tendon_stiffness[worldid % tendon_stiffness.shape[0], tenid]
|
||||||
damping = tendon_damping[worldid % tendon_damping.shape[0], tenid]
|
damping = tendon_damping[worldid % tendon_damping.shape[0], tenid]
|
||||||
@@ -207,7 +210,13 @@ def _spring_damper_tendon_passive(
|
|||||||
if not has_stiffness and not has_damping:
|
if not has_stiffness and not has_damping:
|
||||||
return
|
return
|
||||||
|
|
||||||
J = ten_J_in[worldid, tenid, dofid]
|
rownnz = ten_J_rownnz[tenid]
|
||||||
|
if dofid_sparse >= rownnz:
|
||||||
|
return
|
||||||
|
rowadr = ten_J_rowadr[tenid]
|
||||||
|
sparseid = rowadr + dofid_sparse
|
||||||
|
J = ten_J_in[worldid, sparseid]
|
||||||
|
dofid = ten_J_colind[sparseid]
|
||||||
|
|
||||||
if has_stiffness:
|
if has_stiffness:
|
||||||
# compute spring force along tendon
|
# compute spring force along tendon
|
||||||
@@ -565,6 +574,7 @@ def _flex_elasticity(
|
|||||||
flex_edgeadr: wp.array(dtype=int),
|
flex_edgeadr: wp.array(dtype=int),
|
||||||
flex_elemadr: wp.array(dtype=int),
|
flex_elemadr: wp.array(dtype=int),
|
||||||
flex_elemnum: wp.array(dtype=int),
|
flex_elemnum: wp.array(dtype=int),
|
||||||
|
flex_elemdataadr: wp.array(dtype=int),
|
||||||
flex_elemedgeadr: wp.array(dtype=int),
|
flex_elemedgeadr: wp.array(dtype=int),
|
||||||
flex_vertbodyid: wp.array(dtype=int),
|
flex_vertbodyid: wp.array(dtype=int),
|
||||||
flex_elem: wp.array(dtype=int),
|
flex_elem: wp.array(dtype=int),
|
||||||
@@ -590,32 +600,39 @@ def _flex_elasticity(
|
|||||||
f = i
|
f = i
|
||||||
break
|
break
|
||||||
|
|
||||||
|
local_elemid = elemid - flex_elemadr[f]
|
||||||
dim = flex_dim[f]
|
dim = flex_dim[f]
|
||||||
nvert = dim + 1
|
nvert = dim + 1
|
||||||
nedge = nvert * (nvert - 1) / 2
|
nedge = nvert * (nvert - 1) / 2
|
||||||
edges = wp.where(
|
edges = wp.where(
|
||||||
|
dim == 1,
|
||||||
|
wp.matrix(0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, shape=(6, 2), dtype=int),
|
||||||
|
wp.where(
|
||||||
dim == 3,
|
dim == 3,
|
||||||
wp.matrix(0, 1, 1, 2, 2, 0, 2, 3, 0, 3, 1, 3, shape=(6, 2), dtype=int),
|
wp.matrix(0, 1, 1, 2, 2, 0, 2, 3, 0, 3, 1, 3, shape=(6, 2), dtype=int),
|
||||||
wp.matrix(1, 2, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, shape=(6, 2), dtype=int),
|
wp.matrix(1, 2, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, shape=(6, 2), dtype=int),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
if timestep > 0.0 and not dsbl_damper:
|
if timestep > 0.0 and not dsbl_damper:
|
||||||
kD = flex_damping[f] / timestep
|
kD = flex_damping[f] / timestep
|
||||||
else:
|
else:
|
||||||
kD = 0.0
|
kD = 0.0
|
||||||
|
|
||||||
|
elem_data_adr = flex_elemdataadr[f] + local_elemid * (dim + 1)
|
||||||
|
vbase = flex_vertadr[f]
|
||||||
gradient = wp.matrix(0.0, shape=(6, 6))
|
gradient = wp.matrix(0.0, shape=(6, 6))
|
||||||
for e in range(nedge):
|
for e in range(nedge):
|
||||||
vert0 = flex_elem[(dim + 1) * elemid + edges[e, 0]]
|
vert0 = flex_elem[elem_data_adr + edges[e, 0]]
|
||||||
vert1 = flex_elem[(dim + 1) * elemid + edges[e, 1]]
|
vert1 = flex_elem[elem_data_adr + edges[e, 1]]
|
||||||
xpos0 = flexvert_xpos_in[worldid, vert0]
|
xpos0 = flexvert_xpos_in[worldid, vbase + vert0]
|
||||||
xpos1 = flexvert_xpos_in[worldid, vert1]
|
xpos1 = flexvert_xpos_in[worldid, vbase + vert1]
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
gradient[e, 0 + i] = xpos0[i] - xpos1[i]
|
gradient[e, 0 + i] = xpos0[i] - xpos1[i]
|
||||||
gradient[e, 3 + i] = xpos1[i] - xpos0[i]
|
gradient[e, 3 + i] = xpos1[i] - xpos0[i]
|
||||||
|
|
||||||
elongation = wp.spatial_vectorf(0.0)
|
elongation = wp.spatial_vectorf(0.0)
|
||||||
for e in range(nedge):
|
for e in range(nedge):
|
||||||
idx = flex_elemedge[elemid * nedge + e]
|
idx = flex_elemedge[flex_elemedgeadr[f] + local_elemid * nedge + e]
|
||||||
vel = flexedge_velocity_in[worldid, flex_edgeadr[f] + idx]
|
vel = flexedge_velocity_in[worldid, flex_edgeadr[f] + idx]
|
||||||
deformed = flexedge_length_in[worldid, flex_edgeadr[f] + idx]
|
deformed = flexedge_length_in[worldid, flex_edgeadr[f] + idx]
|
||||||
reference = flexedge_length0[flex_edgeadr[f] + idx]
|
reference = flexedge_length0[flex_edgeadr[f] + idx]
|
||||||
@@ -638,7 +655,7 @@ def _flex_elasticity(
|
|||||||
force[edges[ed2, i], x] -= elongation[ed1] * gradient[ed2, 3 * i + x] * metric[ed1, ed2]
|
force[edges[ed2, i], x] -= elongation[ed1] * gradient[ed2, 3 * i + x] * metric[ed1, ed2]
|
||||||
|
|
||||||
for v in range(nvert):
|
for v in range(nvert):
|
||||||
vert = flex_elem[(dim + 1) * elemid + v]
|
vert = flex_elem[elem_data_adr + v]
|
||||||
bodyid = flex_vertbodyid[flex_vertadr[f] + vert]
|
bodyid = flex_vertbodyid[flex_vertadr[f] + vert]
|
||||||
for x in range(3):
|
for x in range(3):
|
||||||
wp.atomic_add(qfrc_spring_out, worldid, body_dofadr[bodyid] + x, force[v, x])
|
wp.atomic_add(qfrc_spring_out, worldid, body_dofadr[bodyid] + x, force[v, x])
|
||||||
@@ -742,8 +759,11 @@ def passive(m: Model, d: Data):
|
|||||||
if m.ntendon:
|
if m.ntendon:
|
||||||
wp.launch(
|
wp.launch(
|
||||||
_spring_damper_tendon_passive,
|
_spring_damper_tendon_passive,
|
||||||
dim=(d.nworld, m.ntendon, m.nv),
|
dim=(d.nworld, m.ntendon, m.max_ten_J_rownnz),
|
||||||
inputs=[
|
inputs=[
|
||||||
|
m.ten_J_rownnz,
|
||||||
|
m.ten_J_rowadr,
|
||||||
|
m.ten_J_colind,
|
||||||
m.tendon_stiffness,
|
m.tendon_stiffness,
|
||||||
m.tendon_damping,
|
m.tendon_damping,
|
||||||
m.tendon_lengthspring,
|
m.tendon_lengthspring,
|
||||||
@@ -772,6 +792,7 @@ def passive(m: Model, d: Data):
|
|||||||
m.flex_edgeadr,
|
m.flex_edgeadr,
|
||||||
m.flex_elemadr,
|
m.flex_elemadr,
|
||||||
m.flex_elemnum,
|
m.flex_elemnum,
|
||||||
|
m.flex_elemdataadr,
|
||||||
m.flex_elemedgeadr,
|
m.flex_elemedgeadr,
|
||||||
m.flex_vertbodyid,
|
m.flex_vertbodyid,
|
||||||
m.flex_elem,
|
m.flex_elem,
|
||||||
|
|||||||
+20
-2
@@ -752,7 +752,8 @@ def ray_mesh_with_bvh_anyhit(
|
|||||||
@wp.func
|
@wp.func
|
||||||
def ray_flex_with_bvh(
|
def ray_flex_with_bvh(
|
||||||
# In:
|
# In:
|
||||||
bvh_id: wp.uint64,
|
flex_bvh_id: wp.array(dtype=wp.uint64),
|
||||||
|
flexid: int,
|
||||||
group_root: int,
|
group_root: int,
|
||||||
pnt: wp.vec3,
|
pnt: wp.vec3,
|
||||||
vec: wp.vec3,
|
vec: wp.vec3,
|
||||||
@@ -769,7 +770,7 @@ def ray_flex_with_bvh(
|
|||||||
n = wp.vec3(0.0, 0.0, 0.0)
|
n = wp.vec3(0.0, 0.0, 0.0)
|
||||||
f = int(-1)
|
f = int(-1)
|
||||||
|
|
||||||
hit = wp.mesh_query_ray(bvh_id, pnt, vec, max_t, t, u, v, sign, n, f, group_root)
|
hit = wp.mesh_query_ray(flex_bvh_id[flexid], pnt, vec, max_t, t, u, v, sign, n, f, group_root)
|
||||||
|
|
||||||
if hit:
|
if hit:
|
||||||
return t, n, u, v, f
|
return t, n, u, v, f
|
||||||
@@ -777,6 +778,23 @@ def ray_flex_with_bvh(
|
|||||||
return -1.0, wp.vec3(0.0, 0.0, 0.0), 0.0, 0.0, -1
|
return -1.0, wp.vec3(0.0, 0.0, 0.0), 0.0, 0.0, -1
|
||||||
|
|
||||||
|
|
||||||
|
@wp.func
|
||||||
|
def ray_flex_with_bvh_anyhit(
|
||||||
|
# In:
|
||||||
|
flex_bvh_id: wp.array(dtype=wp.uint64),
|
||||||
|
flexid: int,
|
||||||
|
group_root: int,
|
||||||
|
pnt: wp.vec3,
|
||||||
|
vec: wp.vec3,
|
||||||
|
max_t: float,
|
||||||
|
) -> bool:
|
||||||
|
"""Returns True if there is any hit for ray flex intersections.
|
||||||
|
|
||||||
|
Requires wp.Mesh be constructed and their ids to be passed. Flex are already in world space.
|
||||||
|
"""
|
||||||
|
return wp.mesh_query_ray_anyhit(flex_bvh_id[flexid], pnt, vec, max_t, group_root)
|
||||||
|
|
||||||
|
|
||||||
@wp.func
|
@wp.func
|
||||||
def ray_geom(pos: wp.vec3, mat: wp.mat33, size: wp.vec3, pnt: wp.vec3, vec: wp.vec3, geomtype: int) -> Tuple[float, wp.vec3]:
|
def ray_geom(pos: wp.vec3, mat: wp.mat33, size: wp.vec3, pnt: wp.vec3, vec: wp.vec3, geomtype: int) -> Tuple[float, wp.vec3]:
|
||||||
"""Returns distance along ray to intersection with geom and normal at intersection point.
|
"""Returns distance along ray to intersection with geom and normal at intersection point.
|
||||||
|
|||||||
+258
-126
@@ -23,6 +23,7 @@ from mujoco.mjx.third_party.mujoco_warp._src.ray import ray_capsule
|
|||||||
from mujoco.mjx.third_party.mujoco_warp._src.ray import ray_cylinder
|
from mujoco.mjx.third_party.mujoco_warp._src.ray import ray_cylinder
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.ray import ray_ellipsoid
|
from mujoco.mjx.third_party.mujoco_warp._src.ray import ray_ellipsoid
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.ray import ray_flex_with_bvh
|
from mujoco.mjx.third_party.mujoco_warp._src.ray import ray_flex_with_bvh
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.ray import ray_flex_with_bvh_anyhit
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.ray import ray_mesh_with_bvh
|
from mujoco.mjx.third_party.mujoco_warp._src.ray import ray_mesh_with_bvh
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.ray import ray_mesh_with_bvh_anyhit
|
from mujoco.mjx.third_party.mujoco_warp._src.ray import ray_mesh_with_bvh_anyhit
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.ray import ray_plane
|
from mujoco.mjx.third_party.mujoco_warp._src.ray import ray_plane
|
||||||
@@ -39,10 +40,6 @@ from mujoco.mjx.third_party.mujoco_warp._src.warp_util import event_scope
|
|||||||
wp.set_module_options({"enable_backward": False})
|
wp.set_module_options({"enable_backward": False})
|
||||||
|
|
||||||
|
|
||||||
# TODO(team): remove after mjwarp depends on warp-lang >= 1.12 in pyproject.toml
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import TEXTURE_DTYPE
|
|
||||||
|
|
||||||
|
|
||||||
@wp.func
|
@wp.func
|
||||||
def sample_texture(
|
def sample_texture(
|
||||||
# Model:
|
# Model:
|
||||||
@@ -51,7 +48,7 @@ def sample_texture(
|
|||||||
# In:
|
# In:
|
||||||
geom_id: int,
|
geom_id: int,
|
||||||
tex_repeat: wp.vec2,
|
tex_repeat: wp.vec2,
|
||||||
tex: TEXTURE_DTYPE,
|
tex: wp.Texture2D,
|
||||||
pos: wp.vec3,
|
pos: wp.vec3,
|
||||||
rot: wp.mat33,
|
rot: wp.mat33,
|
||||||
mesh_facetexcoord: wp.array(dtype=wp.vec3i),
|
mesh_facetexcoord: wp.array(dtype=wp.vec3i),
|
||||||
@@ -94,17 +91,26 @@ def cast_ray(
|
|||||||
geom_type: wp.array(dtype=int),
|
geom_type: wp.array(dtype=int),
|
||||||
geom_dataid: wp.array(dtype=int),
|
geom_dataid: wp.array(dtype=int),
|
||||||
geom_size: wp.array2d(dtype=wp.vec3),
|
geom_size: wp.array2d(dtype=wp.vec3),
|
||||||
|
flex_vertadr: wp.array(dtype=int),
|
||||||
|
flex_edge: wp.array(dtype=wp.vec2i),
|
||||||
|
flex_radius: wp.array(dtype=float),
|
||||||
# Data in:
|
# Data in:
|
||||||
geom_xpos_in: wp.array2d(dtype=wp.vec3),
|
geom_xpos_in: wp.array2d(dtype=wp.vec3),
|
||||||
geom_xmat_in: wp.array2d(dtype=wp.mat33),
|
geom_xmat_in: wp.array2d(dtype=wp.mat33),
|
||||||
|
flexvert_xpos_in: wp.array2d(dtype=wp.vec3),
|
||||||
# In:
|
# In:
|
||||||
bvh_id: wp.uint64,
|
bvh_id: wp.uint64,
|
||||||
group_root: int,
|
group_root: int,
|
||||||
world_id: int,
|
worldid: int,
|
||||||
bvh_ngeom: int,
|
bvh_ngeom: int,
|
||||||
|
flex_bvh_ngeom: int,
|
||||||
enabled_geom_ids: wp.array(dtype=int),
|
enabled_geom_ids: wp.array(dtype=int),
|
||||||
mesh_bvh_id: wp.array(dtype=wp.uint64),
|
mesh_bvh_id: wp.array(dtype=wp.uint64),
|
||||||
hfield_bvh_id: wp.array(dtype=wp.uint64),
|
hfield_bvh_id: wp.array(dtype=wp.uint64),
|
||||||
|
flex_geom_flexid: wp.array(dtype=int),
|
||||||
|
flex_geom_edgeid: wp.array(dtype=int),
|
||||||
|
flex_bvh_id: wp.array(dtype=wp.uint64),
|
||||||
|
flex_group_root: wp.array2d(dtype=int),
|
||||||
ray_origin_world: wp.vec3,
|
ray_origin_world: wp.vec3,
|
||||||
ray_dir_world: wp.vec3,
|
ray_dir_world: wp.vec3,
|
||||||
) -> Tuple[int, float, wp.vec3, float, float, int, int]:
|
) -> Tuple[int, float, wp.vec3, float, float, int, int]:
|
||||||
@@ -118,91 +124,127 @@ def cast_ray(
|
|||||||
|
|
||||||
query = wp.bvh_query_ray(bvh_id, ray_origin_world, ray_dir_world, group_root)
|
query = wp.bvh_query_ray(bvh_id, ray_origin_world, ray_dir_world, group_root)
|
||||||
bounds_nr = int(0)
|
bounds_nr = int(0)
|
||||||
|
ngeom = bvh_ngeom + flex_bvh_ngeom
|
||||||
|
|
||||||
while wp.bvh_query_next(query, bounds_nr, dist):
|
while wp.bvh_query_next(query, bounds_nr, dist):
|
||||||
gi_global = bounds_nr
|
gi_global = bounds_nr
|
||||||
gi_bvh_local = gi_global - (world_id * bvh_ngeom)
|
local_id = gi_global - (worldid * ngeom)
|
||||||
gi = enabled_geom_ids[gi_bvh_local]
|
|
||||||
|
|
||||||
|
d = float(-1.0)
|
||||||
hit_mesh_id = int(-1)
|
hit_mesh_id = int(-1)
|
||||||
u = float(0.0)
|
u = float(0.0)
|
||||||
v = float(0.0)
|
v = float(0.0)
|
||||||
f = int(-1)
|
f = int(-1)
|
||||||
n = wp.vec3(0.0, 0.0, 0.0)
|
n = wp.vec3(0.0, 0.0, 0.0)
|
||||||
|
hit_geom_id = int(-1)
|
||||||
|
|
||||||
|
if local_id < bvh_ngeom:
|
||||||
|
gi = enabled_geom_ids[local_id]
|
||||||
|
gtype = geom_type[gi]
|
||||||
|
else:
|
||||||
|
gi = local_id - bvh_ngeom
|
||||||
|
gtype = GeomType.FLEX
|
||||||
|
|
||||||
|
hit_geom_id = gi
|
||||||
|
|
||||||
# TODO: Investigate branch elimination with static loop unrolling
|
# TODO: Investigate branch elimination with static loop unrolling
|
||||||
if geom_type[gi] == GeomType.PLANE:
|
if gtype == GeomType.PLANE:
|
||||||
d, n = ray_plane(
|
d, n = ray_plane(
|
||||||
geom_xpos_in[world_id, gi],
|
geom_xpos_in[worldid, gi],
|
||||||
geom_xmat_in[world_id, gi],
|
geom_xmat_in[worldid, gi],
|
||||||
geom_size[world_id % geom_size.shape[0], gi],
|
geom_size[worldid % geom_size.shape[0], gi],
|
||||||
ray_origin_world,
|
ray_origin_world,
|
||||||
ray_dir_world,
|
ray_dir_world,
|
||||||
)
|
)
|
||||||
if geom_type[gi] == GeomType.HFIELD:
|
if gtype == GeomType.HFIELD:
|
||||||
d, n, u, v, f, geom_hfield_id = ray_mesh_with_bvh(
|
d, n, u, v, f, geom_hfield_id = ray_mesh_with_bvh(
|
||||||
hfield_bvh_id,
|
hfield_bvh_id,
|
||||||
geom_dataid[gi],
|
geom_dataid[gi],
|
||||||
geom_xpos_in[world_id, gi],
|
geom_xpos_in[worldid, gi],
|
||||||
geom_xmat_in[world_id, gi],
|
geom_xmat_in[worldid, gi],
|
||||||
ray_origin_world,
|
ray_origin_world,
|
||||||
ray_dir_world,
|
ray_dir_world,
|
||||||
dist,
|
dist,
|
||||||
)
|
)
|
||||||
if geom_type[gi] == GeomType.SPHERE:
|
if gtype == GeomType.SPHERE:
|
||||||
d, n = ray_sphere(
|
d, n = ray_sphere(
|
||||||
geom_xpos_in[world_id, gi],
|
geom_xpos_in[worldid, gi],
|
||||||
geom_size[world_id % geom_size.shape[0], gi][0] * geom_size[world_id % geom_size.shape[0], gi][0],
|
geom_size[worldid % geom_size.shape[0], gi][0] * geom_size[worldid % geom_size.shape[0], gi][0],
|
||||||
ray_origin_world,
|
ray_origin_world,
|
||||||
ray_dir_world,
|
ray_dir_world,
|
||||||
)
|
)
|
||||||
if geom_type[gi] == GeomType.ELLIPSOID:
|
if gtype == GeomType.ELLIPSOID:
|
||||||
d, n = ray_ellipsoid(
|
d, n = ray_ellipsoid(
|
||||||
geom_xpos_in[world_id, gi],
|
geom_xpos_in[worldid, gi],
|
||||||
geom_xmat_in[world_id, gi],
|
geom_xmat_in[worldid, gi],
|
||||||
geom_size[world_id % geom_size.shape[0], gi],
|
geom_size[worldid % geom_size.shape[0], gi],
|
||||||
ray_origin_world,
|
ray_origin_world,
|
||||||
ray_dir_world,
|
ray_dir_world,
|
||||||
)
|
)
|
||||||
if geom_type[gi] == GeomType.CAPSULE:
|
if gtype == GeomType.CAPSULE:
|
||||||
d, n = ray_capsule(
|
d, n = ray_capsule(
|
||||||
geom_xpos_in[world_id, gi],
|
geom_xpos_in[worldid, gi],
|
||||||
geom_xmat_in[world_id, gi],
|
geom_xmat_in[worldid, gi],
|
||||||
geom_size[world_id % geom_size.shape[0], gi],
|
geom_size[worldid % geom_size.shape[0], gi],
|
||||||
ray_origin_world,
|
ray_origin_world,
|
||||||
ray_dir_world,
|
ray_dir_world,
|
||||||
)
|
)
|
||||||
if geom_type[gi] == GeomType.CYLINDER:
|
if gtype == GeomType.CYLINDER:
|
||||||
d, n = ray_cylinder(
|
d, n = ray_cylinder(
|
||||||
geom_xpos_in[world_id, gi],
|
geom_xpos_in[worldid, gi],
|
||||||
geom_xmat_in[world_id, gi],
|
geom_xmat_in[worldid, gi],
|
||||||
geom_size[world_id % geom_size.shape[0], gi],
|
geom_size[worldid % geom_size.shape[0], gi],
|
||||||
ray_origin_world,
|
ray_origin_world,
|
||||||
ray_dir_world,
|
ray_dir_world,
|
||||||
)
|
)
|
||||||
if geom_type[gi] == GeomType.BOX:
|
if gtype == GeomType.BOX:
|
||||||
d, all, n = ray_box(
|
d, all, n = ray_box(
|
||||||
geom_xpos_in[world_id, gi],
|
geom_xpos_in[worldid, gi],
|
||||||
geom_xmat_in[world_id, gi],
|
geom_xmat_in[worldid, gi],
|
||||||
geom_size[world_id % geom_size.shape[0], gi],
|
geom_size[worldid % geom_size.shape[0], gi],
|
||||||
ray_origin_world,
|
ray_origin_world,
|
||||||
ray_dir_world,
|
ray_dir_world,
|
||||||
)
|
)
|
||||||
if geom_type[gi] == GeomType.MESH:
|
if gtype == GeomType.MESH:
|
||||||
d, n, u, v, f, hit_mesh_id = ray_mesh_with_bvh(
|
d, n, u, v, f, hit_mesh_id = ray_mesh_with_bvh(
|
||||||
mesh_bvh_id,
|
mesh_bvh_id,
|
||||||
geom_dataid[gi],
|
geom_dataid[gi],
|
||||||
geom_xpos_in[world_id, gi],
|
geom_xpos_in[worldid, gi],
|
||||||
geom_xmat_in[world_id, gi],
|
geom_xmat_in[worldid, gi],
|
||||||
ray_origin_world,
|
ray_origin_world,
|
||||||
ray_dir_world,
|
ray_dir_world,
|
||||||
dist,
|
dist,
|
||||||
)
|
)
|
||||||
|
if gtype == GeomType.FLEX:
|
||||||
|
hit_geom_id = -2
|
||||||
|
flexid = flex_geom_flexid[gi]
|
||||||
|
edge_id = flex_geom_edgeid[gi]
|
||||||
|
|
||||||
|
if edge_id >= 0:
|
||||||
|
edge = flex_edge[edge_id]
|
||||||
|
vert_adr = flex_vertadr[flexid]
|
||||||
|
v0 = flexvert_xpos_in[worldid, vert_adr + edge[0]]
|
||||||
|
v1 = flexvert_xpos_in[worldid, vert_adr + edge[1]]
|
||||||
|
pos = 0.5 * (v0 + v1)
|
||||||
|
vec = v1 - v0
|
||||||
|
|
||||||
|
length = wp.length(vec)
|
||||||
|
edgeq = math.quat_z2vec(vec)
|
||||||
|
mat = math.quat_to_mat(edgeq)
|
||||||
|
size = wp.vec3(flex_radius[flexid], 0.5 * length, 0.0)
|
||||||
|
|
||||||
|
d, n = ray_capsule(pos, mat, size, ray_origin_world, ray_dir_world)
|
||||||
|
hit_mesh_id = flexid
|
||||||
|
else:
|
||||||
|
flex_gr = flex_group_root[worldid, flexid]
|
||||||
|
d, n, u, v, f = ray_flex_with_bvh(flex_bvh_id, flexid, flex_gr, ray_origin_world, ray_dir_world, dist)
|
||||||
|
if d >= 0.0:
|
||||||
|
hit_mesh_id = flexid
|
||||||
|
|
||||||
if d >= 0.0 and d < dist:
|
if d >= 0.0 and d < dist:
|
||||||
dist = d
|
dist = d
|
||||||
normal = n
|
normal = n
|
||||||
geom_id = gi
|
geom_id = hit_geom_id
|
||||||
bary_u = u
|
bary_u = u
|
||||||
bary_v = v
|
bary_v = v
|
||||||
face_idx = f
|
face_idx = f
|
||||||
@@ -217,17 +259,26 @@ def cast_ray_first_hit(
|
|||||||
geom_type: wp.array(dtype=int),
|
geom_type: wp.array(dtype=int),
|
||||||
geom_dataid: wp.array(dtype=int),
|
geom_dataid: wp.array(dtype=int),
|
||||||
geom_size: wp.array2d(dtype=wp.vec3),
|
geom_size: wp.array2d(dtype=wp.vec3),
|
||||||
|
flex_vertadr: wp.array(dtype=int),
|
||||||
|
flex_edge: wp.array(dtype=wp.vec2i),
|
||||||
|
flex_radius: wp.array(dtype=float),
|
||||||
# Data in:
|
# Data in:
|
||||||
geom_xpos_in: wp.array2d(dtype=wp.vec3),
|
geom_xpos_in: wp.array2d(dtype=wp.vec3),
|
||||||
geom_xmat_in: wp.array2d(dtype=wp.mat33),
|
geom_xmat_in: wp.array2d(dtype=wp.mat33),
|
||||||
|
flexvert_xpos_in: wp.array2d(dtype=wp.vec3),
|
||||||
# In:
|
# In:
|
||||||
bvh_id: wp.uint64,
|
bvh_id: wp.uint64,
|
||||||
group_root: int,
|
group_root: int,
|
||||||
world_id: int,
|
worldid: int,
|
||||||
bvh_ngeom: int,
|
bvh_ngeom: int,
|
||||||
|
bvh_nflexgeom: int,
|
||||||
enabled_geom_ids: wp.array(dtype=int),
|
enabled_geom_ids: wp.array(dtype=int),
|
||||||
mesh_bvh_id: wp.array(dtype=wp.uint64),
|
mesh_bvh_id: wp.array(dtype=wp.uint64),
|
||||||
hfield_bvh_id: wp.array(dtype=wp.uint64),
|
hfield_bvh_id: wp.array(dtype=wp.uint64),
|
||||||
|
flex_geom_flexid: wp.array(dtype=int),
|
||||||
|
flex_geom_edgeid: wp.array(dtype=int),
|
||||||
|
flex_bvh_id: wp.array(dtype=wp.uint64),
|
||||||
|
flex_group_root: wp.array2d(dtype=int),
|
||||||
ray_origin_world: wp.vec3,
|
ray_origin_world: wp.vec3,
|
||||||
ray_dir_world: wp.vec3,
|
ray_dir_world: wp.vec3,
|
||||||
max_dist: float,
|
max_dist: float,
|
||||||
@@ -235,76 +286,114 @@ def cast_ray_first_hit(
|
|||||||
"""A simpler version of casting rays that only checks for the first hit."""
|
"""A simpler version of casting rays that only checks for the first hit."""
|
||||||
query = wp.bvh_query_ray(bvh_id, ray_origin_world, ray_dir_world, group_root)
|
query = wp.bvh_query_ray(bvh_id, ray_origin_world, ray_dir_world, group_root)
|
||||||
bounds_nr = int(0)
|
bounds_nr = int(0)
|
||||||
|
ngeom = bvh_ngeom + bvh_nflexgeom
|
||||||
|
|
||||||
while wp.bvh_query_next(query, bounds_nr, max_dist):
|
while wp.bvh_query_next(query, bounds_nr, max_dist):
|
||||||
gi_global = bounds_nr
|
gi_global = bounds_nr
|
||||||
gi_bvh_local = gi_global - (world_id * bvh_ngeom)
|
local_id = gi_global - (worldid * ngeom)
|
||||||
gi = enabled_geom_ids[gi_bvh_local]
|
|
||||||
|
d = float(-1.0)
|
||||||
|
n = wp.vec3(0.0, 0.0, 0.0)
|
||||||
|
|
||||||
|
if local_id < bvh_ngeom:
|
||||||
|
gi = enabled_geom_ids[local_id]
|
||||||
|
gtype = geom_type[gi]
|
||||||
|
else:
|
||||||
|
gi = local_id - bvh_ngeom
|
||||||
|
gtype = GeomType.FLEX
|
||||||
|
|
||||||
# TODO: Investigate branch elimination with static loop unrolling
|
# TODO: Investigate branch elimination with static loop unrolling
|
||||||
if geom_type[gi] == GeomType.PLANE:
|
if gtype == GeomType.PLANE:
|
||||||
d, n = ray_plane(
|
d, n = ray_plane(
|
||||||
geom_xpos_in[world_id, gi],
|
geom_xpos_in[worldid, gi],
|
||||||
geom_xmat_in[world_id, gi],
|
geom_xmat_in[worldid, gi],
|
||||||
geom_size[world_id % geom_size.shape[0], gi],
|
geom_size[worldid % geom_size.shape[0], gi],
|
||||||
ray_origin_world,
|
ray_origin_world,
|
||||||
ray_dir_world,
|
ray_dir_world,
|
||||||
)
|
)
|
||||||
if geom_type[gi] == GeomType.HFIELD:
|
if gtype == GeomType.HFIELD:
|
||||||
d, n, u, v, f, geom_hfield_id = ray_mesh_with_bvh(
|
d, n, u, v, f, geom_hfield_id = ray_mesh_with_bvh(
|
||||||
hfield_bvh_id,
|
hfield_bvh_id,
|
||||||
geom_dataid[gi],
|
geom_dataid[gi],
|
||||||
geom_xpos_in[world_id, gi],
|
geom_xpos_in[worldid, gi],
|
||||||
geom_xmat_in[world_id, gi],
|
geom_xmat_in[worldid, gi],
|
||||||
ray_origin_world,
|
ray_origin_world,
|
||||||
ray_dir_world,
|
ray_dir_world,
|
||||||
max_dist,
|
max_dist,
|
||||||
)
|
)
|
||||||
if geom_type[gi] == GeomType.SPHERE:
|
if gtype == GeomType.SPHERE:
|
||||||
d, n = ray_sphere(
|
d, n = ray_sphere(
|
||||||
geom_xpos_in[world_id, gi],
|
geom_xpos_in[worldid, gi],
|
||||||
geom_size[world_id % geom_size.shape[0], gi][0] * geom_size[world_id % geom_size.shape[0], gi][0],
|
geom_size[worldid % geom_size.shape[0], gi][0] * geom_size[worldid % geom_size.shape[0], gi][0],
|
||||||
ray_origin_world,
|
ray_origin_world,
|
||||||
ray_dir_world,
|
ray_dir_world,
|
||||||
)
|
)
|
||||||
if geom_type[gi] == GeomType.ELLIPSOID:
|
if gtype == GeomType.ELLIPSOID:
|
||||||
d, n = ray_ellipsoid(
|
d, n = ray_ellipsoid(
|
||||||
geom_xpos_in[world_id, gi],
|
geom_xpos_in[worldid, gi],
|
||||||
geom_xmat_in[world_id, gi],
|
geom_xmat_in[worldid, gi],
|
||||||
geom_size[world_id % geom_size.shape[0], gi],
|
geom_size[worldid % geom_size.shape[0], gi],
|
||||||
ray_origin_world,
|
ray_origin_world,
|
||||||
ray_dir_world,
|
ray_dir_world,
|
||||||
)
|
)
|
||||||
if geom_type[gi] == GeomType.CAPSULE:
|
if gtype == GeomType.CAPSULE:
|
||||||
d, n = ray_capsule(
|
d, n = ray_capsule(
|
||||||
geom_xpos_in[world_id, gi],
|
geom_xpos_in[worldid, gi],
|
||||||
geom_xmat_in[world_id, gi],
|
geom_xmat_in[worldid, gi],
|
||||||
geom_size[world_id % geom_size.shape[0], gi],
|
geom_size[worldid % geom_size.shape[0], gi],
|
||||||
ray_origin_world,
|
ray_origin_world,
|
||||||
ray_dir_world,
|
ray_dir_world,
|
||||||
)
|
)
|
||||||
if geom_type[gi] == GeomType.CYLINDER:
|
if gtype == GeomType.CYLINDER:
|
||||||
d, n = ray_cylinder(
|
d, n = ray_cylinder(
|
||||||
geom_xpos_in[world_id, gi],
|
geom_xpos_in[worldid, gi],
|
||||||
geom_xmat_in[world_id, gi],
|
geom_xmat_in[worldid, gi],
|
||||||
geom_size[world_id % geom_size.shape[0], gi],
|
geom_size[worldid % geom_size.shape[0], gi],
|
||||||
ray_origin_world,
|
ray_origin_world,
|
||||||
ray_dir_world,
|
ray_dir_world,
|
||||||
)
|
)
|
||||||
if geom_type[gi] == GeomType.BOX:
|
if gtype == GeomType.BOX:
|
||||||
d, all, n = ray_box(
|
d, all, n = ray_box(
|
||||||
geom_xpos_in[world_id, gi],
|
geom_xpos_in[worldid, gi],
|
||||||
geom_xmat_in[world_id, gi],
|
geom_xmat_in[worldid, gi],
|
||||||
geom_size[world_id % geom_size.shape[0], gi],
|
geom_size[worldid % geom_size.shape[0], gi],
|
||||||
ray_origin_world,
|
ray_origin_world,
|
||||||
ray_dir_world,
|
ray_dir_world,
|
||||||
)
|
)
|
||||||
if geom_type[gi] == GeomType.MESH:
|
if gtype == GeomType.MESH:
|
||||||
hit = ray_mesh_with_bvh_anyhit(
|
hit = ray_mesh_with_bvh_anyhit(
|
||||||
mesh_bvh_id,
|
mesh_bvh_id,
|
||||||
geom_dataid[gi],
|
geom_dataid[gi],
|
||||||
geom_xpos_in[world_id, gi],
|
geom_xpos_in[worldid, gi],
|
||||||
geom_xmat_in[world_id, gi],
|
geom_xmat_in[worldid, gi],
|
||||||
|
ray_origin_world,
|
||||||
|
ray_dir_world,
|
||||||
|
max_dist,
|
||||||
|
)
|
||||||
|
d = 0.0 if hit else -1.0
|
||||||
|
if gtype == GeomType.FLEX:
|
||||||
|
flexid = flex_geom_flexid[gi]
|
||||||
|
edge_id = flex_geom_edgeid[gi]
|
||||||
|
|
||||||
|
if edge_id >= 0:
|
||||||
|
edge = flex_edge[edge_id]
|
||||||
|
vert_adr = flex_vertadr[flexid]
|
||||||
|
v0 = flexvert_xpos_in[worldid, vert_adr + edge[0]]
|
||||||
|
v1 = flexvert_xpos_in[worldid, vert_adr + edge[1]]
|
||||||
|
pos = 0.5 * (v0 + v1)
|
||||||
|
vec = v1 - v0
|
||||||
|
|
||||||
|
length = wp.length(vec)
|
||||||
|
edgeq = math.quat_z2vec(vec)
|
||||||
|
mat = math.quat_to_mat(edgeq)
|
||||||
|
size = wp.vec3(flex_radius[flexid], 0.5 * length, 0.0)
|
||||||
|
|
||||||
|
d, n = ray_capsule(pos, mat, size, ray_origin_world, ray_dir_world)
|
||||||
|
else:
|
||||||
|
hit = ray_flex_with_bvh_anyhit(
|
||||||
|
flex_bvh_id,
|
||||||
|
flexid,
|
||||||
|
flex_group_root[worldid, flexid],
|
||||||
ray_origin_world,
|
ray_origin_world,
|
||||||
ray_dir_world,
|
ray_dir_world,
|
||||||
max_dist,
|
max_dist,
|
||||||
@@ -323,18 +412,27 @@ def compute_lighting(
|
|||||||
geom_type: wp.array(dtype=int),
|
geom_type: wp.array(dtype=int),
|
||||||
geom_dataid: wp.array(dtype=int),
|
geom_dataid: wp.array(dtype=int),
|
||||||
geom_size: wp.array2d(dtype=wp.vec3),
|
geom_size: wp.array2d(dtype=wp.vec3),
|
||||||
|
flex_vertadr: wp.array(dtype=int),
|
||||||
|
flex_edge: wp.array(dtype=wp.vec2i),
|
||||||
|
flex_radius: wp.array(dtype=float),
|
||||||
# Data in:
|
# Data in:
|
||||||
geom_xpos_in: wp.array2d(dtype=wp.vec3),
|
geom_xpos_in: wp.array2d(dtype=wp.vec3),
|
||||||
geom_xmat_in: wp.array2d(dtype=wp.mat33),
|
geom_xmat_in: wp.array2d(dtype=wp.mat33),
|
||||||
|
flexvert_xpos_in: wp.array2d(dtype=wp.vec3),
|
||||||
# In:
|
# In:
|
||||||
use_shadows: bool,
|
use_shadows: bool,
|
||||||
bvh_id: wp.uint64,
|
bvh_id: wp.uint64,
|
||||||
group_root: int,
|
group_root: int,
|
||||||
bvh_ngeom: int,
|
bvh_ngeom: int,
|
||||||
|
bvh_nflexgeom: int,
|
||||||
enabled_geom_ids: wp.array(dtype=int),
|
enabled_geom_ids: wp.array(dtype=int),
|
||||||
world_id: int,
|
worldid: int,
|
||||||
mesh_bvh_id: wp.array(dtype=wp.uint64),
|
mesh_bvh_id: wp.array(dtype=wp.uint64),
|
||||||
hfield_bvh_id: wp.array(dtype=wp.uint64),
|
hfield_bvh_id: wp.array(dtype=wp.uint64),
|
||||||
|
flex_geom_flexid: wp.array(dtype=int),
|
||||||
|
flex_geom_edgeid: wp.array(dtype=int),
|
||||||
|
flex_bvh_id: wp.array(dtype=wp.uint64),
|
||||||
|
flex_group_root: wp.array2d(dtype=int),
|
||||||
lightactive: bool,
|
lightactive: bool,
|
||||||
lighttype: int,
|
lighttype: int,
|
||||||
lightcastshadow: bool,
|
lightcastshadow: bool,
|
||||||
@@ -385,15 +483,24 @@ def compute_lighting(
|
|||||||
geom_type,
|
geom_type,
|
||||||
geom_dataid,
|
geom_dataid,
|
||||||
geom_size,
|
geom_size,
|
||||||
|
flex_vertadr,
|
||||||
|
flex_edge,
|
||||||
|
flex_radius,
|
||||||
geom_xpos_in,
|
geom_xpos_in,
|
||||||
geom_xmat_in,
|
geom_xmat_in,
|
||||||
|
flexvert_xpos_in,
|
||||||
bvh_id,
|
bvh_id,
|
||||||
group_root,
|
group_root,
|
||||||
world_id,
|
worldid,
|
||||||
bvh_ngeom,
|
bvh_ngeom,
|
||||||
|
bvh_nflexgeom,
|
||||||
enabled_geom_ids,
|
enabled_geom_ids,
|
||||||
mesh_bvh_id,
|
mesh_bvh_id,
|
||||||
hfield_bvh_id,
|
hfield_bvh_id,
|
||||||
|
flex_geom_flexid,
|
||||||
|
flex_geom_edgeid,
|
||||||
|
flex_bvh_id,
|
||||||
|
flex_group_root,
|
||||||
shadow_origin,
|
shadow_origin,
|
||||||
L,
|
L,
|
||||||
max_t,
|
max_t,
|
||||||
@@ -418,6 +525,7 @@ def render(m: Model, d: Data, rc: RenderContext):
|
|||||||
"""
|
"""
|
||||||
rc.rgb_data.fill_(rc.background_color)
|
rc.rgb_data.fill_(rc.background_color)
|
||||||
rc.depth_data.fill_(0.0)
|
rc.depth_data.fill_(0.0)
|
||||||
|
rc.seg_data.fill_(-1)
|
||||||
|
|
||||||
@wp.kernel(module="unique", enable_backward=False)
|
@wp.kernel(module="unique", enable_backward=False)
|
||||||
def _render_megakernel(
|
def _render_megakernel(
|
||||||
@@ -434,6 +542,9 @@ def render(m: Model, d: Data, rc: RenderContext):
|
|||||||
light_type: wp.array2d(dtype=int),
|
light_type: wp.array2d(dtype=int),
|
||||||
light_castshadow: wp.array2d(dtype=bool),
|
light_castshadow: wp.array2d(dtype=bool),
|
||||||
light_active: wp.array2d(dtype=bool),
|
light_active: wp.array2d(dtype=bool),
|
||||||
|
flex_vertadr: wp.array(dtype=int),
|
||||||
|
flex_edge: wp.array(dtype=wp.vec2i),
|
||||||
|
flex_radius: wp.array(dtype=float),
|
||||||
mesh_faceadr: wp.array(dtype=int),
|
mesh_faceadr: wp.array(dtype=int),
|
||||||
mat_texid: wp.array3d(dtype=int),
|
mat_texid: wp.array3d(dtype=int),
|
||||||
mat_texrepeat: wp.array2d(dtype=wp.vec2),
|
mat_texrepeat: wp.array2d(dtype=wp.vec2),
|
||||||
@@ -445,21 +556,25 @@ def render(m: Model, d: Data, rc: RenderContext):
|
|||||||
cam_xmat_in: wp.array2d(dtype=wp.mat33),
|
cam_xmat_in: wp.array2d(dtype=wp.mat33),
|
||||||
light_xpos_in: wp.array2d(dtype=wp.vec3),
|
light_xpos_in: wp.array2d(dtype=wp.vec3),
|
||||||
light_xdir_in: wp.array2d(dtype=wp.vec3),
|
light_xdir_in: wp.array2d(dtype=wp.vec3),
|
||||||
|
flexvert_xpos_in: wp.array2d(dtype=wp.vec3),
|
||||||
# In:
|
# In:
|
||||||
nrender: int,
|
nrender: int,
|
||||||
use_shadows: bool,
|
use_shadows: bool,
|
||||||
bvh_ngeom: int,
|
bvh_ngeom: int,
|
||||||
|
bvh_nflexgeom: int,
|
||||||
cam_res: wp.array(dtype=wp.vec2i),
|
cam_res: wp.array(dtype=wp.vec2i),
|
||||||
cam_id_map: wp.array(dtype=int),
|
cam_id_map: wp.array(dtype=int),
|
||||||
ray: wp.array(dtype=wp.vec3),
|
ray: wp.array(dtype=wp.vec3),
|
||||||
rgb_adr: wp.array(dtype=int),
|
rgb_adr: wp.array(dtype=int),
|
||||||
depth_adr: wp.array(dtype=int),
|
depth_adr: wp.array(dtype=int),
|
||||||
|
seg_adr: wp.array(dtype=int),
|
||||||
render_rgb: wp.array(dtype=bool),
|
render_rgb: wp.array(dtype=bool),
|
||||||
render_depth: wp.array(dtype=bool),
|
render_depth: wp.array(dtype=bool),
|
||||||
|
render_seg: wp.array(dtype=bool),
|
||||||
bvh_id: wp.uint64,
|
bvh_id: wp.uint64,
|
||||||
group_root: wp.array(dtype=int),
|
group_root: wp.array(dtype=int),
|
||||||
flex_bvh_id: wp.uint64,
|
flex_bvh_id: wp.array(dtype=wp.uint64),
|
||||||
flex_group_root: wp.array(dtype=int),
|
flex_group_root: wp.array2d(dtype=int),
|
||||||
enabled_geom_ids: wp.array(dtype=int),
|
enabled_geom_ids: wp.array(dtype=int),
|
||||||
mesh_bvh_id: wp.array(dtype=wp.uint64),
|
mesh_bvh_id: wp.array(dtype=wp.uint64),
|
||||||
mesh_facetexcoord: wp.array(dtype=wp.vec3i),
|
mesh_facetexcoord: wp.array(dtype=wp.vec3i),
|
||||||
@@ -467,46 +582,48 @@ def render(m: Model, d: Data, rc: RenderContext):
|
|||||||
mesh_texcoord_offsets: wp.array(dtype=int),
|
mesh_texcoord_offsets: wp.array(dtype=int),
|
||||||
hfield_bvh_id: wp.array(dtype=wp.uint64),
|
hfield_bvh_id: wp.array(dtype=wp.uint64),
|
||||||
flex_rgba: wp.array(dtype=wp.vec4),
|
flex_rgba: wp.array(dtype=wp.vec4),
|
||||||
# TODO: remove after mjwarp depends on warp-lang >= 1.12 in pyproject.toml
|
flex_geom_flexid: wp.array(dtype=int),
|
||||||
textures: wp.array(dtype=TEXTURE_DTYPE),
|
flex_geom_edgeid: wp.array(dtype=int),
|
||||||
|
textures: wp.array(dtype=wp.Texture2D),
|
||||||
# Out:
|
# Out:
|
||||||
rgb_out: wp.array2d(dtype=wp.uint32),
|
rgb_out: wp.array2d(dtype=wp.uint32),
|
||||||
depth_out: wp.array2d(dtype=float),
|
depth_out: wp.array2d(dtype=float),
|
||||||
|
seg_out: wp.array2d(dtype=int),
|
||||||
):
|
):
|
||||||
world_idx, ray_idx = wp.tid()
|
worldid, rayid = wp.tid()
|
||||||
|
|
||||||
# Map global ray_idx -> (cam_idx, ray_idx_local) using cumulative sizes
|
# Map global rayid -> (cam_idx, rayid_local) using cumulative sizes
|
||||||
cam_idx = int(-1)
|
cam_idx = int(-1)
|
||||||
ray_idx_local = int(-1)
|
rayid_local = int(-1)
|
||||||
accum = int(0)
|
accum = int(0)
|
||||||
for i in range(nrender):
|
for i in range(nrender):
|
||||||
num_i = cam_res[i][0] * cam_res[i][1]
|
num_i = cam_res[i][0] * cam_res[i][1]
|
||||||
if ray_idx < accum + num_i:
|
if rayid < accum + num_i:
|
||||||
cam_idx = i
|
cam_idx = i
|
||||||
ray_idx_local = ray_idx - accum
|
rayid_local = rayid - accum
|
||||||
break
|
break
|
||||||
accum += num_i
|
accum += num_i
|
||||||
if cam_idx == -1 or ray_idx_local < 0:
|
if cam_idx == -1 or rayid_local < 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
if not render_rgb[cam_idx] and not render_depth[cam_idx]:
|
if not render_rgb[cam_idx] and not render_depth[cam_idx] and not render_seg[cam_idx]:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Map active camera index to MuJoCo camera ID
|
# Map active camera index to MuJoCo camera ID
|
||||||
mujoco_cam_id = cam_id_map[cam_idx]
|
mujoco_cam_id = cam_id_map[cam_idx]
|
||||||
|
|
||||||
if wp.static(rc.use_precomputed_rays):
|
if wp.static(rc.use_precomputed_rays):
|
||||||
ray_dir_local_cam = ray[ray_idx]
|
ray_dir_local_cam = ray[rayid]
|
||||||
else:
|
else:
|
||||||
img_w = cam_res[cam_idx][0]
|
img_w = cam_res[cam_idx][0]
|
||||||
img_h = cam_res[cam_idx][1]
|
img_h = cam_res[cam_idx][1]
|
||||||
px = ray_idx_local % img_w
|
px = rayid_local % img_w
|
||||||
py = ray_idx_local // img_w
|
py = rayid_local // img_w
|
||||||
ray_dir_local_cam = compute_ray(
|
ray_dir_local_cam = compute_ray(
|
||||||
cam_projection[mujoco_cam_id],
|
cam_projection[mujoco_cam_id],
|
||||||
cam_fovy[world_idx % cam_fovy.shape[0], mujoco_cam_id],
|
cam_fovy[worldid % cam_fovy.shape[0], mujoco_cam_id],
|
||||||
cam_sensorsize[mujoco_cam_id],
|
cam_sensorsize[mujoco_cam_id],
|
||||||
cam_intrinsic[world_idx % cam_intrinsic.shape[0], mujoco_cam_id],
|
cam_intrinsic[worldid % cam_intrinsic.shape[0], mujoco_cam_id],
|
||||||
img_w,
|
img_w,
|
||||||
img_h,
|
img_h,
|
||||||
px,
|
px,
|
||||||
@@ -514,38 +631,37 @@ def render(m: Model, d: Data, rc: RenderContext):
|
|||||||
wp.static(rc.znear),
|
wp.static(rc.znear),
|
||||||
)
|
)
|
||||||
|
|
||||||
ray_dir_world = cam_xmat_in[world_idx, mujoco_cam_id] @ ray_dir_local_cam
|
ray_dir_world = cam_xmat_in[worldid, mujoco_cam_id] @ ray_dir_local_cam
|
||||||
ray_origin_world = cam_xpos_in[world_idx, mujoco_cam_id]
|
ray_origin_world = cam_xpos_in[worldid, mujoco_cam_id]
|
||||||
|
|
||||||
geom_id, dist, normal, u, v, f, mesh_id = cast_ray(
|
geom_id, dist, normal, u, v, f, mesh_id = cast_ray(
|
||||||
geom_type,
|
geom_type,
|
||||||
geom_dataid,
|
geom_dataid,
|
||||||
geom_size,
|
geom_size,
|
||||||
|
flex_vertadr,
|
||||||
|
flex_edge,
|
||||||
|
flex_radius,
|
||||||
geom_xpos_in,
|
geom_xpos_in,
|
||||||
geom_xmat_in,
|
geom_xmat_in,
|
||||||
|
flexvert_xpos_in,
|
||||||
bvh_id,
|
bvh_id,
|
||||||
group_root[world_idx],
|
group_root[worldid],
|
||||||
world_idx,
|
worldid,
|
||||||
bvh_ngeom,
|
bvh_ngeom,
|
||||||
|
bvh_nflexgeom,
|
||||||
enabled_geom_ids,
|
enabled_geom_ids,
|
||||||
mesh_bvh_id,
|
mesh_bvh_id,
|
||||||
hfield_bvh_id,
|
hfield_bvh_id,
|
||||||
|
flex_geom_flexid,
|
||||||
|
flex_geom_edgeid,
|
||||||
|
flex_bvh_id,
|
||||||
|
flex_group_root,
|
||||||
ray_origin_world,
|
ray_origin_world,
|
||||||
ray_dir_world,
|
ray_dir_world,
|
||||||
)
|
)
|
||||||
|
|
||||||
if wp.static(m.nflex > 0):
|
if render_seg[cam_idx] and geom_id != -1:
|
||||||
d, n, u, v, f = ray_flex_with_bvh(
|
seg_out[worldid, seg_adr[cam_idx] + rayid_local] = geom_id
|
||||||
flex_bvh_id,
|
|
||||||
flex_group_root[world_idx],
|
|
||||||
ray_origin_world,
|
|
||||||
ray_dir_world,
|
|
||||||
dist,
|
|
||||||
)
|
|
||||||
if d >= 0.0 and d < dist:
|
|
||||||
dist = d
|
|
||||||
normal = n
|
|
||||||
geom_id = -2
|
|
||||||
|
|
||||||
# Early Out
|
# Early Out
|
||||||
if geom_id == -1:
|
if geom_id == -1:
|
||||||
@@ -556,9 +672,7 @@ def render(m: Model, d: Data, rc: RenderContext):
|
|||||||
# In camera-local coordinates, the optical axis is -Z. The Z-component of the
|
# In camera-local coordinates, the optical axis is -Z. The Z-component of the
|
||||||
# normalized ray direction is negative, so -ray_dir_local_cam[2] gives cos(θ)
|
# normalized ray direction is negative, so -ray_dir_local_cam[2] gives cos(θ)
|
||||||
# between the ray and the optical axis.
|
# between the ray and the optical axis.
|
||||||
depth_out[world_idx, depth_adr[cam_idx] + ray_idx_local] = dist * (
|
depth_out[worldid, depth_adr[cam_idx] + rayid_local] = dist * (-ray_dir_local_cam[2])
|
||||||
-ray_dir_local_cam[2]
|
|
||||||
)
|
|
||||||
|
|
||||||
if not render_rgb[cam_idx]:
|
if not render_rgb[cam_idx]:
|
||||||
return
|
return
|
||||||
@@ -567,31 +681,30 @@ def render(m: Model, d: Data, rc: RenderContext):
|
|||||||
hit_point = ray_origin_world + ray_dir_world * dist
|
hit_point = ray_origin_world + ray_dir_world * dist
|
||||||
|
|
||||||
if geom_id == -2:
|
if geom_id == -2:
|
||||||
# TODO: Currently flex textures are not supported, and only the first rgba value
|
# We encode flex_id in mesh_id for flex ray hits during cast_ray
|
||||||
# is used until further flex support is added.
|
color = flex_rgba[mesh_id]
|
||||||
color = flex_rgba[0]
|
elif geom_matid[worldid % geom_matid.shape[0], geom_id] == -1:
|
||||||
elif geom_matid[world_idx % geom_matid.shape[0], geom_id] == -1:
|
color = geom_rgba[worldid % geom_rgba.shape[0], geom_id]
|
||||||
color = geom_rgba[world_idx % geom_rgba.shape[0], geom_id]
|
|
||||||
else:
|
else:
|
||||||
color = mat_rgba[world_idx % mat_rgba.shape[0], geom_matid[world_idx % geom_matid.shape[0], geom_id]]
|
color = mat_rgba[worldid % mat_rgba.shape[0], geom_matid[worldid % geom_matid.shape[0], geom_id]]
|
||||||
|
|
||||||
base_color = wp.vec3(color[0], color[1], color[2])
|
base_color = wp.vec3(color[0], color[1], color[2])
|
||||||
hit_color = base_color
|
hit_color = base_color
|
||||||
|
|
||||||
if wp.static(rc.use_textures):
|
if wp.static(rc.use_textures):
|
||||||
if geom_id != -2:
|
if geom_id != -2:
|
||||||
mat_id = geom_matid[world_idx % geom_matid.shape[0], geom_id]
|
mat_id = geom_matid[worldid % geom_matid.shape[0], geom_id]
|
||||||
if mat_id >= 0:
|
if mat_id >= 0:
|
||||||
tex_id = mat_texid[world_idx % mat_texid.shape[0], mat_id, 1]
|
tex_id = mat_texid[worldid % mat_texid.shape[0], mat_id, 1]
|
||||||
if tex_id >= 0:
|
if tex_id >= 0:
|
||||||
tex_color = sample_texture(
|
tex_color = sample_texture(
|
||||||
geom_type,
|
geom_type,
|
||||||
mesh_faceadr,
|
mesh_faceadr,
|
||||||
geom_id,
|
geom_id,
|
||||||
mat_texrepeat[world_idx % mat_texrepeat.shape[0], mat_id],
|
mat_texrepeat[worldid % mat_texrepeat.shape[0], mat_id],
|
||||||
textures[tex_id],
|
textures[tex_id],
|
||||||
geom_xpos_in[world_idx, geom_id],
|
geom_xpos_in[worldid, geom_id],
|
||||||
geom_xmat_in[world_idx, geom_id],
|
geom_xmat_in[worldid, geom_id],
|
||||||
mesh_facetexcoord,
|
mesh_facetexcoord,
|
||||||
mesh_texcoord,
|
mesh_texcoord,
|
||||||
mesh_texcoord_offsets,
|
mesh_texcoord_offsets,
|
||||||
@@ -616,21 +729,30 @@ def render(m: Model, d: Data, rc: RenderContext):
|
|||||||
geom_type,
|
geom_type,
|
||||||
geom_dataid,
|
geom_dataid,
|
||||||
geom_size,
|
geom_size,
|
||||||
|
flex_vertadr,
|
||||||
|
flex_edge,
|
||||||
|
flex_radius,
|
||||||
geom_xpos_in,
|
geom_xpos_in,
|
||||||
geom_xmat_in,
|
geom_xmat_in,
|
||||||
|
flexvert_xpos_in,
|
||||||
use_shadows,
|
use_shadows,
|
||||||
bvh_id,
|
bvh_id,
|
||||||
group_root[world_idx],
|
group_root[worldid],
|
||||||
bvh_ngeom,
|
bvh_ngeom,
|
||||||
|
bvh_nflexgeom,
|
||||||
enabled_geom_ids,
|
enabled_geom_ids,
|
||||||
world_idx,
|
worldid,
|
||||||
mesh_bvh_id,
|
mesh_bvh_id,
|
||||||
hfield_bvh_id,
|
hfield_bvh_id,
|
||||||
light_active[world_idx % light_active.shape[0], l],
|
flex_geom_flexid,
|
||||||
light_type[world_idx % light_type.shape[0], l],
|
flex_geom_edgeid,
|
||||||
light_castshadow[world_idx % light_castshadow.shape[0], l],
|
flex_bvh_id,
|
||||||
light_xpos_in[world_idx, l],
|
flex_group_root,
|
||||||
light_xdir_in[world_idx, l],
|
light_active[worldid % light_active.shape[0], l],
|
||||||
|
light_type[worldid % light_type.shape[0], l],
|
||||||
|
light_castshadow[worldid % light_castshadow.shape[0], l],
|
||||||
|
light_xpos_in[worldid, l],
|
||||||
|
light_xdir_in[worldid, l],
|
||||||
normal,
|
normal,
|
||||||
hit_point,
|
hit_point,
|
||||||
)
|
)
|
||||||
@@ -639,7 +761,7 @@ def render(m: Model, d: Data, rc: RenderContext):
|
|||||||
hit_color = wp.min(result, wp.vec3(1.0, 1.0, 1.0))
|
hit_color = wp.min(result, wp.vec3(1.0, 1.0, 1.0))
|
||||||
hit_color = wp.max(hit_color, wp.vec3(0.0, 0.0, 0.0))
|
hit_color = wp.max(hit_color, wp.vec3(0.0, 0.0, 0.0))
|
||||||
|
|
||||||
rgb_out[world_idx, rgb_adr[cam_idx] + ray_idx_local] = pack_rgba_to_uint32(
|
rgb_out[worldid, rgb_adr[cam_idx] + rayid_local] = pack_rgba_to_uint32(
|
||||||
hit_color[0] * 255.0,
|
hit_color[0] * 255.0,
|
||||||
hit_color[1] * 255.0,
|
hit_color[1] * 255.0,
|
||||||
hit_color[2] * 255.0,
|
hit_color[2] * 255.0,
|
||||||
@@ -662,6 +784,9 @@ def render(m: Model, d: Data, rc: RenderContext):
|
|||||||
m.light_type,
|
m.light_type,
|
||||||
m.light_castshadow,
|
m.light_castshadow,
|
||||||
m.light_active,
|
m.light_active,
|
||||||
|
m.flex_vertadr,
|
||||||
|
m.flex_edge,
|
||||||
|
m.flex_radius,
|
||||||
m.mesh_faceadr,
|
m.mesh_faceadr,
|
||||||
m.mat_texid,
|
m.mat_texid,
|
||||||
m.mat_texrepeat,
|
m.mat_texrepeat,
|
||||||
@@ -672,16 +797,20 @@ def render(m: Model, d: Data, rc: RenderContext):
|
|||||||
d.cam_xmat,
|
d.cam_xmat,
|
||||||
d.light_xpos,
|
d.light_xpos,
|
||||||
d.light_xdir,
|
d.light_xdir,
|
||||||
|
d.flexvert_xpos,
|
||||||
rc.nrender,
|
rc.nrender,
|
||||||
rc.use_shadows,
|
rc.use_shadows,
|
||||||
rc.bvh_ngeom,
|
rc.bvh_ngeom,
|
||||||
|
rc.bvh_nflexgeom,
|
||||||
rc.cam_res,
|
rc.cam_res,
|
||||||
rc.cam_id_map,
|
rc.cam_id_map,
|
||||||
rc.ray,
|
rc.ray,
|
||||||
rc.rgb_adr,
|
rc.rgb_adr,
|
||||||
rc.depth_adr,
|
rc.depth_adr,
|
||||||
|
rc.seg_adr,
|
||||||
rc.render_rgb,
|
rc.render_rgb,
|
||||||
rc.render_depth,
|
rc.render_depth,
|
||||||
|
rc.render_seg,
|
||||||
rc.bvh_id,
|
rc.bvh_id,
|
||||||
rc.group_root,
|
rc.group_root,
|
||||||
rc.flex_bvh_id,
|
rc.flex_bvh_id,
|
||||||
@@ -693,10 +822,13 @@ def render(m: Model, d: Data, rc: RenderContext):
|
|||||||
rc.mesh_texcoord_offsets,
|
rc.mesh_texcoord_offsets,
|
||||||
rc.hfield_bvh_id,
|
rc.hfield_bvh_id,
|
||||||
rc.flex_rgba,
|
rc.flex_rgba,
|
||||||
|
rc.flex_geom_flexid,
|
||||||
|
rc.flex_geom_edgeid,
|
||||||
rc.textures,
|
rc.textures,
|
||||||
],
|
],
|
||||||
outputs=[
|
outputs=[
|
||||||
rc.rgb_data,
|
rc.rgb_data,
|
||||||
rc.depth_data,
|
rc.depth_data,
|
||||||
|
rc.seg_data,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -206,3 +206,41 @@ def get_depth(rc: RenderContext, camera_index: int, depth_scale: float, depth_ou
|
|||||||
inputs=[rc.depth_data, rc.depth_adr, camera_index, depth_scale],
|
inputs=[rc.depth_data, rc.depth_adr, camera_index, depth_scale],
|
||||||
outputs=[depth_out],
|
outputs=[depth_out],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@wp.kernel
|
||||||
|
def _extract_seg_kernel(
|
||||||
|
# In:
|
||||||
|
seg_data: wp.array2d(dtype=int),
|
||||||
|
seg_adr: wp.array(dtype=int),
|
||||||
|
camera_index: int,
|
||||||
|
# Out:
|
||||||
|
seg_out: wp.array3d(dtype=int),
|
||||||
|
):
|
||||||
|
"""Extract per-pixel geom IDs from the render context buffers for a given camera index."""
|
||||||
|
worldid, pixelid = wp.tid()
|
||||||
|
xid = pixelid % seg_out.shape[2]
|
||||||
|
yid = pixelid // seg_out.shape[2]
|
||||||
|
|
||||||
|
seg_adr_offset = seg_adr[camera_index]
|
||||||
|
seg_out[worldid, yid, xid] = seg_data[worldid, seg_adr_offset + pixelid]
|
||||||
|
|
||||||
|
|
||||||
|
def get_segmentation(rc: RenderContext, camera_index: int, seg_out: wp.array3d(dtype=int)):
|
||||||
|
"""Get the segmentation data from the render context buffers for a given camera index.
|
||||||
|
|
||||||
|
Each pixel contains the MuJoCo geom ID of the geometry hit by the ray, -1 for
|
||||||
|
background, or -2 for flex bodies.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
rc: The render context on device.
|
||||||
|
camera_index: The index of the camera to get the segmentation data for.
|
||||||
|
seg_out: The output array to store the geom IDs in, with shape
|
||||||
|
(nworld, height, width).
|
||||||
|
"""
|
||||||
|
wp.launch(
|
||||||
|
_extract_seg_kernel,
|
||||||
|
dim=(seg_out.shape[0], seg_out.shape[1] * seg_out.shape[2]),
|
||||||
|
inputs=[rc.seg_data, rc.seg_adr, camera_index],
|
||||||
|
outputs=[seg_out],
|
||||||
|
)
|
||||||
|
|||||||
+18
-44
@@ -15,12 +15,17 @@
|
|||||||
|
|
||||||
from typing import Any, Tuple
|
from typing import Any, Tuple
|
||||||
|
|
||||||
|
import warp as wp
|
||||||
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src import math
|
from mujoco.mjx.third_party.mujoco_warp._src import math
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src import ray
|
from mujoco.mjx.third_party.mujoco_warp._src import ray
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src import smooth
|
from mujoco.mjx.third_party.mujoco_warp._src import smooth
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src import support
|
from mujoco.mjx.third_party.mujoco_warp._src import support
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_sdf import get_sdf_params
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_sdf import get_sdf_params
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.collision_sdf import sdf
|
from mujoco.mjx.third_party.mujoco_warp._src.collision_sdf import sdf
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MAXCONPAIR
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MAXVAL
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MINVAL
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import ConeType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import ConeType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import ConstraintType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import ConstraintType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import ContactType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import ContactType
|
||||||
@@ -28,9 +33,6 @@ from mujoco.mjx.third_party.mujoco_warp._src.types import Data
|
|||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import DataType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import DataType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import DisableBit
|
from mujoco.mjx.third_party.mujoco_warp._src.types import DisableBit
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import JointType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import JointType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MAXCONPAIR
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MAXVAL
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MINVAL
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import Model
|
from mujoco.mjx.third_party.mujoco_warp._src.types import Model
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import ObjType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import ObjType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import SensorType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import SensorType
|
||||||
@@ -40,10 +42,10 @@ from mujoco.mjx.third_party.mujoco_warp._src.types import vec5
|
|||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import vec6
|
from mujoco.mjx.third_party.mujoco_warp._src.types import vec6
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import vec8
|
from mujoco.mjx.third_party.mujoco_warp._src.types import vec8
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import vec8i
|
from mujoco.mjx.third_party.mujoco_warp._src.types import vec8i
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import vec_pluginattr
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.util_misc import inside_geom
|
from mujoco.mjx.third_party.mujoco_warp._src.util_misc import inside_geom
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import cache_kernel
|
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import cache_kernel
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import event_scope
|
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import event_scope
|
||||||
import warp as wp
|
|
||||||
|
|
||||||
wp.set_module_options({"enable_backward": False})
|
wp.set_module_options({"enable_backward": False})
|
||||||
|
|
||||||
@@ -2126,6 +2128,7 @@ def _sensor_tactile(
|
|||||||
oct_coeff: wp.array(dtype=vec8),
|
oct_coeff: wp.array(dtype=vec8),
|
||||||
geom_type: wp.array(dtype=int),
|
geom_type: wp.array(dtype=int),
|
||||||
geom_bodyid: wp.array(dtype=int),
|
geom_bodyid: wp.array(dtype=int),
|
||||||
|
geom_dataid: wp.array(dtype=int),
|
||||||
geom_size: wp.array2d(dtype=wp.vec3),
|
geom_size: wp.array2d(dtype=wp.vec3),
|
||||||
mesh_vertadr: wp.array(dtype=int),
|
mesh_vertadr: wp.array(dtype=int),
|
||||||
mesh_vertnum: wp.array(dtype=int),
|
mesh_vertnum: wp.array(dtype=int),
|
||||||
@@ -2140,7 +2143,7 @@ def _sensor_tactile(
|
|||||||
sensor_dim: wp.array(dtype=int),
|
sensor_dim: wp.array(dtype=int),
|
||||||
sensor_adr: wp.array(dtype=int),
|
sensor_adr: wp.array(dtype=int),
|
||||||
plugin: wp.array(dtype=int),
|
plugin: wp.array(dtype=int),
|
||||||
plugin_attr: wp.array(dtype=wp.vec3f),
|
plugin_attr: wp.array(dtype=vec_pluginattr),
|
||||||
geom_plugin_index: wp.array(dtype=int),
|
geom_plugin_index: wp.array(dtype=int),
|
||||||
taxel_vertadr: wp.array(dtype=int),
|
taxel_vertadr: wp.array(dtype=int),
|
||||||
taxel_sensorid: wp.array(dtype=int),
|
taxel_sensorid: wp.array(dtype=int),
|
||||||
@@ -2220,31 +2223,16 @@ def _sensor_tactile(
|
|||||||
contact_type,
|
contact_type,
|
||||||
geom_size[worldid % geom_size.shape[0], geom],
|
geom_size[worldid % geom_size.shape[0], geom],
|
||||||
plugin_id,
|
plugin_id,
|
||||||
mesh_id,
|
geom_dataid[geom],
|
||||||
)
|
)
|
||||||
|
|
||||||
depth = wp.min(
|
depth = wp.min(sdf(contact_type, lpos, plugin_attributes, plugin_index, volume_data, mesh_data), 0.0)
|
||||||
sdf(
|
|
||||||
contact_type,
|
|
||||||
lpos,
|
|
||||||
plugin_attributes,
|
|
||||||
plugin_index,
|
|
||||||
volume_data,
|
|
||||||
mesh_data,
|
|
||||||
),
|
|
||||||
0.0,
|
|
||||||
)
|
|
||||||
if depth >= 0.0:
|
if depth >= 0.0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
vel_sensor = _transform_spatial(
|
vel_sensor = _transform_spatial(cvel_in[worldid, parent_weld], xpos - subtree_com_in[worldid, body_rootid[parent_weld]])
|
||||||
cvel_in[worldid, parent_weld],
|
|
||||||
xpos - subtree_com_in[worldid, body_rootid[parent_weld]],
|
|
||||||
)
|
|
||||||
vel_other = _transform_spatial(
|
vel_other = _transform_spatial(
|
||||||
cvel_in[worldid, body],
|
cvel_in[worldid, body], geom_xpos_in[worldid, geom] - subtree_com_in[worldid, body_rootid[body]]
|
||||||
geom_xpos_in[worldid, geom]
|
|
||||||
- subtree_com_in[worldid, body_rootid[body]],
|
|
||||||
)
|
)
|
||||||
vel_rel = vel_sensor - vel_other
|
vel_rel = vel_sensor - vel_other
|
||||||
|
|
||||||
@@ -2259,24 +2247,9 @@ def _sensor_tactile(
|
|||||||
forceT[2] = wp.abs(wp.dot(vel_rel, tang2))
|
forceT[2] = wp.abs(wp.dot(vel_rel, tang2))
|
||||||
|
|
||||||
dim = sensor_dim[sensor_id] // 3
|
dim = sensor_dim[sensor_id] // 3
|
||||||
wp.atomic_add(
|
wp.atomic_add(sensordata_out, worldid, sensor_adr[sensor_id] + 0 * dim + vertid, forceT[0])
|
||||||
sensordata_out,
|
wp.atomic_add(sensordata_out, worldid, sensor_adr[sensor_id] + 1 * dim + vertid, forceT[1])
|
||||||
worldid,
|
wp.atomic_add(sensordata_out, worldid, sensor_adr[sensor_id] + 2 * dim + vertid, forceT[2])
|
||||||
sensor_adr[sensor_id] + 0 * dim + vertid,
|
|
||||||
forceT[0],
|
|
||||||
)
|
|
||||||
wp.atomic_add(
|
|
||||||
sensordata_out,
|
|
||||||
worldid,
|
|
||||||
sensor_adr[sensor_id] + 1 * dim + vertid,
|
|
||||||
forceT[1],
|
|
||||||
)
|
|
||||||
wp.atomic_add(
|
|
||||||
sensordata_out,
|
|
||||||
worldid,
|
|
||||||
sensor_adr[sensor_id] + 2 * dim + vertid,
|
|
||||||
forceT[2],
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@wp.func
|
@wp.func
|
||||||
@@ -2533,6 +2506,7 @@ def sensor_acc(m: Model, d: Data):
|
|||||||
m.oct_coeff,
|
m.oct_coeff,
|
||||||
m.geom_type,
|
m.geom_type,
|
||||||
m.geom_bodyid,
|
m.geom_bodyid,
|
||||||
|
m.geom_dataid,
|
||||||
m.geom_size,
|
m.geom_size,
|
||||||
m.mesh_vertadr,
|
m.mesh_vertadr,
|
||||||
m.mesh_vertnum,
|
m.mesh_vertnum,
|
||||||
@@ -2882,12 +2856,12 @@ def energy_pos(m: Model, d: Data):
|
|||||||
wp.launch(_energy_pos_zero, dim=d.nworld, outputs=[d.energy])
|
wp.launch(_energy_pos_zero, dim=d.nworld, outputs=[d.energy])
|
||||||
|
|
||||||
# init potential energy: -sum_i(body_i.mass * dot(gravity, body_i.pos))
|
# init potential energy: -sum_i(body_i.mass * dot(gravity, body_i.pos))
|
||||||
if not m.opt.disableflags & DisableBit.GRAVITY:
|
if not (m.opt.disableflags & DisableBit.GRAVITY):
|
||||||
wp.launch(
|
wp.launch(
|
||||||
_energy_pos_gravity, dim=(d.nworld, m.nbody - 1), inputs=[m.opt.gravity, m.body_mass, d.xipos], outputs=[d.energy]
|
_energy_pos_gravity, dim=(d.nworld, m.nbody - 1), inputs=[m.opt.gravity, m.body_mass, d.xipos], outputs=[d.energy]
|
||||||
)
|
)
|
||||||
|
|
||||||
if not m.opt.disableflags & DisableBit.SPRING:
|
if not (m.opt.disableflags & DisableBit.SPRING):
|
||||||
# add joint-level springs
|
# add joint-level springs
|
||||||
wp.launch(
|
wp.launch(
|
||||||
_energy_pos_passive_joint,
|
_energy_pos_passive_joint,
|
||||||
|
|||||||
+604
-356
File diff suppressed because it is too large
Load Diff
+111
-263
@@ -17,17 +17,17 @@ import dataclasses
|
|||||||
from math import ceil
|
from math import ceil
|
||||||
from math import sqrt
|
from math import sqrt
|
||||||
|
|
||||||
|
import warp as wp
|
||||||
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src import math
|
from mujoco.mjx.third_party.mujoco_warp._src import math
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src import smooth
|
from mujoco.mjx.third_party.mujoco_warp._src import smooth
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src import support
|
from mujoco.mjx.third_party.mujoco_warp._src import support
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src import types
|
from mujoco.mjx.third_party.mujoco_warp._src import types
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.block_cholesky import create_blocked_cholesky_func
|
from mujoco.mjx.third_party.mujoco_warp._src.block_cholesky import create_blocked_cholesky_func
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.block_cholesky import create_blocked_cholesky_solve_func
|
from mujoco.mjx.third_party.mujoco_warp._src.block_cholesky import create_blocked_cholesky_solve_func
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import SPARSE_CONSTRAINT_JACOBIAN
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import cache_kernel
|
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import cache_kernel
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import event_scope
|
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import event_scope
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import scoped_mathdx_gemm_disabled
|
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import scoped_mathdx_gemm_disabled
|
||||||
import warp as wp
|
|
||||||
|
|
||||||
wp.set_module_options({"enable_backward": False})
|
wp.set_module_options({"enable_backward": False})
|
||||||
|
|
||||||
@@ -139,18 +139,10 @@ def create_solver_context(m: types.Model, d: types.Data) -> SolverContext:
|
|||||||
prev_grad=wp.empty((nworld, nv), dtype=float),
|
prev_grad=wp.empty((nworld, nv), dtype=float),
|
||||||
prev_Mgrad=wp.empty((nworld, nv), dtype=float),
|
prev_Mgrad=wp.empty((nworld, nv), dtype=float),
|
||||||
beta=wp.empty((nworld,), dtype=float),
|
beta=wp.empty((nworld,), dtype=float),
|
||||||
h=wp.zeros((nworld, nv_pad, nv_pad), dtype=float)
|
h=wp.zeros((nworld, nv_pad, nv_pad), dtype=float) if alloc_h else wp.empty((nworld, 0, 0), dtype=float),
|
||||||
if alloc_h
|
hfactor=wp.zeros((nworld, nv_pad, nv_pad), dtype=float) if alloc_hfactor else wp.empty((nworld, 0, 0), dtype=float),
|
||||||
else wp.empty((nworld, 0, 0), dtype=float),
|
changed_efc_ids=wp.empty((nworld, njmax), dtype=int) if alloc_h else wp.empty((nworld, 0), dtype=int),
|
||||||
hfactor=wp.zeros((nworld, nv_pad, nv_pad), dtype=float)
|
changed_efc_count=wp.empty((nworld,), dtype=int) if alloc_h else wp.empty((0,), dtype=int),
|
||||||
if alloc_hfactor
|
|
||||||
else wp.empty((nworld, 0, 0), dtype=float),
|
|
||||||
changed_efc_ids=wp.empty((nworld, njmax), dtype=int)
|
|
||||||
if alloc_h
|
|
||||||
else wp.empty((nworld, 0), dtype=int),
|
|
||||||
changed_efc_count=wp.empty((nworld,), dtype=int)
|
|
||||||
if alloc_h
|
|
||||||
else wp.empty((0,), dtype=int),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -892,18 +884,19 @@ def _compute_efc_eval_pt_3alphas_elliptic(
|
|||||||
|
|
||||||
|
|
||||||
@cache_kernel
|
@cache_kernel
|
||||||
def linesearch_iterative(ls_iterations: int, cone_type: types.ConeType, fuse_jv: bool):
|
def linesearch_iterative(ls_iterations: int, cone_type: types.ConeType, fuse_jv: bool, is_sparse: bool):
|
||||||
"""Factory for iterative linesearch kernel.
|
"""Factory for iterative linesearch kernel.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
block_dim: Number of threads per block for tile reductions.
|
|
||||||
ls_iterations: Max linesearch iterations (compile-time constant for loop optimization).
|
ls_iterations: Max linesearch iterations (compile-time constant for loop optimization).
|
||||||
cone_type: Friction cone type (PYRAMIDAL or ELLIPTIC) for compile-time optimization.
|
cone_type: Friction cone type (PYRAMIDAL or ELLIPTIC) for compile-time optimization.
|
||||||
fuse_jv: Whether to compute jv = J @ search in-kernel (efficient for small nv).
|
fuse_jv: Whether to compute jv = J @ search in-kernel (efficient for small nv).
|
||||||
|
is_sparse: Use sparse matrix representation for constraint Jacobian.
|
||||||
"""
|
"""
|
||||||
LS_ITERATIONS = ls_iterations
|
LS_ITERATIONS = ls_iterations
|
||||||
IS_ELLIPTIC = cone_type == types.ConeType.ELLIPTIC
|
IS_ELLIPTIC = cone_type == types.ConeType.ELLIPTIC
|
||||||
FUSE_JV = fuse_jv
|
FUSE_JV = fuse_jv
|
||||||
|
IS_SPARSE = is_sparse
|
||||||
|
|
||||||
# Native snippet for CUDA __syncthreads()
|
# Native snippet for CUDA __syncthreads()
|
||||||
@wp.func_native(snippet="WP_TILE_SYNC();")
|
@wp.func_native(snippet="WP_TILE_SYNC();")
|
||||||
@@ -976,15 +969,13 @@ def linesearch_iterative(ls_iterations: int, cone_type: types.ConeType, fuse_jv:
|
|||||||
if wp.static(FUSE_JV):
|
if wp.static(FUSE_JV):
|
||||||
for efcid in range(tid, nefc, wp.block_dim()):
|
for efcid in range(tid, nefc, wp.block_dim()):
|
||||||
jv = float(0.0)
|
jv = float(0.0)
|
||||||
if wp.static(SPARSE_CONSTRAINT_JACOBIAN):
|
if wp.static(IS_SPARSE):
|
||||||
rownnz = efc_J_rownnz_in[worldid, efcid]
|
rownnz = efc_J_rownnz_in[worldid, efcid]
|
||||||
rowadr = efc_J_rowadr_in[worldid, efcid]
|
rowadr = efc_J_rowadr_in[worldid, efcid]
|
||||||
for k in range(rownnz):
|
for k in range(rownnz):
|
||||||
sparseid = rowadr + k
|
sparseid = rowadr + k
|
||||||
colind = efc_J_colind_in[worldid, 0, sparseid]
|
colind = efc_J_colind_in[worldid, 0, sparseid]
|
||||||
jv += (
|
jv += efc_J_in[worldid, 0, sparseid] * ctx_search_in[worldid, colind]
|
||||||
efc_J_in[worldid, 0, sparseid] * ctx_search_in[worldid, colind]
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
for i in range(nv):
|
for i in range(nv):
|
||||||
jv += efc_J_in[worldid, efcid, i] * ctx_search_in[worldid, i]
|
jv += efc_J_in[worldid, efcid, i] * ctx_search_in[worldid, i]
|
||||||
@@ -1360,7 +1351,7 @@ def _linesearch_iterative(m: types.Model, d: types.Data, ctx: SolverContext, fus
|
|||||||
fuse_jv: Whether jv is computed in-kernel (True) or pre-computed (False).
|
fuse_jv: Whether jv is computed in-kernel (True) or pre-computed (False).
|
||||||
"""
|
"""
|
||||||
wp.launch_tiled(
|
wp.launch_tiled(
|
||||||
linesearch_iterative(m.opt.ls_iterations, m.opt.cone, fuse_jv),
|
linesearch_iterative(m.opt.ls_iterations, m.opt.cone, fuse_jv, m.is_sparse),
|
||||||
dim=d.nworld,
|
dim=d.nworld,
|
||||||
inputs=[
|
inputs=[
|
||||||
m.nv,
|
m.nv,
|
||||||
@@ -1420,7 +1411,7 @@ def linesearch_zero_jv(
|
|||||||
|
|
||||||
|
|
||||||
@cache_kernel
|
@cache_kernel
|
||||||
def linesearch_jv_fused(opt_is_sparse: bool, nv: int, dofs_per_thread: int):
|
def linesearch_jv_fused(is_sparse: bool, nv: int, dofs_per_thread: int):
|
||||||
@wp.kernel(module="unique", enable_backward=False)
|
@wp.kernel(module="unique", enable_backward=False)
|
||||||
def kernel(
|
def kernel(
|
||||||
# Data in:
|
# Data in:
|
||||||
@@ -1446,23 +1437,21 @@ def linesearch_jv_fused(opt_is_sparse: bool, nv: int, dofs_per_thread: int):
|
|||||||
jv_out = float(0.0)
|
jv_out = float(0.0)
|
||||||
|
|
||||||
if wp.static(dofs_per_thread >= nv):
|
if wp.static(dofs_per_thread >= nv):
|
||||||
if wp.static(SPARSE_CONSTRAINT_JACOBIAN):
|
if wp.static(is_sparse):
|
||||||
# Sparse: iterate over non-zero entries in the row
|
# Sparse: iterate over non-zero entries in the row
|
||||||
rownnz = efc_J_rownnz_in[worldid, efcid]
|
rownnz = efc_J_rownnz_in[worldid, efcid]
|
||||||
rowadr = efc_J_rowadr_in[worldid, efcid]
|
rowadr = efc_J_rowadr_in[worldid, efcid]
|
||||||
for k in range(rownnz):
|
for k in range(rownnz):
|
||||||
sparseid = rowadr + k
|
sparseid = rowadr + k
|
||||||
colind = efc_J_colind_in[worldid, 0, sparseid]
|
colind = efc_J_colind_in[worldid, 0, sparseid]
|
||||||
jv_out += (
|
jv_out += efc_J_in[worldid, 0, sparseid] * ctx_search_in[worldid, colind]
|
||||||
efc_J_in[worldid, 0, sparseid] * ctx_search_in[worldid, colind]
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
for i in range(wp.static(min(dofs_per_thread, nv))):
|
for i in range(wp.static(min(dofs_per_thread, nv))):
|
||||||
jv_out += efc_J_in[worldid, efcid, i] * ctx_search_in[worldid, i]
|
jv_out += efc_J_in[worldid, efcid, i] * ctx_search_in[worldid, i]
|
||||||
ctx_jv_out[worldid, efcid] = jv_out
|
ctx_jv_out[worldid, efcid] = jv_out
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if wp.static(SPARSE_CONSTRAINT_JACOBIAN):
|
if wp.static(is_sparse):
|
||||||
# Sparse: thread 0 handles entire row (sparse entries << nv typically)
|
# Sparse: thread 0 handles entire row (sparse entries << nv typically)
|
||||||
if dofstart == 0:
|
if dofstart == 0:
|
||||||
rownnz = efc_J_rownnz_in[worldid, efcid]
|
rownnz = efc_J_rownnz_in[worldid, efcid]
|
||||||
@@ -1470,9 +1459,7 @@ def linesearch_jv_fused(opt_is_sparse: bool, nv: int, dofs_per_thread: int):
|
|||||||
for k in range(rownnz):
|
for k in range(rownnz):
|
||||||
sparseid = rowadr + k
|
sparseid = rowadr + k
|
||||||
colind = efc_J_colind_in[worldid, 0, sparseid]
|
colind = efc_J_colind_in[worldid, 0, sparseid]
|
||||||
jv_out += (
|
jv_out += efc_J_in[worldid, 0, sparseid] * ctx_search_in[worldid, colind]
|
||||||
efc_J_in[worldid, 0, sparseid] * ctx_search_in[worldid, colind]
|
|
||||||
)
|
|
||||||
ctx_jv_out[worldid, efcid] = jv_out
|
ctx_jv_out[worldid, efcid] = jv_out
|
||||||
else:
|
else:
|
||||||
for i in range(wp.static(dofs_per_thread)):
|
for i in range(wp.static(dofs_per_thread)):
|
||||||
@@ -1583,10 +1570,7 @@ def linesearch_prepare_quad(
|
|||||||
|
|
||||||
dim = contact_dim_in[conid]
|
dim = contact_dim_in[conid]
|
||||||
friction = contact_friction_in[conid]
|
friction = contact_friction_in[conid]
|
||||||
mu = (
|
mu = friction[0] * opt_impratio_invsqrt[worldid % opt_impratio_invsqrt.shape[0]]
|
||||||
friction[0]
|
|
||||||
* opt_impratio_invsqrt[worldid % opt_impratio_invsqrt.shape[0]]
|
|
||||||
)
|
|
||||||
|
|
||||||
u0 = Jaref * mu
|
u0 = Jaref * mu
|
||||||
v0 = jv * mu
|
v0 = jv * mu
|
||||||
@@ -1709,15 +1693,7 @@ def _linesearch(m: types.Model, d: types.Data, ctx: SolverContext, cost: wp.arra
|
|||||||
wp.launch(
|
wp.launch(
|
||||||
linesearch_jv_fused(m.is_sparse, m.nv, dofs_per_thread),
|
linesearch_jv_fused(m.is_sparse, m.nv, dofs_per_thread),
|
||||||
dim=(d.nworld, d.njmax, threads_per_efc),
|
dim=(d.nworld, d.njmax, threads_per_efc),
|
||||||
inputs=[
|
inputs=[d.nefc, d.efc.J_rownnz, d.efc.J_rowadr, d.efc.J_colind, d.efc.J, ctx.search, ctx.done],
|
||||||
d.nefc,
|
|
||||||
d.efc.J_rownnz,
|
|
||||||
d.efc.J_rowadr,
|
|
||||||
d.efc.J_colind,
|
|
||||||
d.efc.J,
|
|
||||||
ctx.search,
|
|
||||||
ctx.done,
|
|
||||||
],
|
|
||||||
outputs=[ctx.jv],
|
outputs=[ctx.jv],
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1744,7 +1720,7 @@ def solve_init_efc(
|
|||||||
|
|
||||||
|
|
||||||
@cache_kernel
|
@cache_kernel
|
||||||
def solve_init_jaref(opt_is_sparse: bool, nv: int, dofs_per_thread: int):
|
def solve_init_jaref(is_sparse: bool, nv: int, dofs_per_thread: int):
|
||||||
@wp.kernel(module="unique", enable_backward=False)
|
@wp.kernel(module="unique", enable_backward=False)
|
||||||
def kernel(
|
def kernel(
|
||||||
# Data in:
|
# Data in:
|
||||||
@@ -1764,7 +1740,7 @@ def solve_init_jaref(opt_is_sparse: bool, nv: int, dofs_per_thread: int):
|
|||||||
return
|
return
|
||||||
|
|
||||||
jaref = float(0.0)
|
jaref = float(0.0)
|
||||||
if wp.static(SPARSE_CONSTRAINT_JACOBIAN):
|
if wp.static(is_sparse):
|
||||||
rownnz = efc_J_rownnz_in[worldid, efcid]
|
rownnz = efc_J_rownnz_in[worldid, efcid]
|
||||||
rowadr = efc_J_rowadr_in[worldid, efcid]
|
rowadr = efc_J_rowadr_in[worldid, efcid]
|
||||||
for i in range(rownnz):
|
for i in range(rownnz):
|
||||||
@@ -1785,9 +1761,7 @@ def solve_init_jaref(opt_is_sparse: bool, nv: int, dofs_per_thread: int):
|
|||||||
jaref += efc_J_in[worldid, efcid, ii] * qacc_in[worldid, ii]
|
jaref += efc_J_in[worldid, efcid, ii] * qacc_in[worldid, ii]
|
||||||
|
|
||||||
if dofstart == 0:
|
if dofstart == 0:
|
||||||
wp.atomic_add(
|
wp.atomic_add(ctx_Jaref_out, worldid, efcid, jaref - efc_aref_in[worldid, efcid])
|
||||||
ctx_Jaref_out, worldid, efcid, jaref - efc_aref_in[worldid, efcid]
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
wp.atomic_add(ctx_Jaref_out, worldid, efcid, jaref)
|
wp.atomic_add(ctx_Jaref_out, worldid, efcid, jaref)
|
||||||
|
|
||||||
@@ -1869,9 +1843,7 @@ def update_constraint_efc(track_changes: bool):
|
|||||||
|
|
||||||
# Read old QUADRATIC status before overwriting
|
# Read old QUADRATIC status before overwriting
|
||||||
if wp.static(TRACK_CHANGES):
|
if wp.static(TRACK_CHANGES):
|
||||||
old_quad = (
|
old_quad = efc_state_out[worldid, efcid] == types.ConstraintState.QUADRATIC.value
|
||||||
efc_state_out[worldid, efcid] == types.ConstraintState.QUADRATIC.value
|
|
||||||
)
|
|
||||||
|
|
||||||
efc_D = efc_D_in[worldid, efcid]
|
efc_D = efc_D_in[worldid, efcid]
|
||||||
Jaref = ctx_Jaref_in[worldid, efcid]
|
Jaref = ctx_Jaref_in[worldid, efcid]
|
||||||
@@ -1919,10 +1891,7 @@ def update_constraint_efc(track_changes: bool):
|
|||||||
|
|
||||||
dim = contact_dim_in[conid]
|
dim = contact_dim_in[conid]
|
||||||
friction = contact_friction_in[conid]
|
friction = contact_friction_in[conid]
|
||||||
mu = (
|
mu = friction[0] * opt_impratio_invsqrt[worldid % opt_impratio_invsqrt.shape[0]]
|
||||||
friction[0]
|
|
||||||
* opt_impratio_invsqrt[worldid % opt_impratio_invsqrt.shape[0]]
|
|
||||||
)
|
|
||||||
|
|
||||||
efcid0 = contact_efc_address_in[conid, 0]
|
efcid0 = contact_efc_address_in[conid, 0]
|
||||||
if efcid0 < 0:
|
if efcid0 < 0:
|
||||||
@@ -2076,8 +2045,8 @@ def update_constraint_gauss_cost(nv: int, dofs_per_thread: int):
|
|||||||
gauss_cost += (efc_Ma_in[worldid, ii] - qfrc_smooth_in[worldid, ii]) * (
|
gauss_cost += (efc_Ma_in[worldid, ii] - qfrc_smooth_in[worldid, ii]) * (
|
||||||
qacc_in[worldid, ii] - qacc_smooth_in[worldid, ii]
|
qacc_in[worldid, ii] - qacc_smooth_in[worldid, ii]
|
||||||
)
|
)
|
||||||
wp.atomic_add(ctx_gauss_out, worldid, gauss_cost)
|
wp.atomic_add(ctx_gauss_out, worldid, 0.5 * gauss_cost)
|
||||||
wp.atomic_add(ctx_cost_out, worldid, gauss_cost)
|
wp.atomic_add(ctx_cost_out, worldid, 0.5 * gauss_cost)
|
||||||
|
|
||||||
return kernel
|
return kernel
|
||||||
|
|
||||||
@@ -2182,12 +2151,7 @@ def update_gradient_h_incremental_sparse(
|
|||||||
wp.atomic_add(ctx_h_out[worldid, colindj], colindi, h)
|
wp.atomic_add(ctx_h_out[worldid, colindj], colindi, h)
|
||||||
|
|
||||||
|
|
||||||
def _update_constraint(
|
def _update_constraint(m: types.Model, d: types.Data, ctx: SolverContext | InverseContext, track_changes: bool = False):
|
||||||
m: types.Model,
|
|
||||||
d: types.Data,
|
|
||||||
ctx: SolverContext | InverseContext,
|
|
||||||
track_changes: bool = False,
|
|
||||||
):
|
|
||||||
"""Update constraint arrays after each solve iteration."""
|
"""Update constraint arrays after each solve iteration."""
|
||||||
wp.launch(
|
wp.launch(
|
||||||
update_constraint_init_cost,
|
update_constraint_init_cost,
|
||||||
@@ -2217,30 +2181,16 @@ def _update_constraint(
|
|||||||
update_constraint_efc(track_changes),
|
update_constraint_efc(track_changes),
|
||||||
dim=(d.nworld, d.njmax),
|
dim=(d.nworld, d.njmax),
|
||||||
inputs=efc_inputs,
|
inputs=efc_inputs,
|
||||||
outputs=[
|
outputs=[d.efc.force, d.efc.state, ctx.cost, ctx.changed_efc_ids, ctx.changed_efc_count],
|
||||||
d.efc.force,
|
|
||||||
d.efc.state,
|
|
||||||
ctx.cost,
|
|
||||||
ctx.changed_efc_ids,
|
|
||||||
ctx.changed_efc_count,
|
|
||||||
],
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# qfrc_constraint = efc_J.T @ efc_force
|
# qfrc_constraint = efc_J.T @ efc_force
|
||||||
if SPARSE_CONSTRAINT_JACOBIAN:
|
if m.is_sparse:
|
||||||
d.qfrc_constraint.zero_()
|
d.qfrc_constraint.zero_()
|
||||||
wp.launch(
|
wp.launch(
|
||||||
update_constraint_init_qfrc_constraint_sparse,
|
update_constraint_init_qfrc_constraint_sparse,
|
||||||
dim=(d.nworld, d.njmax),
|
dim=(d.nworld, d.njmax),
|
||||||
inputs=[
|
inputs=[d.nefc, d.efc.J_rownnz, d.efc.J_rowadr, d.efc.J_colind, d.efc.J, d.efc.force, ctx.done],
|
||||||
d.nefc,
|
|
||||||
d.efc.J_rownnz,
|
|
||||||
d.efc.J_rowadr,
|
|
||||||
d.efc.J_colind,
|
|
||||||
d.efc.J,
|
|
||||||
d.efc.force,
|
|
||||||
ctx.done,
|
|
||||||
],
|
|
||||||
outputs=[d.qfrc_constraint],
|
outputs=[d.qfrc_constraint],
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
@@ -2441,9 +2391,7 @@ def update_gradient_JTDAJ_dense_tiled(nv_pad: int, tile_size: int, njmax: int):
|
|||||||
|
|
||||||
nefc = nefc_in[worldid]
|
nefc = nefc_in[worldid]
|
||||||
|
|
||||||
sum_val = wp.tile_load(
|
sum_val = wp.tile_load(qM_in[worldid], shape=(nv_pad, nv_pad), bounds_check=True)
|
||||||
qM_in[worldid], shape=(nv_pad, nv_pad), bounds_check=True
|
|
||||||
)
|
|
||||||
|
|
||||||
# Each tile processes one output tile by looping over all constraints
|
# Each tile processes one output tile by looping over all constraints
|
||||||
for k in range(0, njmax, TILE_SIZE_K):
|
for k in range(0, njmax, TILE_SIZE_K):
|
||||||
@@ -2453,12 +2401,7 @@ def update_gradient_JTDAJ_dense_tiled(nv_pad: int, tile_size: int, njmax: int):
|
|||||||
# AD: leaving bounds-check disabled here because I'm not entirely sure that
|
# AD: leaving bounds-check disabled here because I'm not entirely sure that
|
||||||
# everything always hits the fast path. The padding takes care of any
|
# everything always hits the fast path. The padding takes care of any
|
||||||
# potential OOB accesses.
|
# potential OOB accesses.
|
||||||
J_kj = wp.tile_load(
|
J_kj = wp.tile_load(efc_J_in[worldid], shape=(TILE_SIZE_K, nv_pad), offset=(k, 0), bounds_check=False)
|
||||||
efc_J_in[worldid],
|
|
||||||
shape=(TILE_SIZE_K, nv_pad),
|
|
||||||
offset=(k, 0),
|
|
||||||
bounds_check=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
# state check
|
# state check
|
||||||
D_k = wp.tile_load(efc_D_in[worldid], shape=TILE_SIZE_K, offset=k, bounds_check=False)
|
D_k = wp.tile_load(efc_D_in[worldid], shape=TILE_SIZE_K, offset=k, bounds_check=False)
|
||||||
@@ -2473,11 +2416,7 @@ def update_gradient_JTDAJ_dense_tiled(nv_pad: int, tile_size: int, njmax: int):
|
|||||||
active_tile = wp.tile_map(active_check, tid_tile, threshold_tile)
|
active_tile = wp.tile_map(active_check, tid_tile, threshold_tile)
|
||||||
D_k = wp.tile_map(wp.mul, active_tile, D_k)
|
D_k = wp.tile_map(wp.mul, active_tile, D_k)
|
||||||
|
|
||||||
J_ki = wp.tile_map(
|
J_ki = wp.tile_map(wp.mul, wp.tile_transpose(J_kj), wp.tile_broadcast(D_k, shape=(nv_pad, TILE_SIZE_K)))
|
||||||
wp.mul,
|
|
||||||
wp.tile_transpose(J_kj),
|
|
||||||
wp.tile_broadcast(D_k, shape=(nv_pad, TILE_SIZE_K)),
|
|
||||||
)
|
|
||||||
|
|
||||||
sum_val += wp.tile_matmul(J_ki, J_kj)
|
sum_val += wp.tile_matmul(J_ki, J_kj)
|
||||||
|
|
||||||
@@ -2514,7 +2453,7 @@ def update_gradient_JTCJ_sparse(
|
|||||||
nblocks_perblock: int,
|
nblocks_perblock: int,
|
||||||
dim_block: int,
|
dim_block: int,
|
||||||
# Out:
|
# Out:
|
||||||
h_out: wp.array3d(dtype=float),
|
ctx_h_out: wp.array3d(dtype=float),
|
||||||
):
|
):
|
||||||
conid_start, elementid = wp.tid()
|
conid_start, elementid = wp.tid()
|
||||||
|
|
||||||
@@ -2529,20 +2468,37 @@ def update_gradient_JTCJ_sparse(
|
|||||||
|
|
||||||
worldid = contact_worldid_in[conid]
|
worldid = contact_worldid_in[conid]
|
||||||
if ctx_done_in[worldid]:
|
if ctx_done_in[worldid]:
|
||||||
return
|
continue
|
||||||
|
|
||||||
condim = contact_dim_in[conid]
|
condim = contact_dim_in[conid]
|
||||||
|
|
||||||
if condim == 1:
|
if condim == 1:
|
||||||
return
|
continue
|
||||||
|
|
||||||
# check contact status
|
# check contact status
|
||||||
if contact_dist_in[conid] - contact_includemargin_in[conid] >= 0.0:
|
if contact_dist_in[conid] - contact_includemargin_in[conid] >= 0.0:
|
||||||
return
|
continue
|
||||||
|
|
||||||
efcid0 = contact_efc_address_in[conid, 0]
|
efcid0 = contact_efc_address_in[conid, 0]
|
||||||
if efc_state_in[worldid, efcid0] != types.ConstraintState.CONE:
|
if efc_state_in[worldid, efcid0] != types.ConstraintState.CONE:
|
||||||
return
|
continue
|
||||||
|
|
||||||
|
# All dims share the same sparsity pattern. Scan colind once to find
|
||||||
|
# the sparse positions of dof1id and dof2id. Skip if either is absent.
|
||||||
|
rownnz = efc_J_rownnz_in[worldid, efcid0]
|
||||||
|
rowadr0 = efc_J_rowadr_in[worldid, efcid0]
|
||||||
|
pos1 = int(-1)
|
||||||
|
pos2 = int(-1)
|
||||||
|
for k in range(rownnz):
|
||||||
|
col = efc_J_colind_in[worldid, 0, rowadr0 + k]
|
||||||
|
if col == dof1id:
|
||||||
|
pos1 = k
|
||||||
|
if col == dof2id:
|
||||||
|
pos2 = k
|
||||||
|
if pos1 >= 0 and pos2 >= 0:
|
||||||
|
break
|
||||||
|
if pos1 < 0 or pos2 < 0:
|
||||||
|
continue
|
||||||
|
|
||||||
fri = contact_friction_in[conid]
|
fri = contact_friction_in[conid]
|
||||||
mu = fri[0] * opt_impratio_invsqrt[worldid % opt_impratio_invsqrt.shape[0]]
|
mu = fri[0] * opt_impratio_invsqrt[worldid % opt_impratio_invsqrt.shape[0]]
|
||||||
@@ -2551,7 +2507,7 @@ def update_gradient_JTCJ_sparse(
|
|||||||
dm = math.safe_div(efc_D_in[worldid, efcid0], mu2 * (1.0 + mu2))
|
dm = math.safe_div(efc_D_in[worldid, efcid0], mu2 * (1.0 + mu2))
|
||||||
|
|
||||||
if dm == 0.0:
|
if dm == 0.0:
|
||||||
return
|
continue
|
||||||
|
|
||||||
n = ctx_Jaref_in[worldid, efcid0] * mu
|
n = ctx_Jaref_in[worldid, efcid0] * mu
|
||||||
u = types.vec6(n, 0.0, 0.0, 0.0, 0.0, 0.0)
|
u = types.vec6(n, 0.0, 0.0, 0.0, 0.0, 0.0)
|
||||||
@@ -2570,52 +2526,40 @@ def update_gradient_JTCJ_sparse(
|
|||||||
t = wp.max(t, types.MJ_MINVAL)
|
t = wp.max(t, types.MJ_MINVAL)
|
||||||
ttt = wp.max(t * t * t, types.MJ_MINVAL)
|
ttt = wp.max(t * t * t, types.MJ_MINVAL)
|
||||||
|
|
||||||
|
# Precompute common subexpressions.
|
||||||
|
mu_over_t = math.safe_div(mu, t)
|
||||||
|
mu_n_over_ttt = mu * math.safe_div(n, ttt)
|
||||||
|
mu2_minus_mu_n_over_t = mu2 - mu * math.safe_div(n, t)
|
||||||
|
|
||||||
h = float(0.0)
|
h = float(0.0)
|
||||||
|
|
||||||
for dim1id in range(condim):
|
for dim1id in range(condim):
|
||||||
if dim1id == 0:
|
if dim1id == 0:
|
||||||
efcid1 = efcid0
|
rowadr1 = rowadr0
|
||||||
|
dm_fri1 = dm * mu
|
||||||
else:
|
else:
|
||||||
efcid1 = contact_efc_address_in[conid, dim1id]
|
efcid1 = contact_efc_address_in[conid, dim1id]
|
||||||
|
|
||||||
# TODO(team): improve performance for sparse code path
|
|
||||||
rownnz1 = efc_J_rownnz_in[worldid, efcid1]
|
|
||||||
rowadr1 = efc_J_rowadr_in[worldid, efcid1]
|
rowadr1 = efc_J_rowadr_in[worldid, efcid1]
|
||||||
|
dm_fri1 = dm * fri[dim1id - 1]
|
||||||
|
|
||||||
efc_J11 = float(0.0)
|
# Direct J reads using cached sparse positions.
|
||||||
efc_J12 = float(0.0)
|
efc_J11 = efc_J_in[worldid, 0, rowadr1 + pos1]
|
||||||
for i1 in range(rownnz1):
|
efc_J12 = efc_J_in[worldid, 0, rowadr1 + pos2]
|
||||||
sparseid1 = rowadr1 + i1
|
|
||||||
colind1 = efc_J_colind_in[worldid, 0, sparseid1]
|
|
||||||
if dof1id == colind1:
|
|
||||||
efc_J11 = efc_J_in[worldid, 0, sparseid1]
|
|
||||||
if dof2id == colind1:
|
|
||||||
efc_J12 = efc_J_in[worldid, 0, sparseid1]
|
|
||||||
if efc_J11 != 0.0 and efc_J12 != 0.0:
|
|
||||||
break
|
|
||||||
|
|
||||||
ui = u[dim1id]
|
ui = u[dim1id]
|
||||||
|
|
||||||
for dim2id in range(0, dim1id + 1):
|
for dim2id in range(0, dim1id + 1):
|
||||||
if dim2id == 0:
|
if dim2id == 0:
|
||||||
efcid2 = efcid0
|
rowadr2 = rowadr0
|
||||||
|
dm_fri12 = dm_fri1 * mu
|
||||||
else:
|
else:
|
||||||
efcid2 = contact_efc_address_in[conid, dim2id]
|
efcid2 = contact_efc_address_in[conid, dim2id]
|
||||||
|
|
||||||
rownnz2 = efc_J_rownnz_in[worldid, efcid2]
|
|
||||||
rowadr2 = efc_J_rowadr_in[worldid, efcid2]
|
rowadr2 = efc_J_rowadr_in[worldid, efcid2]
|
||||||
|
dm_fri12 = dm_fri1 * fri[dim2id - 1]
|
||||||
|
|
||||||
efc_J21 = float(0.0)
|
# Direct J reads using cached sparse positions.
|
||||||
efc_J22 = float(0.0)
|
efc_J21 = efc_J_in[worldid, 0, rowadr2 + pos1]
|
||||||
for i2 in range(rownnz2):
|
efc_J22 = efc_J_in[worldid, 0, rowadr2 + pos2]
|
||||||
sparseid2 = rowadr2 + i2
|
|
||||||
colind2 = efc_J_colind_in[worldid, 0, sparseid2]
|
|
||||||
if dof1id == colind2:
|
|
||||||
efc_J21 = efc_J_in[worldid, 0, sparseid2]
|
|
||||||
if dof2id == colind2:
|
|
||||||
efc_J22 = efc_J_in[worldid, 0, sparseid2]
|
|
||||||
if efc_J21 != 0.0 and efc_J22 != 0.0:
|
|
||||||
break
|
|
||||||
|
|
||||||
uj = u[dim2id]
|
uj = u[dim2id]
|
||||||
|
|
||||||
@@ -2623,28 +2567,17 @@ def update_gradient_JTCJ_sparse(
|
|||||||
if dim1id == 0 and dim2id == 0:
|
if dim1id == 0 and dim2id == 0:
|
||||||
hcone = 1.0
|
hcone = 1.0
|
||||||
elif dim1id == 0:
|
elif dim1id == 0:
|
||||||
hcone = -math.safe_div(mu, t) * uj
|
hcone = -mu_over_t * uj
|
||||||
elif dim2id == 0:
|
elif dim2id == 0:
|
||||||
hcone = -math.safe_div(mu, t) * ui
|
hcone = -mu_over_t * ui
|
||||||
else:
|
else:
|
||||||
hcone = mu * math.safe_div(n, ttt) * ui * uj
|
hcone = mu_n_over_ttt * ui * uj
|
||||||
|
|
||||||
# add to diagonal: mu^2 - mu * n / t
|
# add to diagonal: mu^2 - mu * n / t
|
||||||
if dim1id == dim2id:
|
if dim1id == dim2id:
|
||||||
hcone += mu2 - mu * math.safe_div(n, t)
|
hcone += mu2_minus_mu_n_over_t
|
||||||
|
|
||||||
# pre and post multiply by diag(mu, friction) scale by dm
|
hcone *= dm_fri12
|
||||||
if dim1id == 0:
|
|
||||||
fri1 = mu
|
|
||||||
else:
|
|
||||||
fri1 = fri[dim1id - 1]
|
|
||||||
|
|
||||||
if dim2id == 0:
|
|
||||||
fri2 = mu
|
|
||||||
else:
|
|
||||||
fri2 = fri[dim2id - 1]
|
|
||||||
|
|
||||||
hcone *= dm * fri1 * fri2
|
|
||||||
|
|
||||||
if hcone != 0.0:
|
if hcone != 0.0:
|
||||||
h += hcone * efc_J11 * efc_J22
|
h += hcone * efc_J11 * efc_J22
|
||||||
@@ -2652,7 +2585,7 @@ def update_gradient_JTCJ_sparse(
|
|||||||
if dim1id != dim2id:
|
if dim1id != dim2id:
|
||||||
h += hcone * efc_J12 * efc_J21
|
h += hcone * efc_J12 * efc_J21
|
||||||
|
|
||||||
h_out[worldid, dof1id, dof2id] += h
|
ctx_h_out[worldid, dof1id, dof2id] += h
|
||||||
|
|
||||||
|
|
||||||
@wp.kernel
|
@wp.kernel
|
||||||
@@ -2863,9 +2796,7 @@ def padding_h(nv: int, ctx_done_in: wp.array(dtype=bool), ctx_h_out: wp.array3d(
|
|||||||
ctx_h_out[worldid, dofid, dofid] = 1.0
|
ctx_h_out[worldid, dofid, dofid] = 1.0
|
||||||
|
|
||||||
|
|
||||||
def _cholesky_factorize_solve(
|
def _cholesky_factorize_solve(m: types.Model, d: types.Data, ctx: SolverContext):
|
||||||
m: types.Model, d: types.Data, ctx: SolverContext
|
|
||||||
):
|
|
||||||
"""Cholesky factorize ctx.h and solve for Mgrad."""
|
"""Cholesky factorize ctx.h and solve for Mgrad."""
|
||||||
if m.nv <= _BLOCK_CHOLESKY_DIM:
|
if m.nv <= _BLOCK_CHOLESKY_DIM:
|
||||||
wp.launch_tiled(
|
wp.launch_tiled(
|
||||||
@@ -2886,36 +2817,14 @@ def _cholesky_factorize_solve(
|
|||||||
wp.launch_tiled(
|
wp.launch_tiled(
|
||||||
update_gradient_cholesky_blocked(types.TILE_SIZE_JTDAJ_DENSE, m.nv_pad),
|
update_gradient_cholesky_blocked(types.TILE_SIZE_JTDAJ_DENSE, m.nv_pad),
|
||||||
dim=d.nworld,
|
dim=d.nworld,
|
||||||
inputs=[
|
inputs=[ctx.done, ctx.grad.reshape(shape=(d.nworld, ctx.grad.shape[1], 1)), ctx.h, ctx.hfactor],
|
||||||
ctx.done,
|
|
||||||
ctx.grad.reshape(shape=(d.nworld, ctx.grad.shape[1], 1)),
|
|
||||||
ctx.h,
|
|
||||||
ctx.hfactor,
|
|
||||||
],
|
|
||||||
outputs=[ctx.Mgrad.reshape(shape=(d.nworld, ctx.Mgrad.shape[1], 1))],
|
outputs=[ctx.Mgrad.reshape(shape=(d.nworld, ctx.Mgrad.shape[1], 1))],
|
||||||
block_dim=m.block_dim.update_gradient_cholesky_blocked,
|
block_dim=m.block_dim.update_gradient_cholesky_blocked,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _update_gradient(m: types.Model, d: types.Data, ctx: SolverContext):
|
@wp.kernel
|
||||||
# grad = Ma - qfrc_smooth - qfrc_constraint
|
def _JTDAJ_sparse(
|
||||||
wp.launch(update_gradient_zero_grad_dot, dim=(d.nworld), inputs=[ctx.done], outputs=[ctx.grad_dot])
|
|
||||||
|
|
||||||
wp.launch(
|
|
||||||
update_gradient_grad,
|
|
||||||
dim=(d.nworld, m.nv),
|
|
||||||
inputs=[d.qfrc_smooth, d.qfrc_constraint, d.efc.Ma, ctx.done],
|
|
||||||
outputs=[ctx.grad, ctx.grad_dot],
|
|
||||||
)
|
|
||||||
|
|
||||||
if m.opt.solver == types.SolverType.CG:
|
|
||||||
smooth.solve_m(m, d, ctx.Mgrad, ctx.grad)
|
|
||||||
elif m.opt.solver == types.SolverType.NEWTON:
|
|
||||||
# h = qM + (efc_J.T * efc_D * active) @ efc_J
|
|
||||||
if SPARSE_CONSTRAINT_JACOBIAN:
|
|
||||||
# TODO(team): improve performance for sparse code path
|
|
||||||
@wp.kernel(module="unique", enable_backward=False)
|
|
||||||
def _JTDAJ_sparse(
|
|
||||||
# Data in:
|
# Data in:
|
||||||
nefc_in: wp.array(dtype=int),
|
nefc_in: wp.array(dtype=int),
|
||||||
efc_J_rownnz_in: wp.array2d(dtype=int),
|
efc_J_rownnz_in: wp.array2d(dtype=int),
|
||||||
@@ -2928,7 +2837,7 @@ def _update_gradient(m: types.Model, d: types.Data, ctx: SolverContext):
|
|||||||
ctx_done_in: wp.array(dtype=bool),
|
ctx_done_in: wp.array(dtype=bool),
|
||||||
# Out:
|
# Out:
|
||||||
h_out: wp.array3d(dtype=float),
|
h_out: wp.array3d(dtype=float),
|
||||||
):
|
):
|
||||||
worldid, efcid = wp.tid()
|
worldid, efcid = wp.tid()
|
||||||
|
|
||||||
if ctx_done_in[worldid]:
|
if ctx_done_in[worldid]:
|
||||||
@@ -2966,72 +2875,31 @@ def _update_gradient(m: types.Model, d: types.Data, ctx: SolverContext):
|
|||||||
if i != j:
|
if i != j:
|
||||||
wp.atomic_add(h_out[worldid, colindj], colindi, h)
|
wp.atomic_add(h_out[worldid, colindj], colindi, h)
|
||||||
|
|
||||||
|
|
||||||
|
def _update_gradient(m: types.Model, d: types.Data, ctx: SolverContext):
|
||||||
|
# grad = Ma - qfrc_smooth - qfrc_constraint
|
||||||
|
wp.launch(update_gradient_zero_grad_dot, dim=(d.nworld), inputs=[ctx.done], outputs=[ctx.grad_dot])
|
||||||
|
|
||||||
|
wp.launch(
|
||||||
|
update_gradient_grad,
|
||||||
|
dim=(d.nworld, m.nv),
|
||||||
|
inputs=[d.qfrc_smooth, d.qfrc_constraint, d.efc.Ma, ctx.done],
|
||||||
|
outputs=[ctx.grad, ctx.grad_dot],
|
||||||
|
)
|
||||||
|
|
||||||
|
if m.opt.solver == types.SolverType.CG:
|
||||||
|
smooth.solve_m(m, d, ctx.Mgrad, ctx.grad)
|
||||||
|
elif m.opt.solver == types.SolverType.NEWTON:
|
||||||
|
# h = qM + (efc_J.T * efc_D * active) @ efc_J
|
||||||
|
if m.is_sparse:
|
||||||
|
ctx.h.zero_()
|
||||||
wp.launch(
|
wp.launch(
|
||||||
_JTDAJ_sparse,
|
_JTDAJ_sparse,
|
||||||
dim=(d.nworld, d.njmax),
|
dim=(d.nworld, d.njmax),
|
||||||
inputs=[
|
inputs=[d.nefc, d.efc.J_rownnz, d.efc.J_rowadr, d.efc.J_colind, d.efc.J, d.efc.D, d.efc.state, ctx.done],
|
||||||
d.nefc,
|
|
||||||
d.efc.J_rownnz,
|
|
||||||
d.efc.J_rowadr,
|
|
||||||
d.efc.J_colind,
|
|
||||||
d.efc.J,
|
|
||||||
d.efc.D,
|
|
||||||
d.efc.state,
|
|
||||||
ctx.done,
|
|
||||||
],
|
|
||||||
outputs=[ctx.h],
|
outputs=[ctx.h],
|
||||||
)
|
)
|
||||||
|
|
||||||
if m.is_sparse:
|
|
||||||
wp.launch(
|
|
||||||
update_gradient_set_h_qM_lower_sparse,
|
|
||||||
dim=(d.nworld, m.qM_fullm_i.size),
|
|
||||||
inputs=[m.qM_fullm_i, m.qM_fullm_j, d.qM, ctx.done],
|
|
||||||
outputs=[ctx.h],
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
# dense M: copy qM directly into h
|
|
||||||
@wp.kernel(module="unique", enable_backward=False)
|
|
||||||
def _set_h_qM_dense(
|
|
||||||
nv: int,
|
|
||||||
qM_in: wp.array3d(dtype=float),
|
|
||||||
ctx_done_in: wp.array(dtype=bool),
|
|
||||||
ctx_h_out: wp.array3d(dtype=float),
|
|
||||||
):
|
|
||||||
worldid, i, j = wp.tid()
|
|
||||||
if ctx_done_in[worldid]:
|
|
||||||
return
|
|
||||||
if i >= nv or j >= nv:
|
|
||||||
return
|
|
||||||
if i >= j:
|
|
||||||
ctx_h_out[worldid, i, j] += qM_in[worldid, i, j]
|
|
||||||
|
|
||||||
wp.launch(
|
|
||||||
_set_h_qM_dense,
|
|
||||||
dim=(d.nworld, m.nv, m.nv),
|
|
||||||
inputs=[m.nv, d.qM, ctx.done],
|
|
||||||
outputs=[ctx.h],
|
|
||||||
)
|
|
||||||
elif m.is_sparse:
|
|
||||||
num_blocks_ceil = ceil(m.nv / types.TILE_SIZE_JTDAJ_SPARSE)
|
|
||||||
lower_triangle_dim = int(num_blocks_ceil * (num_blocks_ceil + 1) / 2)
|
|
||||||
with scoped_mathdx_gemm_disabled():
|
|
||||||
wp.launch_tiled(
|
|
||||||
update_gradient_JTDAJ_sparse_tiled(
|
|
||||||
types.TILE_SIZE_JTDAJ_SPARSE, d.njmax
|
|
||||||
),
|
|
||||||
dim=(d.nworld, lower_triangle_dim),
|
|
||||||
inputs=[
|
|
||||||
d.nefc,
|
|
||||||
d.efc.J,
|
|
||||||
d.efc.D,
|
|
||||||
d.efc.state,
|
|
||||||
ctx.done,
|
|
||||||
],
|
|
||||||
outputs=[ctx.h],
|
|
||||||
block_dim=m.block_dim.update_gradient_JTDAJ_sparse,
|
|
||||||
)
|
|
||||||
|
|
||||||
wp.launch(
|
wp.launch(
|
||||||
update_gradient_set_h_qM_lower_sparse,
|
update_gradient_set_h_qM_lower_sparse,
|
||||||
dim=(d.nworld, m.qM_fullm_i.size),
|
dim=(d.nworld, m.qM_fullm_i.size),
|
||||||
@@ -3041,9 +2909,7 @@ def _update_gradient(m: types.Model, d: types.Data, ctx: SolverContext):
|
|||||||
else:
|
else:
|
||||||
with scoped_mathdx_gemm_disabled():
|
with scoped_mathdx_gemm_disabled():
|
||||||
wp.launch_tiled(
|
wp.launch_tiled(
|
||||||
update_gradient_JTDAJ_dense_tiled(
|
update_gradient_JTDAJ_dense_tiled(m.nv_pad, types.TILE_SIZE_JTDAJ_DENSE, d.njmax),
|
||||||
m.nv_pad, types.TILE_SIZE_JTDAJ_DENSE, d.njmax
|
|
||||||
),
|
|
||||||
dim=d.nworld,
|
dim=d.nworld,
|
||||||
inputs=[
|
inputs=[
|
||||||
d.nefc,
|
d.nefc,
|
||||||
@@ -3081,10 +2947,10 @@ def _update_gradient(m: types.Model, d: types.Data, ctx: SolverContext):
|
|||||||
|
|
||||||
nblocks_perblock = int((d.naconmax + dim_block - 1) / dim_block)
|
nblocks_perblock = int((d.naconmax + dim_block - 1) / dim_block)
|
||||||
|
|
||||||
if SPARSE_CONSTRAINT_JACOBIAN:
|
if m.is_sparse:
|
||||||
wp.launch(
|
wp.launch(
|
||||||
update_gradient_JTCJ_sparse,
|
update_gradient_JTCJ_sparse,
|
||||||
dim=(d.naconmax, m.dof_tri_row.size),
|
dim=(dim_block, m.dof_tri_row.size),
|
||||||
inputs=[
|
inputs=[
|
||||||
m.opt.impratio_invsqrt,
|
m.opt.impratio_invsqrt,
|
||||||
m.dof_tri_row,
|
m.dof_tri_row,
|
||||||
@@ -3142,20 +3008,13 @@ def _update_gradient(m: types.Model, d: types.Data, ctx: SolverContext):
|
|||||||
raise ValueError(f"Unknown solver type: {m.opt.solver}")
|
raise ValueError(f"Unknown solver type: {m.opt.solver}")
|
||||||
|
|
||||||
|
|
||||||
def _update_gradient_incremental(
|
def _update_gradient_incremental(m: types.Model, d: types.Data, ctx: SolverContext):
|
||||||
m: types.Model, d: types.Data, ctx: SolverContext
|
|
||||||
):
|
|
||||||
"""Incremental gradient update: update H for changed constraints + re-factorize.
|
"""Incremental gradient update: update H for changed constraints + re-factorize.
|
||||||
|
|
||||||
Skips the full J^T*D*J rebuild by applying only the delta from constraints
|
Skips the full J^T*D*J rebuild by applying only the delta from constraints
|
||||||
that changed QUADRATIC state, then re-factorizes and solves.
|
that changed QUADRATIC state, then re-factorizes and solves.
|
||||||
"""
|
"""
|
||||||
wp.launch(
|
wp.launch(update_gradient_zero_grad_dot, dim=(d.nworld), inputs=[ctx.done], outputs=[ctx.grad_dot])
|
||||||
update_gradient_zero_grad_dot,
|
|
||||||
dim=(d.nworld),
|
|
||||||
inputs=[ctx.done],
|
|
||||||
outputs=[ctx.grad_dot],
|
|
||||||
)
|
|
||||||
|
|
||||||
wp.launch(
|
wp.launch(
|
||||||
update_gradient_grad,
|
update_gradient_grad,
|
||||||
@@ -3165,7 +3024,7 @@ def _update_gradient_incremental(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Update lower triangle of H with delta from changed constraints
|
# Update lower triangle of H with delta from changed constraints
|
||||||
if SPARSE_CONSTRAINT_JACOBIAN:
|
if m.is_sparse:
|
||||||
wp.launch(
|
wp.launch(
|
||||||
update_gradient_h_incremental_sparse,
|
update_gradient_h_incremental_sparse,
|
||||||
dim=(d.nworld, ctx.changed_efc_ids.shape[1]),
|
dim=(d.nworld, ctx.changed_efc_ids.shape[1]),
|
||||||
@@ -3347,10 +3206,7 @@ def _solver_iteration(
|
|||||||
# path in update_constraint_efc has early returns that skip state change
|
# path in update_constraint_efc has early returns that skip state change
|
||||||
# tracking, and the additional JTCJ Hessian term depends on Jaref which
|
# tracking, and the additional JTCJ Hessian term depends on Jaref which
|
||||||
# changes every iteration.
|
# changes every iteration.
|
||||||
incremental = (
|
incremental = m.opt.solver == types.SolverType.NEWTON and m.opt.cone != types.ConeType.ELLIPTIC
|
||||||
m.opt.solver == types.SolverType.NEWTON
|
|
||||||
and m.opt.cone != types.ConeType.ELLIPTIC
|
|
||||||
)
|
|
||||||
|
|
||||||
if incremental:
|
if incremental:
|
||||||
# Must complete before update_constraint_efc which atomically increments.
|
# Must complete before update_constraint_efc which atomically increments.
|
||||||
@@ -3424,15 +3280,7 @@ def init_context(m: types.Model, d: types.Data, ctx: SolverContext | InverseCont
|
|||||||
wp.launch(
|
wp.launch(
|
||||||
solve_init_jaref(m.is_sparse, m.nv, dofs_per_thread),
|
solve_init_jaref(m.is_sparse, m.nv, dofs_per_thread),
|
||||||
dim=(d.nworld, d.njmax, threads_per_efc),
|
dim=(d.nworld, d.njmax, threads_per_efc),
|
||||||
inputs=[
|
inputs=[d.nefc, d.qacc, d.efc.J_rownnz, d.efc.J_rowadr, d.efc.J_colind, d.efc.J, d.efc.aref],
|
||||||
d.nefc,
|
|
||||||
d.qacc,
|
|
||||||
d.efc.J_rownnz,
|
|
||||||
d.efc.J_rowadr,
|
|
||||||
d.efc.J_colind,
|
|
||||||
d.efc.J,
|
|
||||||
d.efc.aref,
|
|
||||||
],
|
|
||||||
outputs=[ctx.Jaref],
|
outputs=[ctx.Jaref],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -18,18 +18,52 @@ from typing import Optional, Tuple
|
|||||||
import warp as wp
|
import warp as wp
|
||||||
|
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.math import motion_cross
|
from mujoco.mjx.third_party.mujoco_warp._src.math import motion_cross
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import MJ_MINVAL
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import ConeType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import ConeType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import Data
|
from mujoco.mjx.third_party.mujoco_warp._src.types import Data
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import DynType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import JointType
|
from mujoco.mjx.third_party.mujoco_warp._src.types import JointType
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import Model
|
from mujoco.mjx.third_party.mujoco_warp._src.types import Model
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import State
|
from mujoco.mjx.third_party.mujoco_warp._src.types import State
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.types import vec5
|
from mujoco.mjx.third_party.mujoco_warp._src.types import vec5
|
||||||
|
from mujoco.mjx.third_party.mujoco_warp._src.types import vec10f
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import cache_kernel
|
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import cache_kernel
|
||||||
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import event_scope
|
from mujoco.mjx.third_party.mujoco_warp._src.warp_util import event_scope
|
||||||
|
|
||||||
wp.set_module_options({"enable_backward": False})
|
wp.set_module_options({"enable_backward": False})
|
||||||
|
|
||||||
|
|
||||||
|
# TODO(team): kernel analyzer array slice?
|
||||||
|
@wp.func
|
||||||
|
def next_act(
|
||||||
|
# Model:
|
||||||
|
opt_timestep: float, # kernel_analyzer: ignore
|
||||||
|
actuator_dyntype: int, # kernel_analyzer: ignore
|
||||||
|
actuator_dynprm: vec10f, # kernel_analyzer: ignore
|
||||||
|
actuator_actrange: wp.vec2, # kernel_analyzer: ignore
|
||||||
|
# Data In:
|
||||||
|
act_in: float, # kernel_analyzer: ignore
|
||||||
|
act_dot_in: float, # kernel_analyzer: ignore
|
||||||
|
# In:
|
||||||
|
act_dot_scale: float,
|
||||||
|
clamp: bool,
|
||||||
|
) -> float:
|
||||||
|
# advance actuation
|
||||||
|
if actuator_dyntype == DynType.FILTEREXACT:
|
||||||
|
tau = wp.max(MJ_MINVAL, actuator_dynprm[0])
|
||||||
|
act = act_in + act_dot_scale * act_dot_in * tau * (1.0 - wp.exp(-opt_timestep / tau))
|
||||||
|
elif actuator_dyntype == DynType.USER:
|
||||||
|
return act_in
|
||||||
|
else:
|
||||||
|
act = act_in + act_dot_scale * act_dot_in * opt_timestep
|
||||||
|
|
||||||
|
# clamp to actrange
|
||||||
|
if clamp:
|
||||||
|
act = wp.clamp(act, actuator_actrange[0], actuator_actrange[1])
|
||||||
|
|
||||||
|
return act
|
||||||
|
|
||||||
|
|
||||||
@cache_kernel
|
@cache_kernel
|
||||||
def mul_m_sparse(check_skip: bool):
|
def mul_m_sparse(check_skip: bool):
|
||||||
@wp.kernel(module="unique")
|
@wp.kernel(module="unique")
|
||||||
|
|||||||
+136
-143
@@ -33,11 +33,8 @@ MJ_MAX_EPAFACES = 5
|
|||||||
TILE_SIZE_JTDAJ_SPARSE = 16
|
TILE_SIZE_JTDAJ_SPARSE = 16
|
||||||
TILE_SIZE_JTDAJ_DENSE = 16
|
TILE_SIZE_JTDAJ_DENSE = 16
|
||||||
|
|
||||||
# TODO(team): remove after improving performance for sparse constraint jacobian
|
# maximum number of plugin attributes
|
||||||
SPARSE_CONSTRAINT_JACOBIAN = False
|
_NPLUGINATTR = 128
|
||||||
|
|
||||||
# TODO(team): remove after mjwarp depends on warp-lang >= 1.12 in pyproject.toml
|
|
||||||
TEXTURE_DTYPE = wp.Texture2D if hasattr(wp, "Texture2D") else int
|
|
||||||
|
|
||||||
|
|
||||||
# TODO(team): add check that all wp.launch_tiled 'block_dim' settings are configurable
|
# TODO(team): add check that all wp.launch_tiled 'block_dim' settings are configurable
|
||||||
@@ -53,7 +50,6 @@ class BlockDim:
|
|||||||
# forward
|
# forward
|
||||||
euler_dense: int = 32
|
euler_dense: int = 32
|
||||||
actuator_velocity: int = 32
|
actuator_velocity: int = 32
|
||||||
tendon_velocity: int = 32
|
|
||||||
# ray
|
# ray
|
||||||
ray: int = 64
|
ray: int = 64
|
||||||
# sensor
|
# sensor
|
||||||
@@ -63,6 +59,7 @@ class BlockDim:
|
|||||||
cholesky_factorize: int = 32
|
cholesky_factorize: int = 32
|
||||||
cholesky_solve: int = 32
|
cholesky_solve: int = 32
|
||||||
cholesky_factorize_solve: int = 32
|
cholesky_factorize_solve: int = 32
|
||||||
|
solve_LD_sparse_fused: int = 64
|
||||||
# solver
|
# solver
|
||||||
update_gradient_cholesky: int = 64
|
update_gradient_cholesky: int = 64
|
||||||
update_gradient_cholesky_blocked: int = 32
|
update_gradient_cholesky_blocked: int = 32
|
||||||
@@ -351,6 +348,7 @@ class GeomType(enum.IntEnum):
|
|||||||
BOX: box
|
BOX: box
|
||||||
MESH: mesh
|
MESH: mesh
|
||||||
SDF: sdf
|
SDF: sdf
|
||||||
|
FLEX: flex
|
||||||
"""
|
"""
|
||||||
|
|
||||||
PLANE = mujoco.mjtGeom.mjGEOM_PLANE
|
PLANE = mujoco.mjtGeom.mjGEOM_PLANE
|
||||||
@@ -362,6 +360,7 @@ class GeomType(enum.IntEnum):
|
|||||||
BOX = mujoco.mjtGeom.mjGEOM_BOX
|
BOX = mujoco.mjtGeom.mjGEOM_BOX
|
||||||
MESH = mujoco.mjtGeom.mjGEOM_MESH
|
MESH = mujoco.mjtGeom.mjGEOM_MESH
|
||||||
SDF = mujoco.mjtGeom.mjGEOM_SDF
|
SDF = mujoco.mjtGeom.mjGEOM_SDF
|
||||||
|
FLEX = mujoco.mjtGeom.mjGEOM_FLEX
|
||||||
# unsupported: NGEOMTYPES, ARROW*, LINE, SKIN, LABEL, NONE
|
# unsupported: NGEOMTYPES, ARROW*, LINE, SKIN, LABEL, NONE
|
||||||
|
|
||||||
|
|
||||||
@@ -662,6 +661,10 @@ class vec11f(wp.types.vector(length=11, dtype=float)):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class vec_pluginattr(wp.types.vector(length=_NPLUGINATTR, dtype=float)):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class mat23f(wp.types.matrix(shape=(2, 3), dtype=float)):
|
class mat23f(wp.types.matrix(shape=(2, 3), dtype=float)):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -679,6 +682,7 @@ vec6 = vec6f
|
|||||||
vec8 = vec8f
|
vec8 = vec8f
|
||||||
vec10 = vec10f
|
vec10 = vec10f
|
||||||
vec11 = vec11f
|
vec11 = vec11f
|
||||||
|
vec128 = vec_pluginattr
|
||||||
mat23 = mat23f
|
mat23 = mat23f
|
||||||
mat43 = mat43f
|
mat43 = mat43f
|
||||||
mat63 = mat63f
|
mat63 = mat63f
|
||||||
@@ -841,6 +845,7 @@ class Model:
|
|||||||
nflexelem: number of elements in all flexes
|
nflexelem: number of elements in all flexes
|
||||||
nflexelemdata: number of element vertex ids in all flexes
|
nflexelemdata: number of element vertex ids in all flexes
|
||||||
nflexelemedge: number of element edge ids in all flexes
|
nflexelemedge: number of element edge ids in all flexes
|
||||||
|
nflexshelldata: number of shell fragment vertex ids in all flexes
|
||||||
nJfe: number of non-zeros in sparse flexedge Jacobian
|
nJfe: number of non-zeros in sparse flexedge Jacobian
|
||||||
nmesh: number of meshes
|
nmesh: number of meshes
|
||||||
nmeshvert: number of vertices for all meshes
|
nmeshvert: number of vertices for all meshes
|
||||||
@@ -857,6 +862,7 @@ class Model:
|
|||||||
nexclude: number of excluded geom pairs
|
nexclude: number of excluded geom pairs
|
||||||
neq: number of equality constraints
|
neq: number of equality constraints
|
||||||
ntendon: number of tendons
|
ntendon: number of tendons
|
||||||
|
nJten: number of non-zeros in sparse tendon Jacobian
|
||||||
nwrap: number of wrap objects in all tendon paths
|
nwrap: number of wrap objects in all tendon paths
|
||||||
nsensor: number of sensors
|
nsensor: number of sensors
|
||||||
nmocap: number of mocap bodies
|
nmocap: number of mocap bodies
|
||||||
@@ -973,6 +979,11 @@ class Model:
|
|||||||
light_poscom0: global position rel. to sub-com in qpos0 (*, nlight, 3)
|
light_poscom0: global position rel. to sub-com in qpos0 (*, nlight, 3)
|
||||||
light_pos0: global position rel. to body in qpos0 (*, nlight, 3)
|
light_pos0: global position rel. to body in qpos0 (*, nlight, 3)
|
||||||
light_dir0: global direction in qpos0 (*, nlight, 3)
|
light_dir0: global direction in qpos0 (*, nlight, 3)
|
||||||
|
flex_contype: flex contact type (nflex,)
|
||||||
|
flex_conaffinity: flex contact affinity (nflex,)
|
||||||
|
flex_condim: contact dimensionality (1, 3, 4, 6) (nflex,)
|
||||||
|
flex_friction: friction for (slide, spin, roll) (nflex, 3)
|
||||||
|
flex_margin: detect contact if dist<margin (nflex,)
|
||||||
flex_dim: 1: lines, 2: triangles, 3: tetrahedra (nflex,)
|
flex_dim: 1: lines, 2: triangles, 3: tetrahedra (nflex,)
|
||||||
flex_vertadr: first vertex address (nflex,)
|
flex_vertadr: first vertex address (nflex,)
|
||||||
flex_vertnum: number of vertices (nflex,)
|
flex_vertnum: number of vertices (nflex,)
|
||||||
@@ -980,17 +991,24 @@ class Model:
|
|||||||
flex_edgenum: number of edges (nflex,)
|
flex_edgenum: number of edges (nflex,)
|
||||||
flex_elemadr: first element address (nflex,)
|
flex_elemadr: first element address (nflex,)
|
||||||
flex_elemnum: number of elements (nflex,)
|
flex_elemnum: number of elements (nflex,)
|
||||||
flex_elemedgeadr: first element address (nflex,)
|
flex_elemdataadr: first element vertex id address (nflex,)
|
||||||
|
flex_elemedgeadr: first element edge id address (nflex,)
|
||||||
|
flex_shellnum: number of shells (nflex,)
|
||||||
|
flex_shelldataadr: first shell data address (nflex,)
|
||||||
flex_vertbodyid: vertex body ids (nflexvert,)
|
flex_vertbodyid: vertex body ids (nflexvert,)
|
||||||
flex_edge: edge vertex ids (2 per edge) (nflexedge, 2)
|
flex_edge: edge vertex ids (2 per edge) (nflexedge, 2)
|
||||||
flex_edgeflap: adjacent vertex ids (dim=2 only) (nflexedge, 2)
|
flex_edgeflap: adjacent vertex ids (dim=2 only) (nflexedge, 2)
|
||||||
flex_elem: element vertex ids (dim+1 per elem) (nflexelemdata,)
|
flex_elem: element vertex ids (dim+1 per elem) (nflexelemdata,)
|
||||||
flex_elemedge: element edge ids (nflexelemedge,)
|
flex_elemedge: element edge ids (nflexelemedge,)
|
||||||
|
flex_shell: shell fragment vertex ids (dim per frag) (nflexshelldata,)
|
||||||
|
flex_vert: vertex local positions (nflexvert, 3)
|
||||||
flexedge_length0: edge lengths in qpos0 (nflexedge,)
|
flexedge_length0: edge lengths in qpos0 (nflexedge,)
|
||||||
flexedge_invweight0: inv. inertia for the edge (nflexedge,)
|
flexedge_invweight0: inv. inertia for the edge (nflexedge,)
|
||||||
|
flex_radius: radius around primitive element (nflex,)
|
||||||
flex_stiffness: finite element stiffness matrix (nflexelem, 21)
|
flex_stiffness: finite element stiffness matrix (nflexelem, 21)
|
||||||
flex_bending: bending stiffness (nflexedge, 17)
|
flex_bending: bending stiffness (nflexedge, 17)
|
||||||
flex_damping: Rayleigh's damping coefficient (nflex,)
|
flex_damping: Rayleigh's damping coefficient (nflex,)
|
||||||
|
flex_centered: flex vertices are centered at body origin (nflex,)
|
||||||
flexedge_J_rownnz: number of nonzeros in Jacobian row (nflexedge,)
|
flexedge_J_rownnz: number of nonzeros in Jacobian row (nflexedge,)
|
||||||
flexedge_J_rowadr: row start address in colind array (nflexedge,)
|
flexedge_J_rowadr: row start address in colind array (nflexedge,)
|
||||||
flexedge_J_colind: column indices in sparse Jacobian (nJfe,)
|
flexedge_J_colind: column indices in sparse Jacobian (nJfe,)
|
||||||
@@ -1020,8 +1038,7 @@ class Model:
|
|||||||
hfield_ncol: number of columns in grid (nhfield,)
|
hfield_ncol: number of columns in grid (nhfield,)
|
||||||
hfield_adr: start address in hfield_data (nhfield,)
|
hfield_adr: start address in hfield_data (nhfield,)
|
||||||
hfield_data: elevation data (nhfielddata,)
|
hfield_data: elevation data (nhfielddata,)
|
||||||
mat_texid: texture id for rendering (*, nmat,
|
mat_texid: texture id for rendering (*, nmat, mjNTEXROLE)
|
||||||
mjNTEXROLE)
|
|
||||||
mat_texrepeat: texture repeat for rendering (*, nmat, 2)
|
mat_texrepeat: texture repeat for rendering (*, nmat, 2)
|
||||||
mat_rgba: rgba (*, nmat, 4)
|
mat_rgba: rgba (*, nmat, 4)
|
||||||
pair_dim: contact dimensionality (npair,)
|
pair_dim: contact dimensionality (npair,)
|
||||||
@@ -1044,16 +1061,15 @@ class Model:
|
|||||||
eq_data: numeric data for constraint (*, neq, mjNEQDATA)
|
eq_data: numeric data for constraint (*, neq, mjNEQDATA)
|
||||||
tendon_adr: address of first object in tendon's path (ntendon,)
|
tendon_adr: address of first object in tendon's path (ntendon,)
|
||||||
tendon_num: number of objects in tendon's path (ntendon,)
|
tendon_num: number of objects in tendon's path (ntendon,)
|
||||||
|
ten_J_rownnz: number of non-zeros in each tendon row (ntendon,)
|
||||||
|
ten_J_rowadr: row start address for sparse ten_J (ntendon,)
|
||||||
|
ten_J_colind: column indices in sparse ten_J (nJten,)
|
||||||
tendon_limited: does tendon have length limits (ntendon,)
|
tendon_limited: does tendon have length limits (ntendon,)
|
||||||
tendon_actfrclimited: does ten have actuator force limit (ntendon,)
|
tendon_actfrclimited: does ten have actuator force limit (ntendon,)
|
||||||
tendon_solref_lim: constraint solver reference: limit (*, ntendon,
|
tendon_solref_lim: constraint solver reference: limit (*, ntendon, mjNREF)
|
||||||
mjNREF)
|
tendon_solimp_lim: constraint solver impedance: limit (*, ntendon, mjNIMP)
|
||||||
tendon_solimp_lim: constraint solver impedance: limit (*, ntendon,
|
tendon_solref_fri: constraint solver reference: friction (*, ntendon, mjNREF)
|
||||||
mjNIMP)
|
tendon_solimp_fri: constraint solver impedance: friction (*, ntendon, mjNIMP)
|
||||||
tendon_solref_fri: constraint solver reference: friction (*, ntendon,
|
|
||||||
mjNREF)
|
|
||||||
tendon_solimp_fri: constraint solver impedance: friction (*, ntendon,
|
|
||||||
mjNIMP)
|
|
||||||
tendon_range: tendon length limits (*, ntendon, 2)
|
tendon_range: tendon length limits (*, ntendon, 2)
|
||||||
tendon_actfrcrange: range of total actuator force (*, ntendon, 2)
|
tendon_actfrcrange: range of total actuator force (*, ntendon, 2)
|
||||||
tendon_margin: min distance for limit detection (*, ntendon)
|
tendon_margin: min distance for limit detection (*, ntendon)
|
||||||
@@ -1099,11 +1115,12 @@ class Model:
|
|||||||
sensor_adr: address in sensor array (nsensor,)
|
sensor_adr: address in sensor array (nsensor,)
|
||||||
sensor_cutoff: cutoff for real and positive; 0: ignore (nsensor,)
|
sensor_cutoff: cutoff for real and positive; 0: ignore (nsensor,)
|
||||||
plugin: globally registered plugin slot number (nplugin,)
|
plugin: globally registered plugin slot number (nplugin,)
|
||||||
plugin_attr: config attributes of geom plugin (nplugin, 3)
|
plugin_attr: config attributes of geom plugin (nplugin, _NPLUGINATTR)
|
||||||
M_rownnz: number of non-zeros in each row of qM (nv,)
|
M_rownnz: number of non-zeros in each row of qM (nv,)
|
||||||
M_rowadr: index of each row in qM (nv,)
|
M_rowadr: index of each row in qM (nv,)
|
||||||
M_colind: column indices of non-zeros in qM (nM,)
|
M_colind: column indices of non-zeros in qM (nM,)
|
||||||
mapM2M: index mapping from M (legacy) to M (CSR) (nC)
|
mapM2M: index mapping from M (legacy) to M (CSR) (nC)
|
||||||
|
flex_vertflexid: flex id for each flex vertex (nflexvert,)
|
||||||
|
|
||||||
warp only fields:
|
warp only fields:
|
||||||
callback: custom physics callbacks
|
callback: custom physics callbacks
|
||||||
@@ -1120,14 +1137,12 @@ class Model:
|
|||||||
nmaxpolygon: maximum number of verts per polygon
|
nmaxpolygon: maximum number of verts per polygon
|
||||||
nmaxmeshdeg: maximum number of polygons per vert
|
nmaxmeshdeg: maximum number of polygons per vert
|
||||||
is_sparse: whether to use sparse representations
|
is_sparse: whether to use sparse representations
|
||||||
has_fluid: True if wind, density, or viscosity are non-zero at put_model
|
has_fluid: True if wind, density, or viscosity are non-zero at put_model time
|
||||||
time
|
|
||||||
has_sdf_geom: whether the model contains SDF geoms
|
has_sdf_geom: whether the model contains SDF geoms
|
||||||
block_dim: block dim options
|
block_dim: block dim options
|
||||||
body_tree: list of body ids by tree level
|
body_tree: list of body ids by tree level
|
||||||
body_branches: flattened body ids for all branches
|
body_branches: flattened body ids for all branches
|
||||||
body_branch_start: start index in body_branches for each branch (nbranch +
|
body_branch_start: start index in body_branches for each branch (nbranch + 1,)
|
||||||
1,)
|
|
||||||
mocap_bodyid: id of body for mocap (nmocap,)
|
mocap_bodyid: id of body for mocap (nmocap,)
|
||||||
body_fluid_ellipsoid: does body use ellipsoid fluid (nbody,)
|
body_fluid_ellipsoid: does body use ellipsoid fluid (nbody,)
|
||||||
jnt_limited_slide_hinge_adr: limited/slide/hinge jntadr
|
jnt_limited_slide_hinge_adr: limited/slide/hinge jntadr
|
||||||
@@ -1153,6 +1168,7 @@ class Model:
|
|||||||
tendon_site_pair_adr: site pair tendon address
|
tendon_site_pair_adr: site pair tendon address
|
||||||
tendon_geom_adr: geom tendon address
|
tendon_geom_adr: geom tendon address
|
||||||
tendon_limited_adr: addresses for limited tendons
|
tendon_limited_adr: addresses for limited tendons
|
||||||
|
max_ten_J_rownnz: maximum number of non-zeros in a tendon row
|
||||||
ten_wrapadr_site: wrap object starting address for sites
|
ten_wrapadr_site: wrap object starting address for sites
|
||||||
ten_wrapnum_site: number of site wrap objects per tendon
|
ten_wrapnum_site: number of site wrap objects per tendon
|
||||||
wrap_jnt_adr: addresses for joint tendon wrap object
|
wrap_jnt_adr: addresses for joint tendon wrap object
|
||||||
@@ -1189,6 +1205,8 @@ class Model:
|
|||||||
taxel_sensorid: address for tactile sensors
|
taxel_sensorid: address for tactile sensors
|
||||||
qM_tiles: tiling configuration
|
qM_tiles: tiling configuration
|
||||||
qLD_updates: tuple of index triples for sparse factorization
|
qLD_updates: tuple of index triples for sparse factorization
|
||||||
|
qLD_all_updates: tuple of all levels concatenated
|
||||||
|
qLD_level_offsets: tuple of start offsets for each level
|
||||||
qM_fullm_i: sparse mass matrix addressing
|
qM_fullm_i: sparse mass matrix addressing
|
||||||
qM_fullm_j: sparse mass matrix addressing
|
qM_fullm_j: sparse mass matrix addressing
|
||||||
qM_mulm_rowadr: sparse matmul row pointers
|
qM_mulm_rowadr: sparse matmul row pointers
|
||||||
@@ -1216,6 +1234,7 @@ class Model:
|
|||||||
nflexelem: int
|
nflexelem: int
|
||||||
nflexelemdata: int
|
nflexelemdata: int
|
||||||
nflexelemedge: int
|
nflexelemedge: int
|
||||||
|
nflexshelldata: int
|
||||||
nJfe: int
|
nJfe: int
|
||||||
nmesh: int
|
nmesh: int
|
||||||
nmeshvert: int
|
nmeshvert: int
|
||||||
@@ -1232,6 +1251,7 @@ class Model:
|
|||||||
nexclude: int
|
nexclude: int
|
||||||
neq: int
|
neq: int
|
||||||
ntendon: int
|
ntendon: int
|
||||||
|
nJten: int
|
||||||
nwrap: int
|
nwrap: int
|
||||||
nsensor: int
|
nsensor: int
|
||||||
nmocap: int
|
nmocap: int
|
||||||
@@ -1348,6 +1368,11 @@ class Model:
|
|||||||
light_poscom0: array("*", "nlight", wp.vec3)
|
light_poscom0: array("*", "nlight", wp.vec3)
|
||||||
light_pos0: array("*", "nlight", wp.vec3)
|
light_pos0: array("*", "nlight", wp.vec3)
|
||||||
light_dir0: array("*", "nlight", wp.vec3)
|
light_dir0: array("*", "nlight", wp.vec3)
|
||||||
|
flex_contype: array("nflex", int)
|
||||||
|
flex_conaffinity: array("nflex", int)
|
||||||
|
flex_condim: array("nflex", int)
|
||||||
|
flex_friction: array("nflex", wp.vec3)
|
||||||
|
flex_margin: array("nflex", float)
|
||||||
flex_dim: array("nflex", int)
|
flex_dim: array("nflex", int)
|
||||||
flex_vertadr: array("nflex", int)
|
flex_vertadr: array("nflex", int)
|
||||||
flex_vertnum: array("nflex", int)
|
flex_vertnum: array("nflex", int)
|
||||||
@@ -1355,17 +1380,24 @@ class Model:
|
|||||||
flex_edgenum: array("nflex", int)
|
flex_edgenum: array("nflex", int)
|
||||||
flex_elemadr: array("nflex", int)
|
flex_elemadr: array("nflex", int)
|
||||||
flex_elemnum: array("nflex", int)
|
flex_elemnum: array("nflex", int)
|
||||||
|
flex_elemdataadr: array("nflex", int)
|
||||||
flex_elemedgeadr: array("nflex", int)
|
flex_elemedgeadr: array("nflex", int)
|
||||||
|
flex_shellnum: array("nflex", int)
|
||||||
|
flex_shelldataadr: array("nflex", int)
|
||||||
flex_vertbodyid: array("nflexvert", int)
|
flex_vertbodyid: array("nflexvert", int)
|
||||||
flex_edge: array("nflexedge", wp.vec2i)
|
flex_edge: array("nflexedge", wp.vec2i)
|
||||||
flex_edgeflap: array("nflexedge", wp.vec2i)
|
flex_edgeflap: array("nflexedge", wp.vec2i)
|
||||||
flex_elem: array("nflexelemdata", int)
|
flex_elem: array("nflexelemdata", int)
|
||||||
flex_elemedge: array("nflexelemedge", int)
|
flex_elemedge: array("nflexelemedge", int)
|
||||||
|
flex_shell: array("nflexshelldata", int)
|
||||||
|
flex_vert: array("nflexvert", wp.vec3)
|
||||||
flexedge_length0: array("nflexedge", float)
|
flexedge_length0: array("nflexedge", float)
|
||||||
flexedge_invweight0: array("nflexedge", float)
|
flexedge_invweight0: array("nflexedge", float)
|
||||||
|
flex_radius: array("nflex", float)
|
||||||
flex_stiffness: array("nflexelem", 21, float)
|
flex_stiffness: array("nflexelem", 21, float)
|
||||||
flex_bending: array("nflexedge", 17, float)
|
flex_bending: array("nflexedge", 17, float)
|
||||||
flex_damping: array("nflex", float)
|
flex_damping: array("nflex", float)
|
||||||
|
flex_centered: array("nflex", bool)
|
||||||
flexedge_J_rownnz: array("nflexedge", int)
|
flexedge_J_rownnz: array("nflexedge", int)
|
||||||
flexedge_J_rowadr: array("nflexedge", int)
|
flexedge_J_rowadr: array("nflexedge", int)
|
||||||
flexedge_J_colind: array("nJfe", int)
|
flexedge_J_colind: array("nJfe", int)
|
||||||
@@ -1418,6 +1450,9 @@ class Model:
|
|||||||
eq_data: array("*", "neq", vec11)
|
eq_data: array("*", "neq", vec11)
|
||||||
tendon_adr: array("ntendon", int)
|
tendon_adr: array("ntendon", int)
|
||||||
tendon_num: array("ntendon", int)
|
tendon_num: array("ntendon", int)
|
||||||
|
ten_J_rownnz: array("ntendon", int)
|
||||||
|
ten_J_rowadr: array("ntendon", int)
|
||||||
|
ten_J_colind: array("nJten", int)
|
||||||
tendon_limited: array("ntendon", int)
|
tendon_limited: array("ntendon", int)
|
||||||
tendon_actfrclimited: array("ntendon", bool)
|
tendon_actfrclimited: array("ntendon", bool)
|
||||||
tendon_solref_lim: array("*", "ntendon", wp.vec2)
|
tendon_solref_lim: array("*", "ntendon", wp.vec2)
|
||||||
@@ -1469,11 +1504,12 @@ class Model:
|
|||||||
sensor_adr: array("nsensor", int)
|
sensor_adr: array("nsensor", int)
|
||||||
sensor_cutoff: array("nsensor", float)
|
sensor_cutoff: array("nsensor", float)
|
||||||
plugin: array("nplugin", int)
|
plugin: array("nplugin", int)
|
||||||
plugin_attr: array("nplugin", wp.vec3f)
|
plugin_attr: array("nplugin", vec_pluginattr)
|
||||||
M_rownnz: array("nv", int)
|
M_rownnz: array("nv", int)
|
||||||
M_rowadr: array("nv", int)
|
M_rowadr: array("nv", int)
|
||||||
M_colind: array("nC", int)
|
M_colind: array("nC", int)
|
||||||
mapM2M: array("nC", int)
|
mapM2M: array("nC", int)
|
||||||
|
flex_vertflexid: array("nflexvert", int)
|
||||||
# warp only fields:
|
# warp only fields:
|
||||||
callback: Callback
|
callback: Callback
|
||||||
nbranch: int
|
nbranch: int
|
||||||
@@ -1515,6 +1551,7 @@ class Model:
|
|||||||
tendon_site_pair_adr: wp.array(dtype=int)
|
tendon_site_pair_adr: wp.array(dtype=int)
|
||||||
tendon_geom_adr: wp.array(dtype=int)
|
tendon_geom_adr: wp.array(dtype=int)
|
||||||
tendon_limited_adr: wp.array(dtype=int)
|
tendon_limited_adr: wp.array(dtype=int)
|
||||||
|
max_ten_J_rownnz: int
|
||||||
ten_wrapadr_site: wp.array(dtype=int)
|
ten_wrapadr_site: wp.array(dtype=int)
|
||||||
ten_wrapnum_site: wp.array(dtype=int)
|
ten_wrapnum_site: wp.array(dtype=int)
|
||||||
wrap_jnt_adr: wp.array(dtype=int)
|
wrap_jnt_adr: wp.array(dtype=int)
|
||||||
@@ -1546,6 +1583,8 @@ class Model:
|
|||||||
taxel_sensorid: wp.array(dtype=int)
|
taxel_sensorid: wp.array(dtype=int)
|
||||||
qM_tiles: tuple[TileSet, ...]
|
qM_tiles: tuple[TileSet, ...]
|
||||||
qLD_updates: tuple[wp.array(dtype=wp.vec3i), ...]
|
qLD_updates: tuple[wp.array(dtype=wp.vec3i), ...]
|
||||||
|
qLD_all_updates: wp.array(dtype=wp.vec3i)
|
||||||
|
qLD_level_offsets: wp.array(dtype=int)
|
||||||
qM_fullm_i: wp.array(dtype=int)
|
qM_fullm_i: wp.array(dtype=int)
|
||||||
qM_fullm_j: wp.array(dtype=int)
|
qM_fullm_j: wp.array(dtype=int)
|
||||||
# Gather-based sparse mul_m indices (thread per DOF, no atomics)
|
# Gather-based sparse mul_m indices (thread per DOF, no atomics)
|
||||||
@@ -1598,6 +1637,8 @@ class Contact:
|
|||||||
solimp: array("naconmax", vec5)
|
solimp: array("naconmax", vec5)
|
||||||
dim: array("naconmax", int)
|
dim: array("naconmax", int)
|
||||||
geom: array("naconmax", wp.vec2i)
|
geom: array("naconmax", wp.vec2i)
|
||||||
|
flex: array("naconmax", wp.vec2i)
|
||||||
|
vert: array("naconmax", wp.vec2i)
|
||||||
efc_address: array("naconmax", "nmaxpyramid", int)
|
efc_address: array("naconmax", "nmaxpyramid", int)
|
||||||
worldid: array("naconmax", int)
|
worldid: array("naconmax", int)
|
||||||
type: array("naconmax", int)
|
type: array("naconmax", int)
|
||||||
@@ -1611,14 +1652,14 @@ class Constraint:
|
|||||||
Attributes:
|
Attributes:
|
||||||
type: constraint type (ConstraintType) (nworld, njmax)
|
type: constraint type (ConstraintType) (nworld, njmax)
|
||||||
id: id of object of specific type (nworld, njmax)
|
id: id of object of specific type (nworld, njmax)
|
||||||
J_rownnz: number of non-zeros in J row (nworld, 0) dense (nworld,
|
J_rownnz: number of non-zeros in J row (nworld, 0) dense
|
||||||
njmax) sparse
|
(nworld, njmax) sparse
|
||||||
J_rowadr: row start address in colind array (nworld, 0) dense (nworld,
|
J_rowadr: row start address in colind array (nworld, 0) dense
|
||||||
njmax) sparse
|
(nworld, njmax) sparse
|
||||||
J_colind: column indices in J (nworld, 0, 0) dense
|
J_colind: column indices in J (nworld, 0, 0) dense
|
||||||
(nworld, 1, njmax * nv) sparse
|
(nworld, 1, njmax * nv) sparse
|
||||||
J: constraint Jacobian (nworld, njmax_pad,
|
J: constraint Jacobian (nworld, njmax_pad, nv_pad) dense
|
||||||
nv_pad) dense (nworld, 1, njmax * nv) sparse
|
(nworld, 1, njmax * nv) sparse
|
||||||
pos: constraint position (equality, contact) (nworld, njmax)
|
pos: constraint position (equality, contact) (nworld, njmax)
|
||||||
margin: inclusion margin (contact) (nworld, njmax)
|
margin: inclusion margin (contact) (nworld, njmax)
|
||||||
D: constraint mass (nworld, njmax_pad)
|
D: constraint mass (nworld, njmax_pad)
|
||||||
@@ -1627,7 +1668,6 @@ class Constraint:
|
|||||||
frictionloss: frictionloss (friction) (nworld, njmax)
|
frictionloss: frictionloss (friction) (nworld, njmax)
|
||||||
force: constraint force in constraint space (nworld, njmax)
|
force: constraint force in constraint space (nworld, njmax)
|
||||||
state: constraint state (nworld, njmax_pad)
|
state: constraint state (nworld, njmax_pad)
|
||||||
|
|
||||||
warp only fields:
|
warp only fields:
|
||||||
Ma: M*qacc (nworld, nv)
|
Ma: M*qacc (nworld, nv)
|
||||||
"""
|
"""
|
||||||
@@ -1668,88 +1708,55 @@ class Data:
|
|||||||
qacc_warmstart: acceleration used for warmstart (nworld, nv)
|
qacc_warmstart: acceleration used for warmstart (nworld, nv)
|
||||||
ctrl: control (nworld, nu)
|
ctrl: control (nworld, nu)
|
||||||
qfrc_applied: applied generalized force (nworld, nv)
|
qfrc_applied: applied generalized force (nworld, nv)
|
||||||
xfrc_applied: applied Cartesian force/torque (nworld, nbody,
|
xfrc_applied: applied Cartesian force/torque (nworld, nbody, 6)
|
||||||
6)
|
|
||||||
eq_active: enable/disable constraints (nworld, neq)
|
eq_active: enable/disable constraints (nworld, neq)
|
||||||
mocap_pos: position of mocap bodies (nworld, nmocap,
|
mocap_pos: position of mocap bodies (nworld, nmocap, 3)
|
||||||
3)
|
mocap_quat: orientation of mocap bodies (nworld, nmocap, 4)
|
||||||
mocap_quat: orientation of mocap bodies (nworld, nmocap,
|
|
||||||
4)
|
|
||||||
qacc: acceleration (nworld, nv)
|
qacc: acceleration (nworld, nv)
|
||||||
act_dot: time-derivative of actuator activation (nworld, na)
|
act_dot: time-derivative of actuator activation (nworld, na)
|
||||||
sensordata: sensor data array (nworld,
|
sensordata: sensor data array (nworld, nsensordata,)
|
||||||
nsensordata,)
|
xpos: Cartesian position of body frame (nworld, nbody, 3)
|
||||||
xpos: Cartesian position of body frame (nworld, nbody,
|
xquat: Cartesian orientation of body frame (nworld, nbody, 4)
|
||||||
3)
|
xmat: Cartesian orientation of body frame (nworld, nbody, 3, 3)
|
||||||
xquat: Cartesian orientation of body frame (nworld, nbody,
|
xipos: Cartesian position of body com (nworld, nbody, 3)
|
||||||
4)
|
ximat: Cartesian orientation of body inertia (nworld, nbody, 3, 3)
|
||||||
xmat: Cartesian orientation of body frame (nworld, nbody,
|
xanchor: Cartesian position of joint anchor (nworld, njnt, 3)
|
||||||
3, 3)
|
xaxis: Cartesian joint axis (nworld, njnt, 3)
|
||||||
xipos: Cartesian position of body com (nworld, nbody,
|
geom_xpos: Cartesian geom position (nworld, ngeom, 3)
|
||||||
3)
|
geom_xmat: Cartesian geom orientation (nworld, ngeom, 3, 3)
|
||||||
ximat: Cartesian orientation of body inertia (nworld, nbody,
|
site_xpos: Cartesian site position (nworld, nsite, 3)
|
||||||
3, 3)
|
site_xmat: Cartesian site orientation (nworld, nsite, 3, 3)
|
||||||
xanchor: Cartesian position of joint anchor (nworld, njnt,
|
cam_xpos: Cartesian camera position (nworld, ncam, 3)
|
||||||
3)
|
cam_xmat: Cartesian camera orientation (nworld, ncam, 3, 3)
|
||||||
xaxis: Cartesian joint axis (nworld, njnt,
|
light_xpos: Cartesian light position (nworld, nlight, 3)
|
||||||
3)
|
light_xdir: Cartesian light direction (nworld, nlight, 3)
|
||||||
geom_xpos: Cartesian geom position (nworld, ngeom,
|
subtree_com: center of mass of each subtree (nworld, nbody, 3)
|
||||||
3)
|
|
||||||
geom_xmat: Cartesian geom orientation (nworld, ngeom,
|
|
||||||
3, 3)
|
|
||||||
site_xpos: Cartesian site position (nworld, nsite,
|
|
||||||
3)
|
|
||||||
site_xmat: Cartesian site orientation (nworld, nsite,
|
|
||||||
3, 3)
|
|
||||||
cam_xpos: Cartesian camera position (nworld, ncam,
|
|
||||||
3)
|
|
||||||
cam_xmat: Cartesian camera orientation (nworld, ncam,
|
|
||||||
3, 3)
|
|
||||||
light_xpos: Cartesian light position (nworld, nlight,
|
|
||||||
3)
|
|
||||||
light_xdir: Cartesian light direction (nworld, nlight,
|
|
||||||
3)
|
|
||||||
subtree_com: center of mass of each subtree (nworld, nbody,
|
|
||||||
3)
|
|
||||||
cdof: com-based motion axis of each dof (rot:lin) (nworld, nv, 6)
|
cdof: com-based motion axis of each dof (rot:lin) (nworld, nv, 6)
|
||||||
cinert: com-based body inertia and mass (nworld, nbody,
|
cinert: com-based body inertia and mass (nworld, nbody, 10)
|
||||||
10)
|
flexvert_xpos: cartesian flex vertex positions (nworld, nflexvert, 3)
|
||||||
flexvert_xpos: cartesian flex vertex positions (nworld,
|
|
||||||
nflexvert, 3)
|
|
||||||
flexedge_J: edge length Jacobian (nworld, nJfe)
|
flexedge_J: edge length Jacobian (nworld, nJfe)
|
||||||
flexedge_length: flex edge lengths (nworld,
|
flexedge_length: flex edge lengths (nworld, nflexedge, 1)
|
||||||
nflexedge, 1)
|
ten_wrapadr: start address of tendon's path (nworld, ntendon)
|
||||||
ten_wrapadr: start address of tendon's path (nworld,
|
ten_wrapnum: number of wrap points in path (nworld, ntendon)
|
||||||
ntendon)
|
ten_J: tendon Jacobian (nworld, nJten)
|
||||||
ten_wrapnum: number of wrap points in path (nworld,
|
ten_length: tendon lengths (nworld, ntendon)
|
||||||
ntendon)
|
wrap_obj: geomid; -1: site; -2: pulley (nworld, nwrap, 2)
|
||||||
ten_J: tendon Jacobian (nworld,
|
wrap_xpos: Cartesian 3D points in all paths (nworld, nwrap, 6)
|
||||||
ntendon, nv)
|
|
||||||
ten_length: tendon lengths (nworld,
|
|
||||||
ntendon)
|
|
||||||
wrap_obj: geomid; -1: site; -2: pulley (nworld, nwrap,
|
|
||||||
2)
|
|
||||||
wrap_xpos: Cartesian 3D points in all paths (nworld, nwrap,
|
|
||||||
6)
|
|
||||||
actuator_length: actuator lengths (nworld, nu)
|
actuator_length: actuator lengths (nworld, nu)
|
||||||
moment_rownnz: number of non-zeros in actuator_moment row (nworld, nu)
|
moment_rownnz: number of non-zeros in actuator_moment row (nworld, nu)
|
||||||
moment_rowadr: row start address in actuator_moment (nworld, nu)
|
moment_rowadr: row start address in actuator_moment (nworld, nu)
|
||||||
moment_colind: column indices in sparse actuator_moment (nworld, nJmom)
|
moment_colind: column indices in sparse actuator_moment (nworld, nJmom)
|
||||||
actuator_moment: actuator moments (nworld, nJmom)
|
actuator_moment: actuator moments (nworld, nJmom)
|
||||||
crb: com-based composite inertia and mass (nworld, nbody,
|
crb: com-based composite inertia and mass (nworld, nbody, 10)
|
||||||
10)
|
qM: total inertia (nworld, nv, nv) if dense
|
||||||
qM: total inertia (nworld, nv, nv)
|
(nworld, 1, nM) if sparse
|
||||||
if dense (nworld, 1, nM) if sparse
|
qLD: L'*D*L factorization of M (nworld, nv, nv) if dense
|
||||||
qLD: L'*D*L factorization of M (nworld, nv, nv)
|
(nworld, 1, nC) if sparse
|
||||||
if dense (nworld, 1, nC) if sparse
|
|
||||||
qLDiagInv: 1/diag(D) (nworld, nv)
|
qLDiagInv: 1/diag(D) (nworld, nv)
|
||||||
flexedge_velocity: flex edge velocities (nworld,
|
flexedge_velocity: flex edge velocities (nworld, nflexedge)
|
||||||
nflexedge)
|
ten_velocity: tendon velocities (nworld, ntendon)
|
||||||
ten_velocity: tendon velocities (nworld,
|
|
||||||
ntendon)
|
|
||||||
actuator_velocity: actuator velocities (nworld, nu)
|
actuator_velocity: actuator velocities (nworld, nu)
|
||||||
cvel: com-based velocity (rot:lin) (nworld, nbody,
|
cvel: com-based velocity (rot:lin) (nworld, nbody, 6)
|
||||||
6)
|
|
||||||
cdof_dot: time-derivative of cdof (rot:lin) (nworld, nv, 6)
|
cdof_dot: time-derivative of cdof (rot:lin) (nworld, nv, 6)
|
||||||
qfrc_bias: C(qpos,qvel) (nworld, nv)
|
qfrc_bias: C(qpos,qvel) (nworld, nv)
|
||||||
qfrc_spring: passive spring force (nworld, nv)
|
qfrc_spring: passive spring force (nworld, nv)
|
||||||
@@ -1757,23 +1764,19 @@ class Data:
|
|||||||
qfrc_gravcomp: passive gravity compensation force (nworld, nv)
|
qfrc_gravcomp: passive gravity compensation force (nworld, nv)
|
||||||
qfrc_fluid: passive fluid force (nworld, nv)
|
qfrc_fluid: passive fluid force (nworld, nv)
|
||||||
qfrc_passive: total passive force (nworld, nv)
|
qfrc_passive: total passive force (nworld, nv)
|
||||||
subtree_linvel: linear velocity of subtree com (nworld, nbody,
|
subtree_linvel: linear velocity of subtree com (nworld, nbody, 3)
|
||||||
3)
|
subtree_angmom: angular momentum about subtree com (nworld, nbody, 3)
|
||||||
subtree_angmom: angular momentum about subtree com (nworld, nbody,
|
|
||||||
3)
|
|
||||||
actuator_force: actuator force in actuation space (nworld, nu)
|
actuator_force: actuator force in actuation space (nworld, nu)
|
||||||
qfrc_actuator: actuator force (nworld, nv)
|
qfrc_actuator: actuator force (nworld, nv)
|
||||||
qfrc_smooth: net unconstrained force (nworld, nv)
|
qfrc_smooth: net unconstrained force (nworld, nv)
|
||||||
qacc_smooth: unconstrained acceleration (nworld, nv)
|
qacc_smooth: unconstrained acceleration (nworld, nv)
|
||||||
qfrc_constraint: constraint force (nworld, nv)
|
qfrc_constraint: constraint force (nworld, nv)
|
||||||
qfrc_inverse: net external force; should equal: (nworld, nv)
|
qfrc_inverse: net external force; should equal: (nworld, nv)
|
||||||
qfrc_applied + J.T @ xfrc_applied + qfrc_actuator
|
qfrc_applied + J.T @ xfrc_applied
|
||||||
cacc: com-based acceleration (nworld, nbody,
|
+ qfrc_actuator
|
||||||
6)
|
cacc: com-based acceleration (nworld, nbody, 6)
|
||||||
cfrc_int: com-based interaction force with parent (nworld, nbody,
|
cfrc_int: com-based interaction force with parent (nworld, nbody, 6)
|
||||||
6)
|
cfrc_ext: com-based external force on body (nworld, nbody, 6)
|
||||||
cfrc_ext: com-based external force on body (nworld, nbody,
|
|
||||||
6)
|
|
||||||
contact: contact data
|
contact: contact data
|
||||||
efc: constraint data
|
efc: constraint data
|
||||||
tree_island: island ID per tree (-1 if unconstrained) (nworld, ntree)
|
tree_island: island ID per tree (-1 if unconstrained) (nworld, ntree)
|
||||||
@@ -1784,6 +1787,7 @@ class Data:
|
|||||||
naccdmax: maximum number of contacts for CCD (all worlds)
|
naccdmax: maximum number of contacts for CCD (all worlds)
|
||||||
njmax: maximum number of constraints per world
|
njmax: maximum number of constraints per world
|
||||||
njmax_pad: njmax rounded up to the nearest multiple of TILE_SIZE_JTDAJ
|
njmax_pad: njmax rounded up to the nearest multiple of TILE_SIZE_JTDAJ
|
||||||
|
njmax_nnz: number of non-zeros in constraint Jacobian
|
||||||
nacon: number of detected contacts (across all worlds) (1,)
|
nacon: number of detected contacts (across all worlds) (1,)
|
||||||
ncollision: collision count from broadphase (1,)
|
ncollision: collision count from broadphase (1,)
|
||||||
"""
|
"""
|
||||||
@@ -1832,7 +1836,7 @@ class Data:
|
|||||||
flexedge_length: array("nworld", "nflexedge", float)
|
flexedge_length: array("nworld", "nflexedge", float)
|
||||||
ten_wrapadr: array("nworld", "ntendon", int)
|
ten_wrapadr: array("nworld", "ntendon", int)
|
||||||
ten_wrapnum: array("nworld", "ntendon", int)
|
ten_wrapnum: array("nworld", "ntendon", int)
|
||||||
ten_J: array("nworld", "ntendon", "nv", float)
|
ten_J: array("nworld", "nJten", float)
|
||||||
ten_length: array("nworld", "ntendon", float)
|
ten_length: array("nworld", "ntendon", float)
|
||||||
wrap_obj: array("nworld", "nwrap", wp.vec2i)
|
wrap_obj: array("nworld", "nwrap", wp.vec2i)
|
||||||
wrap_xpos: array("nworld", "nwrap", wp.spatial_vector)
|
wrap_xpos: array("nworld", "nwrap", wp.spatial_vector)
|
||||||
@@ -1877,6 +1881,7 @@ class Data:
|
|||||||
naccdmax: int
|
naccdmax: int
|
||||||
njmax: int
|
njmax: int
|
||||||
njmax_pad: int
|
njmax_pad: int
|
||||||
|
njmax_nnz: int
|
||||||
nacon: array(1, int)
|
nacon: array(1, int)
|
||||||
ncollision: array(1, int)
|
ncollision: array(1, int)
|
||||||
|
|
||||||
@@ -1905,21 +1910,12 @@ class RenderContext:
|
|||||||
hfield_registry: hfield BVH id to warp mesh mapping
|
hfield_registry: hfield BVH id to warp mesh mapping
|
||||||
hfield_bvh_id: hfield BVH ids
|
hfield_bvh_id: hfield BVH ids
|
||||||
hfield_bounds_size: hfield bounds half-extents
|
hfield_bounds_size: hfield bounds half-extents
|
||||||
flex_mesh: flex mesh
|
flex_mesh_registry: per-flex mesh BVH registry (prevents garbage collection)
|
||||||
flex_rgba: flex rgba
|
flex_rgba: flex rgba
|
||||||
flex_bvh_id: flex BVH id
|
flex_bvh_id: per-flex BVH ids
|
||||||
flex_face_point: flex face points
|
flex_group_root: per-flex group roots (nworld x n_flex_bvh)
|
||||||
flex_faceadr: flex face addresses
|
|
||||||
flex_nface: number of flex faces
|
|
||||||
flex_nwork: total flex work items for refit
|
|
||||||
flex_group_root: flex group roots
|
|
||||||
flex_elemdataadr: flex element data addresses
|
|
||||||
flex_shell: flex shell data
|
|
||||||
flex_shelldataadr: flex shell data addresses
|
|
||||||
flex_radius: flex radius
|
|
||||||
flex_workadr: flex work item addresses for refit
|
|
||||||
flex_worknum: flex work item counts for refit
|
|
||||||
flex_render_smooth: whether to render flex meshes smoothly
|
flex_render_smooth: whether to render flex meshes smoothly
|
||||||
|
flex_dim: flex dimension per flex (1D/2D/3D)
|
||||||
bvh: scene BVH
|
bvh: scene BVH
|
||||||
bvh_id: scene BVH id
|
bvh_id: scene BVH id
|
||||||
lower: lower bounds
|
lower: lower bounds
|
||||||
@@ -1929,12 +1925,13 @@ class RenderContext:
|
|||||||
ray: rays
|
ray: rays
|
||||||
rgb_data: RGB data
|
rgb_data: RGB data
|
||||||
rgb_adr: RGB addresses
|
rgb_adr: RGB addresses
|
||||||
rgb_size: per-camera RGB buffer sizes
|
|
||||||
depth_data: depth data
|
depth_data: depth data
|
||||||
depth_adr: depth addresses
|
depth_adr: depth addresses
|
||||||
depth_size: per-camera depth buffer sizes
|
|
||||||
render_rgb: per-camera RGB render flags
|
render_rgb: per-camera RGB render flags
|
||||||
render_depth: per-camera depth render flags
|
render_depth: per-camera depth render flags
|
||||||
|
seg_data: segmentation data (per-pixel geom IDs)
|
||||||
|
seg_adr: segmentation addresses
|
||||||
|
render_seg: per-camera segmentation render flags
|
||||||
znear: near plane distance
|
znear: near plane distance
|
||||||
total_rays: total number of rays
|
total_rays: total number of rays
|
||||||
"""
|
"""
|
||||||
@@ -1954,27 +1951,20 @@ class RenderContext:
|
|||||||
mesh_texcoord: array("*", wp.vec2)
|
mesh_texcoord: array("*", wp.vec2)
|
||||||
mesh_texcoord_offsets: array("nmesh", int)
|
mesh_texcoord_offsets: array("nmesh", int)
|
||||||
mesh_facetexcoord: array("nmeshface", wp.vec3i)
|
mesh_facetexcoord: array("nmeshface", wp.vec3i)
|
||||||
# TODO(team): remove after mjwarp depends on warp-lang >= 1.12 in pyproject.toml
|
textures: array("*", wp.Texture2D)
|
||||||
textures: array("*", TEXTURE_DTYPE)
|
textures_registry: list[wp.Texture2D]
|
||||||
textures_registry: list[TEXTURE_DTYPE]
|
|
||||||
hfield_registry: dict
|
hfield_registry: dict
|
||||||
hfield_bvh_id: array("nhfield", wp.uint64)
|
hfield_bvh_id: array("nhfield", wp.uint64)
|
||||||
hfield_bounds_size: array("nhfield", wp.vec3)
|
hfield_bounds_size: array("nhfield", wp.vec3)
|
||||||
flex_mesh: wp.Mesh
|
flex_mesh_registry: dict
|
||||||
flex_rgba: array("nflex", wp.vec4)
|
flex_rgba: array("nflex", wp.vec4)
|
||||||
flex_bvh_id: wp.uint64
|
flex_bvh_id: array("*", wp.uint64)
|
||||||
flex_face_point: array("*", wp.vec3)
|
flex_group_root: array("nworld", "*", int)
|
||||||
flex_faceadr: array("nflex", int)
|
|
||||||
flex_nface: int
|
|
||||||
flex_nwork: int
|
|
||||||
flex_group_root: array("nworld", int)
|
|
||||||
flex_elemdataadr: array("nflex", int)
|
|
||||||
flex_shell: array("*", int)
|
|
||||||
flex_shelldataadr: array("nflex", int)
|
|
||||||
flex_radius: array("nflex", float)
|
|
||||||
flex_workadr: array("nflex", int)
|
|
||||||
flex_worknum: array("nflex", int)
|
|
||||||
flex_render_smooth: bool
|
flex_render_smooth: bool
|
||||||
|
bvh_nflexgeom: int
|
||||||
|
flex_dim_np: array("nflex", int)
|
||||||
|
flex_geom_flexid: array("*", int)
|
||||||
|
flex_geom_edgeid: array("*", int)
|
||||||
bvh: wp.Bvh
|
bvh: wp.Bvh
|
||||||
bvh_id: wp.uint64
|
bvh_id: wp.uint64
|
||||||
lower: array("*", wp.vec3)
|
lower: array("*", wp.vec3)
|
||||||
@@ -1988,5 +1978,8 @@ class RenderContext:
|
|||||||
depth_adr: array("ncam", int)
|
depth_adr: array("ncam", int)
|
||||||
render_rgb: array("ncam", bool)
|
render_rgb: array("ncam", bool)
|
||||||
render_depth: array("ncam", bool)
|
render_depth: array("ncam", bool)
|
||||||
|
seg_data: array("*", int)
|
||||||
|
seg_adr: array("ncam", int)
|
||||||
|
render_seg: array("ncam", bool)
|
||||||
znear: float
|
znear: float
|
||||||
total_rays: int
|
total_rays: int
|
||||||
|
|||||||
+2
-6
@@ -37,9 +37,7 @@ def _parse_version(version_str: str) -> tuple[tuple[int, int | str], ...]:
|
|||||||
"""
|
"""
|
||||||
# Split on both '.' and '-'
|
# Split on both '.' and '-'
|
||||||
parts = re.split(r"[.\-]", version_str)
|
parts = re.split(r"[.\-]", version_str)
|
||||||
return tuple(
|
return tuple([(0, int(p)) if p.isdigit() else (-1, p) for p in parts] + [(0, 0)])
|
||||||
[(0, int(p)) if p.isdigit() else (-1, p) for p in parts] + [(0, 0)]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def check_version(spec: str) -> bool:
|
def check_version(spec: str) -> bool:
|
||||||
@@ -65,9 +63,7 @@ def check_version(spec: str) -> bool:
|
|||||||
"""
|
"""
|
||||||
match = re.match(r"^([a-zA-Z0-9_\-]+)(>=|<=|>|<|==|!=)(.+)$", spec)
|
match = re.match(r"^([a-zA-Z0-9_\-]+)(>=|<=|>|<|==|!=)(.+)$", spec)
|
||||||
if not match:
|
if not match:
|
||||||
raise ValueError(
|
raise ValueError(f"Invalid version spec '{spec}'. Expected format: 'package>=version'")
|
||||||
f"Invalid version spec '{spec}'. Expected format: 'package>=version'"
|
|
||||||
)
|
|
||||||
package_name, op, version_str = match.groups()
|
package_name, op, version_str = match.groups()
|
||||||
|
|
||||||
required_version = _parse_version(version_str)
|
required_version = _parse_version(version_str)
|
||||||
|
|||||||
+2
-2
@@ -28,7 +28,7 @@ requires-python = ">=3.10"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"absl-py",
|
"absl-py",
|
||||||
"etils[epath]",
|
"etils[epath]",
|
||||||
"mujoco>=3.5.0",
|
"mujoco>=3.6.0",
|
||||||
"numpy",
|
"numpy",
|
||||||
"warp-lang>=1.12",
|
"warp-lang>=1.12",
|
||||||
]
|
]
|
||||||
@@ -55,7 +55,7 @@ dev = [
|
|||||||
"ruff",
|
"ruff",
|
||||||
"pygls>=1.0.0,<2.0.0",
|
"pygls>=1.0.0,<2.0.0",
|
||||||
"lsprotocol>=2023.0.1,<2024.0.0",
|
"lsprotocol>=2023.0.1,<2024.0.0",
|
||||||
"mujoco>=3.5.0.dev0",
|
"mujoco>=3.6.0.dev0",
|
||||||
"warp-lang>=1.11.0.dev0",
|
"warp-lang>=1.11.0.dev0",
|
||||||
]
|
]
|
||||||
# TODO(team): cpu and cuda JAX optional dependencies are temporary, remove after we land MJX:Warp
|
# TODO(team): cpu and cuda JAX optional dependencies are temporary, remove after we land MJX:Warp
|
||||||
|
|||||||
+3
-2
@@ -18,7 +18,7 @@
|
|||||||
Usage: mjwarp-viewer <mjcf XML path> [flags]
|
Usage: mjwarp-viewer <mjcf XML path> [flags]
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
mjwarp-viewer benchmark/humanoid/humanoid.xml -o "opt.solver=cg"
|
mjwarp-viewer benchmarks/humanoid/humanoid.xml -o "opt.solver=cg"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
@@ -56,6 +56,7 @@ _CLEAR_WARP_CACHE = flags.DEFINE_bool("clear_warp_cache", False, "Clear warp cac
|
|||||||
_ENGINE = flags.DEFINE_enum_class("engine", EngineOptions.WARP, EngineOptions, "Simulation engine")
|
_ENGINE = flags.DEFINE_enum_class("engine", EngineOptions.WARP, EngineOptions, "Simulation engine")
|
||||||
_NCONMAX = flags.DEFINE_integer("nconmax", None, "Maximum number of contacts.")
|
_NCONMAX = flags.DEFINE_integer("nconmax", None, "Maximum number of contacts.")
|
||||||
_NJMAX = flags.DEFINE_integer("njmax", None, "Maximum number of constraints per world.")
|
_NJMAX = flags.DEFINE_integer("njmax", None, "Maximum number of constraints per world.")
|
||||||
|
_NJMAX_NNZ = flags.DEFINE_integer("njmax_nnz", None, "Maximum number of non-zeros in constraint Jacobian.")
|
||||||
_NCCDMAX = flags.DEFINE_integer("nccdmax", None, "Maximum number of CCD contacts per world.")
|
_NCCDMAX = flags.DEFINE_integer("nccdmax", None, "Maximum number of CCD contacts per world.")
|
||||||
_OVERRIDE = flags.DEFINE_multi_string("override", [], "Model overrides (notation: foo.bar = baz)", short_name="o")
|
_OVERRIDE = flags.DEFINE_multi_string("override", [], "Model overrides (notation: foo.bar = baz)", short_name="o")
|
||||||
_KEYFRAME = flags.DEFINE_integer("keyframe", 0, "keyframe to initialize simulation.")
|
_KEYFRAME = flags.DEFINE_integer("keyframe", 0, "keyframe to initialize simulation.")
|
||||||
@@ -149,7 +150,7 @@ def _main(argv: Sequence[str]) -> None:
|
|||||||
override_model(mjm, _OVERRIDE.value)
|
override_model(mjm, _OVERRIDE.value)
|
||||||
m = mjw.put_model(mjm)
|
m = mjw.put_model(mjm)
|
||||||
override_model(m, _OVERRIDE.value)
|
override_model(m, _OVERRIDE.value)
|
||||||
d = mjw.put_data(mjm, mjd, nconmax=_NCONMAX.value, njmax=_NJMAX.value, nccdmax=_NCCDMAX.value)
|
d = mjw.put_data(mjm, mjd, nconmax=_NCONMAX.value, njmax=_NJMAX.value, njmax_nnz=_NJMAX_NNZ.value, nccdmax=_NCCDMAX.value)
|
||||||
graph = _compile_step(m, d) if wp.get_device().is_cuda else None
|
graph = _compile_step(m, d) if wp.get_device().is_cuda else None
|
||||||
if graph is None:
|
if graph is None:
|
||||||
mjw.step(m, d) # warmup step
|
mjw.step(m, d) # warmup step
|
||||||
|
|||||||
@@ -48,20 +48,27 @@ _cb = mjwp_types.Callback(
|
|||||||
**{f.name: None for f in dataclasses.fields(mjwp_types.Callback) if f.init}
|
**{f.name: None for f in dataclasses.fields(mjwp_types.Callback) if f.init}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ffi.format_args_for_warp
|
@ffi.format_args_for_warp
|
||||||
def _refit_bvh_shim(
|
def _refit_bvh_shim(
|
||||||
# Model
|
# Model
|
||||||
nworld: int,
|
nworld: int,
|
||||||
flex_dim: wp.array(dtype=int),
|
flex_dim: wp.array(dtype=int),
|
||||||
|
flex_edge: wp.array(dtype=wp.vec2i),
|
||||||
flex_elem: wp.array(dtype=int),
|
flex_elem: wp.array(dtype=int),
|
||||||
|
flex_elemadr: wp.array(dtype=int),
|
||||||
|
flex_elemdataadr: wp.array(dtype=int),
|
||||||
flex_elemnum: wp.array(dtype=int),
|
flex_elemnum: wp.array(dtype=int),
|
||||||
|
flex_radius: wp.array(dtype=float),
|
||||||
|
flex_shell: wp.array(dtype=int),
|
||||||
|
flex_shelldataadr: wp.array(dtype=int),
|
||||||
flex_vertadr: wp.array(dtype=int),
|
flex_vertadr: wp.array(dtype=int),
|
||||||
|
flex_vertnum: wp.array(dtype=int),
|
||||||
geom_dataid: wp.array(dtype=int),
|
geom_dataid: wp.array(dtype=int),
|
||||||
geom_size: wp.array2d(dtype=wp.vec3),
|
geom_size: wp.array2d(dtype=wp.vec3),
|
||||||
geom_type: wp.array(dtype=int),
|
geom_type: wp.array(dtype=int),
|
||||||
nflex: int,
|
nflex: int,
|
||||||
nflexelemdata: int,
|
nflexelem: int,
|
||||||
nflexvert: int,
|
|
||||||
# Data
|
# Data
|
||||||
flexvert_xpos: wp.array2d(dtype=wp.vec3),
|
flexvert_xpos: wp.array2d(dtype=wp.vec3),
|
||||||
geom_xmat: wp.array2d(dtype=wp.mat33),
|
geom_xmat: wp.array2d(dtype=wp.mat33),
|
||||||
@@ -77,15 +84,21 @@ def _refit_bvh_shim(
|
|||||||
_d.efc = _e
|
_d.efc = _e
|
||||||
_d.contact = _c
|
_d.contact = _c
|
||||||
_m.flex_dim = flex_dim
|
_m.flex_dim = flex_dim
|
||||||
|
_m.flex_edge = flex_edge
|
||||||
_m.flex_elem = flex_elem
|
_m.flex_elem = flex_elem
|
||||||
|
_m.flex_elemadr = flex_elemadr
|
||||||
|
_m.flex_elemdataadr = flex_elemdataadr
|
||||||
_m.flex_elemnum = flex_elemnum
|
_m.flex_elemnum = flex_elemnum
|
||||||
|
_m.flex_radius = flex_radius
|
||||||
|
_m.flex_shell = flex_shell
|
||||||
|
_m.flex_shelldataadr = flex_shelldataadr
|
||||||
_m.flex_vertadr = flex_vertadr
|
_m.flex_vertadr = flex_vertadr
|
||||||
|
_m.flex_vertnum = flex_vertnum
|
||||||
_m.geom_dataid = geom_dataid
|
_m.geom_dataid = geom_dataid
|
||||||
_m.geom_size = geom_size
|
_m.geom_size = geom_size
|
||||||
_m.geom_type = geom_type
|
_m.geom_type = geom_type
|
||||||
_m.nflex = nflex
|
_m.nflex = nflex
|
||||||
_m.nflexelemdata = nflexelemdata
|
_m.nflexelem = nflexelem
|
||||||
_m.nflexvert = nflexvert
|
|
||||||
_d.flexvert_xpos = flexvert_xpos
|
_d.flexvert_xpos = flexvert_xpos
|
||||||
_d.geom_xmat = geom_xmat
|
_d.geom_xmat = geom_xmat
|
||||||
_d.geom_xpos = geom_xpos
|
_d.geom_xpos = geom_xpos
|
||||||
@@ -113,15 +126,21 @@ def _refit_bvh_jax_impl(
|
|||||||
out = jf(
|
out = jf(
|
||||||
d.qpos.shape[0],
|
d.qpos.shape[0],
|
||||||
m._impl.flex_dim,
|
m._impl.flex_dim,
|
||||||
|
m._impl.flex_edge,
|
||||||
m._impl.flex_elem,
|
m._impl.flex_elem,
|
||||||
|
m._impl.flex_elemadr,
|
||||||
|
m._impl.flex_elemdataadr,
|
||||||
m._impl.flex_elemnum,
|
m._impl.flex_elemnum,
|
||||||
|
m._impl.flex_radius,
|
||||||
|
m._impl.flex_shell,
|
||||||
|
m._impl.flex_shelldataadr,
|
||||||
m._impl.flex_vertadr,
|
m._impl.flex_vertadr,
|
||||||
|
m._impl.flex_vertnum,
|
||||||
m.geom_dataid,
|
m.geom_dataid,
|
||||||
m.geom_size,
|
m.geom_size,
|
||||||
m.geom_type,
|
m.geom_type,
|
||||||
m._impl.nflex,
|
m._impl.nflex,
|
||||||
m._impl.nflexelemdata,
|
m._impl.nflexelem,
|
||||||
m._impl.nflexvert,
|
|
||||||
d._impl.flexvert_xpos,
|
d._impl.flexvert_xpos,
|
||||||
d.geom_xmat,
|
d.geom_xmat,
|
||||||
d.geom_xpos,
|
d.geom_xpos,
|
||||||
|
|||||||
@@ -52,8 +52,26 @@ def _collision_shim(
|
|||||||
# Model
|
# Model
|
||||||
nworld: int,
|
nworld: int,
|
||||||
block_dim: mjwp_types.BlockDim,
|
block_dim: mjwp_types.BlockDim,
|
||||||
|
flex_conaffinity: wp.array(dtype=int),
|
||||||
|
flex_condim: wp.array(dtype=int),
|
||||||
|
flex_contype: wp.array(dtype=int),
|
||||||
|
flex_dim: wp.array(dtype=int),
|
||||||
|
flex_elem: wp.array(dtype=int),
|
||||||
|
flex_elemadr: wp.array(dtype=int),
|
||||||
|
flex_elemdataadr: wp.array(dtype=int),
|
||||||
|
flex_elemnum: wp.array(dtype=int),
|
||||||
|
flex_friction: wp.array(dtype=wp.vec3),
|
||||||
|
flex_margin: wp.array(dtype=float),
|
||||||
|
flex_radius: wp.array(dtype=float),
|
||||||
|
flex_shell: wp.array(dtype=int),
|
||||||
|
flex_shelldataadr: wp.array(dtype=int),
|
||||||
|
flex_shellnum: wp.array(dtype=int),
|
||||||
|
flex_vertadr: wp.array(dtype=int),
|
||||||
|
flex_vertflexid: wp.array(dtype=int),
|
||||||
geom_aabb: wp.array3d(dtype=wp.vec3),
|
geom_aabb: wp.array3d(dtype=wp.vec3),
|
||||||
|
geom_conaffinity: wp.array(dtype=int),
|
||||||
geom_condim: wp.array(dtype=int),
|
geom_condim: wp.array(dtype=int),
|
||||||
|
geom_contype: wp.array(dtype=int),
|
||||||
geom_dataid: wp.array(dtype=int),
|
geom_dataid: wp.array(dtype=int),
|
||||||
geom_friction: wp.array2d(dtype=wp.vec3),
|
geom_friction: wp.array2d(dtype=wp.vec3),
|
||||||
geom_gap: wp.array2d(dtype=float),
|
geom_gap: wp.array2d(dtype=float),
|
||||||
@@ -90,6 +108,10 @@ def _collision_shim(
|
|||||||
mesh_vert: wp.array(dtype=wp.vec3),
|
mesh_vert: wp.array(dtype=wp.vec3),
|
||||||
mesh_vertadr: wp.array(dtype=int),
|
mesh_vertadr: wp.array(dtype=int),
|
||||||
mesh_vertnum: wp.array(dtype=int),
|
mesh_vertnum: wp.array(dtype=int),
|
||||||
|
nflex: int,
|
||||||
|
nflexelem: int,
|
||||||
|
nflexshelldata: int,
|
||||||
|
nflexvert: int,
|
||||||
ngeom: int,
|
ngeom: int,
|
||||||
nmaxmeshdeg: int,
|
nmaxmeshdeg: int,
|
||||||
nmaxpolygon: int,
|
nmaxpolygon: int,
|
||||||
@@ -108,7 +130,7 @@ def _collision_shim(
|
|||||||
pair_solref: wp.array2d(dtype=wp.vec2),
|
pair_solref: wp.array2d(dtype=wp.vec2),
|
||||||
pair_solreffriction: wp.array2d(dtype=wp.vec2),
|
pair_solreffriction: wp.array2d(dtype=wp.vec2),
|
||||||
plugin: wp.array(dtype=int),
|
plugin: wp.array(dtype=int),
|
||||||
plugin_attr: wp.array(dtype=wp.vec3f),
|
plugin_attr: wp.array(dtype=mjwp_types.vec_pluginattr),
|
||||||
opt__broadphase: int,
|
opt__broadphase: int,
|
||||||
opt__broadphase_filter: int,
|
opt__broadphase_filter: int,
|
||||||
opt__ccd_iterations: int,
|
opt__ccd_iterations: int,
|
||||||
@@ -120,12 +142,15 @@ def _collision_shim(
|
|||||||
# Data
|
# Data
|
||||||
naccdmax: int,
|
naccdmax: int,
|
||||||
naconmax: int,
|
naconmax: int,
|
||||||
|
flexvert_xpos: wp.array2d(dtype=wp.vec3),
|
||||||
geom_xmat: wp.array2d(dtype=wp.mat33),
|
geom_xmat: wp.array2d(dtype=wp.mat33),
|
||||||
geom_xpos: wp.array2d(dtype=wp.vec3),
|
geom_xpos: wp.array2d(dtype=wp.vec3),
|
||||||
nacon: wp.array(dtype=int),
|
nacon: wp.array(dtype=int),
|
||||||
ncollision: wp.array(dtype=int),
|
ncollision: wp.array(dtype=int),
|
||||||
contact__dim: wp.array(dtype=int),
|
contact__dim: wp.array(dtype=int),
|
||||||
contact__dist: wp.array(dtype=float),
|
contact__dist: wp.array(dtype=float),
|
||||||
|
contact__efc_address: wp.array2d(dtype=int),
|
||||||
|
contact__flex: wp.array(dtype=wp.vec2i),
|
||||||
contact__frame: wp.array(dtype=wp.mat33),
|
contact__frame: wp.array(dtype=wp.mat33),
|
||||||
contact__friction: wp.array(dtype=mjwp_types.vec5),
|
contact__friction: wp.array(dtype=mjwp_types.vec5),
|
||||||
contact__geom: wp.array(dtype=wp.vec2i),
|
contact__geom: wp.array(dtype=wp.vec2i),
|
||||||
@@ -136,6 +161,7 @@ def _collision_shim(
|
|||||||
contact__solref: wp.array(dtype=wp.vec2),
|
contact__solref: wp.array(dtype=wp.vec2),
|
||||||
contact__solreffriction: wp.array(dtype=wp.vec2),
|
contact__solreffriction: wp.array(dtype=wp.vec2),
|
||||||
contact__type: wp.array(dtype=int),
|
contact__type: wp.array(dtype=int),
|
||||||
|
contact__vert: wp.array(dtype=wp.vec2i),
|
||||||
contact__worldid: wp.array(dtype=int),
|
contact__worldid: wp.array(dtype=int),
|
||||||
):
|
):
|
||||||
_m.stat = _s
|
_m.stat = _s
|
||||||
@@ -144,8 +170,26 @@ def _collision_shim(
|
|||||||
_d.efc = _e
|
_d.efc = _e
|
||||||
_d.contact = _c
|
_d.contact = _c
|
||||||
_m.block_dim = block_dim
|
_m.block_dim = block_dim
|
||||||
|
_m.flex_conaffinity = flex_conaffinity
|
||||||
|
_m.flex_condim = flex_condim
|
||||||
|
_m.flex_contype = flex_contype
|
||||||
|
_m.flex_dim = flex_dim
|
||||||
|
_m.flex_elem = flex_elem
|
||||||
|
_m.flex_elemadr = flex_elemadr
|
||||||
|
_m.flex_elemdataadr = flex_elemdataadr
|
||||||
|
_m.flex_elemnum = flex_elemnum
|
||||||
|
_m.flex_friction = flex_friction
|
||||||
|
_m.flex_margin = flex_margin
|
||||||
|
_m.flex_radius = flex_radius
|
||||||
|
_m.flex_shell = flex_shell
|
||||||
|
_m.flex_shelldataadr = flex_shelldataadr
|
||||||
|
_m.flex_shellnum = flex_shellnum
|
||||||
|
_m.flex_vertadr = flex_vertadr
|
||||||
|
_m.flex_vertflexid = flex_vertflexid
|
||||||
_m.geom_aabb = geom_aabb
|
_m.geom_aabb = geom_aabb
|
||||||
|
_m.geom_conaffinity = geom_conaffinity
|
||||||
_m.geom_condim = geom_condim
|
_m.geom_condim = geom_condim
|
||||||
|
_m.geom_contype = geom_contype
|
||||||
_m.geom_dataid = geom_dataid
|
_m.geom_dataid = geom_dataid
|
||||||
_m.geom_friction = geom_friction
|
_m.geom_friction = geom_friction
|
||||||
_m.geom_gap = geom_gap
|
_m.geom_gap = geom_gap
|
||||||
@@ -182,6 +226,10 @@ def _collision_shim(
|
|||||||
_m.mesh_vert = mesh_vert
|
_m.mesh_vert = mesh_vert
|
||||||
_m.mesh_vertadr = mesh_vertadr
|
_m.mesh_vertadr = mesh_vertadr
|
||||||
_m.mesh_vertnum = mesh_vertnum
|
_m.mesh_vertnum = mesh_vertnum
|
||||||
|
_m.nflex = nflex
|
||||||
|
_m.nflexelem = nflexelem
|
||||||
|
_m.nflexshelldata = nflexshelldata
|
||||||
|
_m.nflexvert = nflexvert
|
||||||
_m.ngeom = ngeom
|
_m.ngeom = ngeom
|
||||||
_m.nmaxmeshdeg = nmaxmeshdeg
|
_m.nmaxmeshdeg = nmaxmeshdeg
|
||||||
_m.nmaxpolygon = nmaxpolygon
|
_m.nmaxpolygon = nmaxpolygon
|
||||||
@@ -211,6 +259,8 @@ def _collision_shim(
|
|||||||
_m.plugin_attr = plugin_attr
|
_m.plugin_attr = plugin_attr
|
||||||
_d.contact.dim = contact__dim
|
_d.contact.dim = contact__dim
|
||||||
_d.contact.dist = contact__dist
|
_d.contact.dist = contact__dist
|
||||||
|
_d.contact.efc_address = contact__efc_address
|
||||||
|
_d.contact.flex = contact__flex
|
||||||
_d.contact.frame = contact__frame
|
_d.contact.frame = contact__frame
|
||||||
_d.contact.friction = contact__friction
|
_d.contact.friction = contact__friction
|
||||||
_d.contact.geom = contact__geom
|
_d.contact.geom = contact__geom
|
||||||
@@ -221,7 +271,9 @@ def _collision_shim(
|
|||||||
_d.contact.solref = contact__solref
|
_d.contact.solref = contact__solref
|
||||||
_d.contact.solreffriction = contact__solreffriction
|
_d.contact.solreffriction = contact__solreffriction
|
||||||
_d.contact.type = contact__type
|
_d.contact.type = contact__type
|
||||||
|
_d.contact.vert = contact__vert
|
||||||
_d.contact.worldid = contact__worldid
|
_d.contact.worldid = contact__worldid
|
||||||
|
_d.flexvert_xpos = flexvert_xpos
|
||||||
_d.geom_xmat = geom_xmat
|
_d.geom_xmat = geom_xmat
|
||||||
_d.geom_xpos = geom_xpos
|
_d.geom_xpos = geom_xpos
|
||||||
_d.naccdmax = naccdmax
|
_d.naccdmax = naccdmax
|
||||||
@@ -238,6 +290,8 @@ def _collision_jax_impl(m: types.Model, d: types.Data):
|
|||||||
'ncollision': d._impl.ncollision.shape,
|
'ncollision': d._impl.ncollision.shape,
|
||||||
'contact__dim': d._impl.contact__dim.shape,
|
'contact__dim': d._impl.contact__dim.shape,
|
||||||
'contact__dist': d._impl.contact__dist.shape,
|
'contact__dist': d._impl.contact__dist.shape,
|
||||||
|
'contact__efc_address': d._impl.contact__efc_address.shape,
|
||||||
|
'contact__flex': d._impl.contact__flex.shape,
|
||||||
'contact__frame': d._impl.contact__frame.shape,
|
'contact__frame': d._impl.contact__frame.shape,
|
||||||
'contact__friction': d._impl.contact__friction.shape,
|
'contact__friction': d._impl.contact__friction.shape,
|
||||||
'contact__geom': d._impl.contact__geom.shape,
|
'contact__geom': d._impl.contact__geom.shape,
|
||||||
@@ -248,11 +302,12 @@ def _collision_jax_impl(m: types.Model, d: types.Data):
|
|||||||
'contact__solref': d._impl.contact__solref.shape,
|
'contact__solref': d._impl.contact__solref.shape,
|
||||||
'contact__solreffriction': d._impl.contact__solreffriction.shape,
|
'contact__solreffriction': d._impl.contact__solreffriction.shape,
|
||||||
'contact__type': d._impl.contact__type.shape,
|
'contact__type': d._impl.contact__type.shape,
|
||||||
|
'contact__vert': d._impl.contact__vert.shape,
|
||||||
'contact__worldid': d._impl.contact__worldid.shape,
|
'contact__worldid': d._impl.contact__worldid.shape,
|
||||||
}
|
}
|
||||||
jf = ffi.jax_callable_variadic_tuple(
|
jf = ffi.jax_callable_variadic_tuple(
|
||||||
_collision_shim,
|
_collision_shim,
|
||||||
num_outputs=15,
|
num_outputs=18,
|
||||||
output_dims=output_dims,
|
output_dims=output_dims,
|
||||||
vmap_method=None,
|
vmap_method=None,
|
||||||
in_out_argnames=set([
|
in_out_argnames=set([
|
||||||
@@ -260,6 +315,8 @@ def _collision_jax_impl(m: types.Model, d: types.Data):
|
|||||||
'ncollision',
|
'ncollision',
|
||||||
'contact__dim',
|
'contact__dim',
|
||||||
'contact__dist',
|
'contact__dist',
|
||||||
|
'contact__efc_address',
|
||||||
|
'contact__flex',
|
||||||
'contact__frame',
|
'contact__frame',
|
||||||
'contact__friction',
|
'contact__friction',
|
||||||
'contact__geom',
|
'contact__geom',
|
||||||
@@ -270,6 +327,7 @@ def _collision_jax_impl(m: types.Model, d: types.Data):
|
|||||||
'contact__solref',
|
'contact__solref',
|
||||||
'contact__solreffriction',
|
'contact__solreffriction',
|
||||||
'contact__type',
|
'contact__type',
|
||||||
|
'contact__vert',
|
||||||
'contact__worldid',
|
'contact__worldid',
|
||||||
]),
|
]),
|
||||||
stage_in_argnames=set([
|
stage_in_argnames=set([
|
||||||
@@ -299,8 +357,26 @@ def _collision_jax_impl(m: types.Model, d: types.Data):
|
|||||||
out = jf(
|
out = jf(
|
||||||
d.qpos.shape[0],
|
d.qpos.shape[0],
|
||||||
m._impl.block_dim,
|
m._impl.block_dim,
|
||||||
|
m._impl.flex_conaffinity,
|
||||||
|
m._impl.flex_condim,
|
||||||
|
m._impl.flex_contype,
|
||||||
|
m._impl.flex_dim,
|
||||||
|
m._impl.flex_elem,
|
||||||
|
m._impl.flex_elemadr,
|
||||||
|
m._impl.flex_elemdataadr,
|
||||||
|
m._impl.flex_elemnum,
|
||||||
|
m._impl.flex_friction,
|
||||||
|
m._impl.flex_margin,
|
||||||
|
m._impl.flex_radius,
|
||||||
|
m._impl.flex_shell,
|
||||||
|
m._impl.flex_shelldataadr,
|
||||||
|
m._impl.flex_shellnum,
|
||||||
|
m._impl.flex_vertadr,
|
||||||
|
m._impl.flex_vertflexid,
|
||||||
m.geom_aabb,
|
m.geom_aabb,
|
||||||
|
m.geom_conaffinity,
|
||||||
m.geom_condim,
|
m.geom_condim,
|
||||||
|
m.geom_contype,
|
||||||
m.geom_dataid,
|
m.geom_dataid,
|
||||||
m.geom_friction,
|
m.geom_friction,
|
||||||
m.geom_gap,
|
m.geom_gap,
|
||||||
@@ -337,6 +413,10 @@ def _collision_jax_impl(m: types.Model, d: types.Data):
|
|||||||
m.mesh_vert,
|
m.mesh_vert,
|
||||||
m.mesh_vertadr,
|
m.mesh_vertadr,
|
||||||
m.mesh_vertnum,
|
m.mesh_vertnum,
|
||||||
|
m._impl.nflex,
|
||||||
|
m._impl.nflexelem,
|
||||||
|
m._impl.nflexshelldata,
|
||||||
|
m._impl.nflexvert,
|
||||||
m.ngeom,
|
m.ngeom,
|
||||||
m._impl.nmaxmeshdeg,
|
m._impl.nmaxmeshdeg,
|
||||||
m._impl.nmaxpolygon,
|
m._impl.nmaxpolygon,
|
||||||
@@ -366,12 +446,15 @@ def _collision_jax_impl(m: types.Model, d: types.Data):
|
|||||||
m.opt._impl.sdf_iterations,
|
m.opt._impl.sdf_iterations,
|
||||||
d._impl.naccdmax,
|
d._impl.naccdmax,
|
||||||
d._impl.naconmax,
|
d._impl.naconmax,
|
||||||
|
d._impl.flexvert_xpos,
|
||||||
d.geom_xmat,
|
d.geom_xmat,
|
||||||
d.geom_xpos,
|
d.geom_xpos,
|
||||||
d._impl.nacon,
|
d._impl.nacon,
|
||||||
d._impl.ncollision,
|
d._impl.ncollision,
|
||||||
d._impl.contact__dim,
|
d._impl.contact__dim,
|
||||||
d._impl.contact__dist,
|
d._impl.contact__dist,
|
||||||
|
d._impl.contact__efc_address,
|
||||||
|
d._impl.contact__flex,
|
||||||
d._impl.contact__frame,
|
d._impl.contact__frame,
|
||||||
d._impl.contact__friction,
|
d._impl.contact__friction,
|
||||||
d._impl.contact__geom,
|
d._impl.contact__geom,
|
||||||
@@ -382,6 +465,7 @@ def _collision_jax_impl(m: types.Model, d: types.Data):
|
|||||||
d._impl.contact__solref,
|
d._impl.contact__solref,
|
||||||
d._impl.contact__solreffriction,
|
d._impl.contact__solreffriction,
|
||||||
d._impl.contact__type,
|
d._impl.contact__type,
|
||||||
|
d._impl.contact__vert,
|
||||||
d._impl.contact__worldid,
|
d._impl.contact__worldid,
|
||||||
)
|
)
|
||||||
d = d.tree_replace({
|
d = d.tree_replace({
|
||||||
@@ -389,17 +473,20 @@ def _collision_jax_impl(m: types.Model, d: types.Data):
|
|||||||
'_impl.ncollision': out[1],
|
'_impl.ncollision': out[1],
|
||||||
'_impl.contact__dim': out[2],
|
'_impl.contact__dim': out[2],
|
||||||
'_impl.contact__dist': out[3],
|
'_impl.contact__dist': out[3],
|
||||||
'_impl.contact__frame': out[4],
|
'_impl.contact__efc_address': out[4],
|
||||||
'_impl.contact__friction': out[5],
|
'_impl.contact__flex': out[5],
|
||||||
'_impl.contact__geom': out[6],
|
'_impl.contact__frame': out[6],
|
||||||
'_impl.contact__geomcollisionid': out[7],
|
'_impl.contact__friction': out[7],
|
||||||
'_impl.contact__includemargin': out[8],
|
'_impl.contact__geom': out[8],
|
||||||
'_impl.contact__pos': out[9],
|
'_impl.contact__geomcollisionid': out[9],
|
||||||
'_impl.contact__solimp': out[10],
|
'_impl.contact__includemargin': out[10],
|
||||||
'_impl.contact__solref': out[11],
|
'_impl.contact__pos': out[11],
|
||||||
'_impl.contact__solreffriction': out[12],
|
'_impl.contact__solimp': out[12],
|
||||||
'_impl.contact__type': out[13],
|
'_impl.contact__solref': out[13],
|
||||||
'_impl.contact__worldid': out[14],
|
'_impl.contact__solreffriction': out[14],
|
||||||
|
'_impl.contact__type': out[15],
|
||||||
|
'_impl.contact__vert': out[16],
|
||||||
|
'_impl.contact__worldid': out[17],
|
||||||
})
|
})
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
|||||||
+232
-58
@@ -138,6 +138,10 @@ def _forward_shim(
|
|||||||
eq_type: wp.array(dtype=int),
|
eq_type: wp.array(dtype=int),
|
||||||
eq_wld_adr: wp.array(dtype=int),
|
eq_wld_adr: wp.array(dtype=int),
|
||||||
flex_bending: wp.array2d(dtype=float),
|
flex_bending: wp.array2d(dtype=float),
|
||||||
|
flex_centered: wp.array(dtype=bool),
|
||||||
|
flex_conaffinity: wp.array(dtype=int),
|
||||||
|
flex_condim: wp.array(dtype=int),
|
||||||
|
flex_contype: wp.array(dtype=int),
|
||||||
flex_damping: wp.array(dtype=float),
|
flex_damping: wp.array(dtype=float),
|
||||||
flex_dim: wp.array(dtype=int),
|
flex_dim: wp.array(dtype=int),
|
||||||
flex_edge: wp.array(dtype=wp.vec2i),
|
flex_edge: wp.array(dtype=wp.vec2i),
|
||||||
@@ -146,12 +150,22 @@ def _forward_shim(
|
|||||||
flex_edgenum: wp.array(dtype=int),
|
flex_edgenum: wp.array(dtype=int),
|
||||||
flex_elem: wp.array(dtype=int),
|
flex_elem: wp.array(dtype=int),
|
||||||
flex_elemadr: wp.array(dtype=int),
|
flex_elemadr: wp.array(dtype=int),
|
||||||
|
flex_elemdataadr: wp.array(dtype=int),
|
||||||
flex_elemedge: wp.array(dtype=int),
|
flex_elemedge: wp.array(dtype=int),
|
||||||
flex_elemedgeadr: wp.array(dtype=int),
|
flex_elemedgeadr: wp.array(dtype=int),
|
||||||
flex_elemnum: wp.array(dtype=int),
|
flex_elemnum: wp.array(dtype=int),
|
||||||
|
flex_friction: wp.array(dtype=wp.vec3),
|
||||||
|
flex_margin: wp.array(dtype=float),
|
||||||
|
flex_radius: wp.array(dtype=float),
|
||||||
|
flex_shell: wp.array(dtype=int),
|
||||||
|
flex_shelldataadr: wp.array(dtype=int),
|
||||||
|
flex_shellnum: wp.array(dtype=int),
|
||||||
flex_stiffness: wp.array2d(dtype=float),
|
flex_stiffness: wp.array2d(dtype=float),
|
||||||
|
flex_vert: wp.array(dtype=wp.vec3),
|
||||||
flex_vertadr: wp.array(dtype=int),
|
flex_vertadr: wp.array(dtype=int),
|
||||||
flex_vertbodyid: wp.array(dtype=int),
|
flex_vertbodyid: wp.array(dtype=int),
|
||||||
|
flex_vertflexid: wp.array(dtype=int),
|
||||||
|
flex_vertnum: wp.array(dtype=int),
|
||||||
flexedge_J_colind: wp.array(dtype=int),
|
flexedge_J_colind: wp.array(dtype=int),
|
||||||
flexedge_J_rowadr: wp.array(dtype=int),
|
flexedge_J_rowadr: wp.array(dtype=int),
|
||||||
flexedge_J_rownnz: wp.array(dtype=int),
|
flexedge_J_rownnz: wp.array(dtype=int),
|
||||||
@@ -159,7 +173,9 @@ def _forward_shim(
|
|||||||
flexedge_length0: wp.array(dtype=float),
|
flexedge_length0: wp.array(dtype=float),
|
||||||
geom_aabb: wp.array3d(dtype=wp.vec3),
|
geom_aabb: wp.array3d(dtype=wp.vec3),
|
||||||
geom_bodyid: wp.array(dtype=int),
|
geom_bodyid: wp.array(dtype=int),
|
||||||
|
geom_conaffinity: wp.array(dtype=int),
|
||||||
geom_condim: wp.array(dtype=int),
|
geom_condim: wp.array(dtype=int),
|
||||||
|
geom_contype: wp.array(dtype=int),
|
||||||
geom_dataid: wp.array(dtype=int),
|
geom_dataid: wp.array(dtype=int),
|
||||||
geom_fluid: wp.array2d(dtype=float),
|
geom_fluid: wp.array2d(dtype=float),
|
||||||
geom_friction: wp.array2d(dtype=wp.vec3),
|
geom_friction: wp.array2d(dtype=wp.vec3),
|
||||||
@@ -213,6 +229,7 @@ def _forward_shim(
|
|||||||
light_targetbodyid: wp.array(dtype=int),
|
light_targetbodyid: wp.array(dtype=int),
|
||||||
mapM2M: wp.array(dtype=int),
|
mapM2M: wp.array(dtype=int),
|
||||||
mat_rgba: wp.array2d(dtype=wp.vec4),
|
mat_rgba: wp.array2d(dtype=wp.vec4),
|
||||||
|
max_ten_J_rownnz: int,
|
||||||
mesh_face: wp.array(dtype=wp.vec3i),
|
mesh_face: wp.array(dtype=wp.vec3i),
|
||||||
mesh_faceadr: wp.array(dtype=int),
|
mesh_faceadr: wp.array(dtype=int),
|
||||||
mesh_graph: wp.array(dtype=int),
|
mesh_graph: wp.array(dtype=int),
|
||||||
@@ -235,6 +252,7 @@ def _forward_shim(
|
|||||||
mesh_vertadr: wp.array(dtype=int),
|
mesh_vertadr: wp.array(dtype=int),
|
||||||
mesh_vertnum: wp.array(dtype=int),
|
mesh_vertnum: wp.array(dtype=int),
|
||||||
nC: int,
|
nC: int,
|
||||||
|
nJten: int,
|
||||||
na: int,
|
na: int,
|
||||||
nacttrnbody: int,
|
nacttrnbody: int,
|
||||||
nbody: int,
|
nbody: int,
|
||||||
@@ -244,6 +262,7 @@ def _forward_shim(
|
|||||||
nflex: int,
|
nflex: int,
|
||||||
nflexedge: int,
|
nflexedge: int,
|
||||||
nflexelem: int,
|
nflexelem: int,
|
||||||
|
nflexshelldata: int,
|
||||||
nflexvert: int,
|
nflexvert: int,
|
||||||
ngeom: int,
|
ngeom: int,
|
||||||
ngravcomp: int,
|
ngravcomp: int,
|
||||||
@@ -279,7 +298,9 @@ def _forward_shim(
|
|||||||
pair_solref: wp.array2d(dtype=wp.vec2),
|
pair_solref: wp.array2d(dtype=wp.vec2),
|
||||||
pair_solreffriction: wp.array2d(dtype=wp.vec2),
|
pair_solreffriction: wp.array2d(dtype=wp.vec2),
|
||||||
plugin: wp.array(dtype=int),
|
plugin: wp.array(dtype=int),
|
||||||
plugin_attr: wp.array(dtype=wp.vec3f),
|
plugin_attr: wp.array(dtype=mjwp_types.vec_pluginattr),
|
||||||
|
qLD_all_updates: wp.array(dtype=wp.vec3i),
|
||||||
|
qLD_level_offsets: wp.array(dtype=int),
|
||||||
qLD_updates: tuple[wp.array(dtype=wp.vec3i), ...],
|
qLD_updates: tuple[wp.array(dtype=wp.vec3i), ...],
|
||||||
qM_fullm_i: wp.array(dtype=int),
|
qM_fullm_i: wp.array(dtype=int),
|
||||||
qM_fullm_j: wp.array(dtype=int),
|
qM_fullm_j: wp.array(dtype=int),
|
||||||
@@ -323,6 +344,9 @@ def _forward_shim(
|
|||||||
site_type: wp.array(dtype=int),
|
site_type: wp.array(dtype=int),
|
||||||
taxel_sensorid: wp.array(dtype=int),
|
taxel_sensorid: wp.array(dtype=int),
|
||||||
taxel_vertadr: wp.array(dtype=int),
|
taxel_vertadr: wp.array(dtype=int),
|
||||||
|
ten_J_colind: wp.array(dtype=int),
|
||||||
|
ten_J_rowadr: wp.array(dtype=int),
|
||||||
|
ten_J_rownnz: wp.array(dtype=int),
|
||||||
tendon_actfrclimited: wp.array(dtype=bool),
|
tendon_actfrclimited: wp.array(dtype=bool),
|
||||||
tendon_actfrcrange: wp.array2d(dtype=wp.vec2),
|
tendon_actfrcrange: wp.array2d(dtype=wp.vec2),
|
||||||
tendon_adr: wp.array(dtype=int),
|
tendon_adr: wp.array(dtype=int),
|
||||||
@@ -382,6 +406,7 @@ def _forward_shim(
|
|||||||
naccdmax: int,
|
naccdmax: int,
|
||||||
naconmax: int,
|
naconmax: int,
|
||||||
njmax: int,
|
njmax: int,
|
||||||
|
njmax_nnz: int,
|
||||||
act: wp.array2d(dtype=float),
|
act: wp.array2d(dtype=float),
|
||||||
act_dot: wp.array2d(dtype=float),
|
act_dot: wp.array2d(dtype=float),
|
||||||
actuator_force: wp.array2d(dtype=float),
|
actuator_force: wp.array2d(dtype=float),
|
||||||
@@ -446,7 +471,7 @@ def _forward_shim(
|
|||||||
subtree_angmom: wp.array2d(dtype=wp.vec3),
|
subtree_angmom: wp.array2d(dtype=wp.vec3),
|
||||||
subtree_com: wp.array2d(dtype=wp.vec3),
|
subtree_com: wp.array2d(dtype=wp.vec3),
|
||||||
subtree_linvel: wp.array2d(dtype=wp.vec3),
|
subtree_linvel: wp.array2d(dtype=wp.vec3),
|
||||||
ten_J: wp.array3d(dtype=float),
|
ten_J: wp.array2d(dtype=float),
|
||||||
ten_length: wp.array2d(dtype=float),
|
ten_length: wp.array2d(dtype=float),
|
||||||
ten_velocity: wp.array2d(dtype=float),
|
ten_velocity: wp.array2d(dtype=float),
|
||||||
ten_wrapadr: wp.array2d(dtype=int),
|
ten_wrapadr: wp.array2d(dtype=int),
|
||||||
@@ -466,6 +491,7 @@ def _forward_shim(
|
|||||||
contact__dim: wp.array(dtype=int),
|
contact__dim: wp.array(dtype=int),
|
||||||
contact__dist: wp.array(dtype=float),
|
contact__dist: wp.array(dtype=float),
|
||||||
contact__efc_address: wp.array2d(dtype=int),
|
contact__efc_address: wp.array2d(dtype=int),
|
||||||
|
contact__flex: wp.array(dtype=wp.vec2i),
|
||||||
contact__frame: wp.array(dtype=wp.mat33),
|
contact__frame: wp.array(dtype=wp.mat33),
|
||||||
contact__friction: wp.array(dtype=mjwp_types.vec5),
|
contact__friction: wp.array(dtype=mjwp_types.vec5),
|
||||||
contact__geom: wp.array(dtype=wp.vec2i),
|
contact__geom: wp.array(dtype=wp.vec2i),
|
||||||
@@ -476,6 +502,7 @@ def _forward_shim(
|
|||||||
contact__solref: wp.array(dtype=wp.vec2),
|
contact__solref: wp.array(dtype=wp.vec2),
|
||||||
contact__solreffriction: wp.array(dtype=wp.vec2),
|
contact__solreffriction: wp.array(dtype=wp.vec2),
|
||||||
contact__type: wp.array(dtype=int),
|
contact__type: wp.array(dtype=int),
|
||||||
|
contact__vert: wp.array(dtype=wp.vec2i),
|
||||||
contact__worldid: wp.array(dtype=int),
|
contact__worldid: wp.array(dtype=int),
|
||||||
efc__D: wp.array2d(dtype=float),
|
efc__D: wp.array2d(dtype=float),
|
||||||
efc__J: wp.array3d(dtype=float),
|
efc__J: wp.array3d(dtype=float),
|
||||||
@@ -585,6 +612,10 @@ def _forward_shim(
|
|||||||
_m.eq_type = eq_type
|
_m.eq_type = eq_type
|
||||||
_m.eq_wld_adr = eq_wld_adr
|
_m.eq_wld_adr = eq_wld_adr
|
||||||
_m.flex_bending = flex_bending
|
_m.flex_bending = flex_bending
|
||||||
|
_m.flex_centered = flex_centered
|
||||||
|
_m.flex_conaffinity = flex_conaffinity
|
||||||
|
_m.flex_condim = flex_condim
|
||||||
|
_m.flex_contype = flex_contype
|
||||||
_m.flex_damping = flex_damping
|
_m.flex_damping = flex_damping
|
||||||
_m.flex_dim = flex_dim
|
_m.flex_dim = flex_dim
|
||||||
_m.flex_edge = flex_edge
|
_m.flex_edge = flex_edge
|
||||||
@@ -593,12 +624,22 @@ def _forward_shim(
|
|||||||
_m.flex_edgenum = flex_edgenum
|
_m.flex_edgenum = flex_edgenum
|
||||||
_m.flex_elem = flex_elem
|
_m.flex_elem = flex_elem
|
||||||
_m.flex_elemadr = flex_elemadr
|
_m.flex_elemadr = flex_elemadr
|
||||||
|
_m.flex_elemdataadr = flex_elemdataadr
|
||||||
_m.flex_elemedge = flex_elemedge
|
_m.flex_elemedge = flex_elemedge
|
||||||
_m.flex_elemedgeadr = flex_elemedgeadr
|
_m.flex_elemedgeadr = flex_elemedgeadr
|
||||||
_m.flex_elemnum = flex_elemnum
|
_m.flex_elemnum = flex_elemnum
|
||||||
|
_m.flex_friction = flex_friction
|
||||||
|
_m.flex_margin = flex_margin
|
||||||
|
_m.flex_radius = flex_radius
|
||||||
|
_m.flex_shell = flex_shell
|
||||||
|
_m.flex_shelldataadr = flex_shelldataadr
|
||||||
|
_m.flex_shellnum = flex_shellnum
|
||||||
_m.flex_stiffness = flex_stiffness
|
_m.flex_stiffness = flex_stiffness
|
||||||
|
_m.flex_vert = flex_vert
|
||||||
_m.flex_vertadr = flex_vertadr
|
_m.flex_vertadr = flex_vertadr
|
||||||
_m.flex_vertbodyid = flex_vertbodyid
|
_m.flex_vertbodyid = flex_vertbodyid
|
||||||
|
_m.flex_vertflexid = flex_vertflexid
|
||||||
|
_m.flex_vertnum = flex_vertnum
|
||||||
_m.flexedge_J_colind = flexedge_J_colind
|
_m.flexedge_J_colind = flexedge_J_colind
|
||||||
_m.flexedge_J_rowadr = flexedge_J_rowadr
|
_m.flexedge_J_rowadr = flexedge_J_rowadr
|
||||||
_m.flexedge_J_rownnz = flexedge_J_rownnz
|
_m.flexedge_J_rownnz = flexedge_J_rownnz
|
||||||
@@ -606,7 +647,9 @@ def _forward_shim(
|
|||||||
_m.flexedge_length0 = flexedge_length0
|
_m.flexedge_length0 = flexedge_length0
|
||||||
_m.geom_aabb = geom_aabb
|
_m.geom_aabb = geom_aabb
|
||||||
_m.geom_bodyid = geom_bodyid
|
_m.geom_bodyid = geom_bodyid
|
||||||
|
_m.geom_conaffinity = geom_conaffinity
|
||||||
_m.geom_condim = geom_condim
|
_m.geom_condim = geom_condim
|
||||||
|
_m.geom_contype = geom_contype
|
||||||
_m.geom_dataid = geom_dataid
|
_m.geom_dataid = geom_dataid
|
||||||
_m.geom_fluid = geom_fluid
|
_m.geom_fluid = geom_fluid
|
||||||
_m.geom_friction = geom_friction
|
_m.geom_friction = geom_friction
|
||||||
@@ -660,6 +703,7 @@ def _forward_shim(
|
|||||||
_m.light_targetbodyid = light_targetbodyid
|
_m.light_targetbodyid = light_targetbodyid
|
||||||
_m.mapM2M = mapM2M
|
_m.mapM2M = mapM2M
|
||||||
_m.mat_rgba = mat_rgba
|
_m.mat_rgba = mat_rgba
|
||||||
|
_m.max_ten_J_rownnz = max_ten_J_rownnz
|
||||||
_m.mesh_face = mesh_face
|
_m.mesh_face = mesh_face
|
||||||
_m.mesh_faceadr = mesh_faceadr
|
_m.mesh_faceadr = mesh_faceadr
|
||||||
_m.mesh_graph = mesh_graph
|
_m.mesh_graph = mesh_graph
|
||||||
@@ -682,6 +726,7 @@ def _forward_shim(
|
|||||||
_m.mesh_vertadr = mesh_vertadr
|
_m.mesh_vertadr = mesh_vertadr
|
||||||
_m.mesh_vertnum = mesh_vertnum
|
_m.mesh_vertnum = mesh_vertnum
|
||||||
_m.nC = nC
|
_m.nC = nC
|
||||||
|
_m.nJten = nJten
|
||||||
_m.na = na
|
_m.na = na
|
||||||
_m.nacttrnbody = nacttrnbody
|
_m.nacttrnbody = nacttrnbody
|
||||||
_m.nbody = nbody
|
_m.nbody = nbody
|
||||||
@@ -691,6 +736,7 @@ def _forward_shim(
|
|||||||
_m.nflex = nflex
|
_m.nflex = nflex
|
||||||
_m.nflexedge = nflexedge
|
_m.nflexedge = nflexedge
|
||||||
_m.nflexelem = nflexelem
|
_m.nflexelem = nflexelem
|
||||||
|
_m.nflexshelldata = nflexshelldata
|
||||||
_m.nflexvert = nflexvert
|
_m.nflexvert = nflexvert
|
||||||
_m.ngeom = ngeom
|
_m.ngeom = ngeom
|
||||||
_m.ngravcomp = ngravcomp
|
_m.ngravcomp = ngravcomp
|
||||||
@@ -753,6 +799,8 @@ def _forward_shim(
|
|||||||
_m.pair_solreffriction = pair_solreffriction
|
_m.pair_solreffriction = pair_solreffriction
|
||||||
_m.plugin = plugin
|
_m.plugin = plugin
|
||||||
_m.plugin_attr = plugin_attr
|
_m.plugin_attr = plugin_attr
|
||||||
|
_m.qLD_all_updates = qLD_all_updates
|
||||||
|
_m.qLD_level_offsets = qLD_level_offsets
|
||||||
_m.qLD_updates = qLD_updates
|
_m.qLD_updates = qLD_updates
|
||||||
_m.qM_fullm_i = qM_fullm_i
|
_m.qM_fullm_i = qM_fullm_i
|
||||||
_m.qM_fullm_j = qM_fullm_j
|
_m.qM_fullm_j = qM_fullm_j
|
||||||
@@ -797,6 +845,9 @@ def _forward_shim(
|
|||||||
_m.stat.meaninertia = stat__meaninertia
|
_m.stat.meaninertia = stat__meaninertia
|
||||||
_m.taxel_sensorid = taxel_sensorid
|
_m.taxel_sensorid = taxel_sensorid
|
||||||
_m.taxel_vertadr = taxel_vertadr
|
_m.taxel_vertadr = taxel_vertadr
|
||||||
|
_m.ten_J_colind = ten_J_colind
|
||||||
|
_m.ten_J_rowadr = ten_J_rowadr
|
||||||
|
_m.ten_J_rownnz = ten_J_rownnz
|
||||||
_m.tendon_actfrclimited = tendon_actfrclimited
|
_m.tendon_actfrclimited = tendon_actfrclimited
|
||||||
_m.tendon_actfrcrange = tendon_actfrcrange
|
_m.tendon_actfrcrange = tendon_actfrcrange
|
||||||
_m.tendon_adr = tendon_adr
|
_m.tendon_adr = tendon_adr
|
||||||
@@ -842,6 +893,7 @@ def _forward_shim(
|
|||||||
_d.contact.dim = contact__dim
|
_d.contact.dim = contact__dim
|
||||||
_d.contact.dist = contact__dist
|
_d.contact.dist = contact__dist
|
||||||
_d.contact.efc_address = contact__efc_address
|
_d.contact.efc_address = contact__efc_address
|
||||||
|
_d.contact.flex = contact__flex
|
||||||
_d.contact.frame = contact__frame
|
_d.contact.frame = contact__frame
|
||||||
_d.contact.friction = contact__friction
|
_d.contact.friction = contact__friction
|
||||||
_d.contact.geom = contact__geom
|
_d.contact.geom = contact__geom
|
||||||
@@ -852,6 +904,7 @@ def _forward_shim(
|
|||||||
_d.contact.solref = contact__solref
|
_d.contact.solref = contact__solref
|
||||||
_d.contact.solreffriction = contact__solreffriction
|
_d.contact.solreffriction = contact__solreffriction
|
||||||
_d.contact.type = contact__type
|
_d.contact.type = contact__type
|
||||||
|
_d.contact.vert = contact__vert
|
||||||
_d.contact.worldid = contact__worldid
|
_d.contact.worldid = contact__worldid
|
||||||
_d.crb = crb
|
_d.crb = crb
|
||||||
_d.ctrl = ctrl
|
_d.ctrl = ctrl
|
||||||
@@ -895,6 +948,7 @@ def _forward_shim(
|
|||||||
_d.nf = nf
|
_d.nf = nf
|
||||||
_d.nisland = nisland
|
_d.nisland = nisland
|
||||||
_d.njmax = njmax
|
_d.njmax = njmax
|
||||||
|
_d.njmax_nnz = njmax_nnz
|
||||||
_d.nl = nl
|
_d.nl = nl
|
||||||
_d.qLD = qLD
|
_d.qLD = qLD
|
||||||
_d.qLDiagInv = qLDiagInv
|
_d.qLDiagInv = qLDiagInv
|
||||||
@@ -1018,6 +1072,7 @@ def _forward_jax_impl(m: types.Model, d: types.Data):
|
|||||||
'contact__dim': d._impl.contact__dim.shape,
|
'contact__dim': d._impl.contact__dim.shape,
|
||||||
'contact__dist': d._impl.contact__dist.shape,
|
'contact__dist': d._impl.contact__dist.shape,
|
||||||
'contact__efc_address': d._impl.contact__efc_address.shape,
|
'contact__efc_address': d._impl.contact__efc_address.shape,
|
||||||
|
'contact__flex': d._impl.contact__flex.shape,
|
||||||
'contact__frame': d._impl.contact__frame.shape,
|
'contact__frame': d._impl.contact__frame.shape,
|
||||||
'contact__friction': d._impl.contact__friction.shape,
|
'contact__friction': d._impl.contact__friction.shape,
|
||||||
'contact__geom': d._impl.contact__geom.shape,
|
'contact__geom': d._impl.contact__geom.shape,
|
||||||
@@ -1028,6 +1083,7 @@ def _forward_jax_impl(m: types.Model, d: types.Data):
|
|||||||
'contact__solref': d._impl.contact__solref.shape,
|
'contact__solref': d._impl.contact__solref.shape,
|
||||||
'contact__solreffriction': d._impl.contact__solreffriction.shape,
|
'contact__solreffriction': d._impl.contact__solreffriction.shape,
|
||||||
'contact__type': d._impl.contact__type.shape,
|
'contact__type': d._impl.contact__type.shape,
|
||||||
|
'contact__vert': d._impl.contact__vert.shape,
|
||||||
'contact__worldid': d._impl.contact__worldid.shape,
|
'contact__worldid': d._impl.contact__worldid.shape,
|
||||||
'efc__D': d._impl.efc__D.shape,
|
'efc__D': d._impl.efc__D.shape,
|
||||||
'efc__J': d._impl.efc__J.shape,
|
'efc__J': d._impl.efc__J.shape,
|
||||||
@@ -1047,7 +1103,7 @@ def _forward_jax_impl(m: types.Model, d: types.Data):
|
|||||||
}
|
}
|
||||||
jf = ffi.jax_callable_variadic_tuple(
|
jf = ffi.jax_callable_variadic_tuple(
|
||||||
_forward_shim,
|
_forward_shim,
|
||||||
num_outputs=100,
|
num_outputs=102,
|
||||||
output_dims=output_dims,
|
output_dims=output_dims,
|
||||||
vmap_method=None,
|
vmap_method=None,
|
||||||
in_out_argnames=set([
|
in_out_argnames=set([
|
||||||
@@ -1125,6 +1181,7 @@ def _forward_jax_impl(m: types.Model, d: types.Data):
|
|||||||
'contact__dim',
|
'contact__dim',
|
||||||
'contact__dist',
|
'contact__dist',
|
||||||
'contact__efc_address',
|
'contact__efc_address',
|
||||||
|
'contact__flex',
|
||||||
'contact__frame',
|
'contact__frame',
|
||||||
'contact__friction',
|
'contact__friction',
|
||||||
'contact__geom',
|
'contact__geom',
|
||||||
@@ -1135,6 +1192,7 @@ def _forward_jax_impl(m: types.Model, d: types.Data):
|
|||||||
'contact__solref',
|
'contact__solref',
|
||||||
'contact__solreffriction',
|
'contact__solreffriction',
|
||||||
'contact__type',
|
'contact__type',
|
||||||
|
'contact__vert',
|
||||||
'contact__worldid',
|
'contact__worldid',
|
||||||
'efc__D',
|
'efc__D',
|
||||||
'efc__J',
|
'efc__J',
|
||||||
@@ -1417,6 +1475,10 @@ def _forward_jax_impl(m: types.Model, d: types.Data):
|
|||||||
m.eq_type,
|
m.eq_type,
|
||||||
m._impl.eq_wld_adr,
|
m._impl.eq_wld_adr,
|
||||||
m._impl.flex_bending,
|
m._impl.flex_bending,
|
||||||
|
m._impl.flex_centered,
|
||||||
|
m._impl.flex_conaffinity,
|
||||||
|
m._impl.flex_condim,
|
||||||
|
m._impl.flex_contype,
|
||||||
m._impl.flex_damping,
|
m._impl.flex_damping,
|
||||||
m._impl.flex_dim,
|
m._impl.flex_dim,
|
||||||
m._impl.flex_edge,
|
m._impl.flex_edge,
|
||||||
@@ -1425,12 +1487,22 @@ def _forward_jax_impl(m: types.Model, d: types.Data):
|
|||||||
m._impl.flex_edgenum,
|
m._impl.flex_edgenum,
|
||||||
m._impl.flex_elem,
|
m._impl.flex_elem,
|
||||||
m._impl.flex_elemadr,
|
m._impl.flex_elemadr,
|
||||||
|
m._impl.flex_elemdataadr,
|
||||||
m._impl.flex_elemedge,
|
m._impl.flex_elemedge,
|
||||||
m._impl.flex_elemedgeadr,
|
m._impl.flex_elemedgeadr,
|
||||||
m._impl.flex_elemnum,
|
m._impl.flex_elemnum,
|
||||||
|
m._impl.flex_friction,
|
||||||
|
m._impl.flex_margin,
|
||||||
|
m._impl.flex_radius,
|
||||||
|
m._impl.flex_shell,
|
||||||
|
m._impl.flex_shelldataadr,
|
||||||
|
m._impl.flex_shellnum,
|
||||||
m._impl.flex_stiffness,
|
m._impl.flex_stiffness,
|
||||||
|
m._impl.flex_vert,
|
||||||
m._impl.flex_vertadr,
|
m._impl.flex_vertadr,
|
||||||
m._impl.flex_vertbodyid,
|
m._impl.flex_vertbodyid,
|
||||||
|
m._impl.flex_vertflexid,
|
||||||
|
m._impl.flex_vertnum,
|
||||||
m._impl.flexedge_J_colind,
|
m._impl.flexedge_J_colind,
|
||||||
m._impl.flexedge_J_rowadr,
|
m._impl.flexedge_J_rowadr,
|
||||||
m._impl.flexedge_J_rownnz,
|
m._impl.flexedge_J_rownnz,
|
||||||
@@ -1438,7 +1510,9 @@ def _forward_jax_impl(m: types.Model, d: types.Data):
|
|||||||
m._impl.flexedge_length0,
|
m._impl.flexedge_length0,
|
||||||
m.geom_aabb,
|
m.geom_aabb,
|
||||||
m.geom_bodyid,
|
m.geom_bodyid,
|
||||||
|
m.geom_conaffinity,
|
||||||
m.geom_condim,
|
m.geom_condim,
|
||||||
|
m.geom_contype,
|
||||||
m.geom_dataid,
|
m.geom_dataid,
|
||||||
m.geom_fluid,
|
m.geom_fluid,
|
||||||
m.geom_friction,
|
m.geom_friction,
|
||||||
@@ -1492,6 +1566,7 @@ def _forward_jax_impl(m: types.Model, d: types.Data):
|
|||||||
m._impl.light_targetbodyid,
|
m._impl.light_targetbodyid,
|
||||||
m._impl.mapM2M,
|
m._impl.mapM2M,
|
||||||
m.mat_rgba,
|
m.mat_rgba,
|
||||||
|
m._impl.max_ten_J_rownnz,
|
||||||
m.mesh_face,
|
m.mesh_face,
|
||||||
m.mesh_faceadr,
|
m.mesh_faceadr,
|
||||||
m.mesh_graph,
|
m.mesh_graph,
|
||||||
@@ -1514,6 +1589,7 @@ def _forward_jax_impl(m: types.Model, d: types.Data):
|
|||||||
m.mesh_vertadr,
|
m.mesh_vertadr,
|
||||||
m.mesh_vertnum,
|
m.mesh_vertnum,
|
||||||
m.nC,
|
m.nC,
|
||||||
|
m.nJten,
|
||||||
m.na,
|
m.na,
|
||||||
m._impl.nacttrnbody,
|
m._impl.nacttrnbody,
|
||||||
m.nbody,
|
m.nbody,
|
||||||
@@ -1523,6 +1599,7 @@ def _forward_jax_impl(m: types.Model, d: types.Data):
|
|||||||
m._impl.nflex,
|
m._impl.nflex,
|
||||||
m._impl.nflexedge,
|
m._impl.nflexedge,
|
||||||
m._impl.nflexelem,
|
m._impl.nflexelem,
|
||||||
|
m._impl.nflexshelldata,
|
||||||
m._impl.nflexvert,
|
m._impl.nflexvert,
|
||||||
m.ngeom,
|
m.ngeom,
|
||||||
m.ngravcomp,
|
m.ngravcomp,
|
||||||
@@ -1559,6 +1636,8 @@ def _forward_jax_impl(m: types.Model, d: types.Data):
|
|||||||
m.pair_solreffriction,
|
m.pair_solreffriction,
|
||||||
m._impl.plugin,
|
m._impl.plugin,
|
||||||
m._impl.plugin_attr,
|
m._impl.plugin_attr,
|
||||||
|
m._impl.qLD_all_updates,
|
||||||
|
m._impl.qLD_level_offsets,
|
||||||
m._impl.qLD_updates,
|
m._impl.qLD_updates,
|
||||||
m._impl.qM_fullm_i,
|
m._impl.qM_fullm_i,
|
||||||
m._impl.qM_fullm_j,
|
m._impl.qM_fullm_j,
|
||||||
@@ -1602,6 +1681,9 @@ def _forward_jax_impl(m: types.Model, d: types.Data):
|
|||||||
m.site_type,
|
m.site_type,
|
||||||
m._impl.taxel_sensorid,
|
m._impl.taxel_sensorid,
|
||||||
m._impl.taxel_vertadr,
|
m._impl.taxel_vertadr,
|
||||||
|
m._impl.ten_J_colind,
|
||||||
|
m._impl.ten_J_rowadr,
|
||||||
|
m._impl.ten_J_rownnz,
|
||||||
m.tendon_actfrclimited,
|
m.tendon_actfrclimited,
|
||||||
m.tendon_actfrcrange,
|
m.tendon_actfrcrange,
|
||||||
m.tendon_adr,
|
m.tendon_adr,
|
||||||
@@ -1660,6 +1742,7 @@ def _forward_jax_impl(m: types.Model, d: types.Data):
|
|||||||
d._impl.naccdmax,
|
d._impl.naccdmax,
|
||||||
d._impl.naconmax,
|
d._impl.naconmax,
|
||||||
d._impl.njmax,
|
d._impl.njmax,
|
||||||
|
d._impl.njmax_nnz,
|
||||||
d.act,
|
d.act,
|
||||||
d.act_dot,
|
d.act_dot,
|
||||||
d.actuator_force,
|
d.actuator_force,
|
||||||
@@ -1744,6 +1827,7 @@ def _forward_jax_impl(m: types.Model, d: types.Data):
|
|||||||
d._impl.contact__dim,
|
d._impl.contact__dim,
|
||||||
d._impl.contact__dist,
|
d._impl.contact__dist,
|
||||||
d._impl.contact__efc_address,
|
d._impl.contact__efc_address,
|
||||||
|
d._impl.contact__flex,
|
||||||
d._impl.contact__frame,
|
d._impl.contact__frame,
|
||||||
d._impl.contact__friction,
|
d._impl.contact__friction,
|
||||||
d._impl.contact__geom,
|
d._impl.contact__geom,
|
||||||
@@ -1754,6 +1838,7 @@ def _forward_jax_impl(m: types.Model, d: types.Data):
|
|||||||
d._impl.contact__solref,
|
d._impl.contact__solref,
|
||||||
d._impl.contact__solreffriction,
|
d._impl.contact__solreffriction,
|
||||||
d._impl.contact__type,
|
d._impl.contact__type,
|
||||||
|
d._impl.contact__vert,
|
||||||
d._impl.contact__worldid,
|
d._impl.contact__worldid,
|
||||||
d._impl.efc__D,
|
d._impl.efc__D,
|
||||||
d._impl.efc__J,
|
d._impl.efc__J,
|
||||||
@@ -1846,32 +1931,34 @@ def _forward_jax_impl(m: types.Model, d: types.Data):
|
|||||||
'_impl.contact__dim': out[71],
|
'_impl.contact__dim': out[71],
|
||||||
'_impl.contact__dist': out[72],
|
'_impl.contact__dist': out[72],
|
||||||
'_impl.contact__efc_address': out[73],
|
'_impl.contact__efc_address': out[73],
|
||||||
'_impl.contact__frame': out[74],
|
'_impl.contact__flex': out[74],
|
||||||
'_impl.contact__friction': out[75],
|
'_impl.contact__frame': out[75],
|
||||||
'_impl.contact__geom': out[76],
|
'_impl.contact__friction': out[76],
|
||||||
'_impl.contact__geomcollisionid': out[77],
|
'_impl.contact__geom': out[77],
|
||||||
'_impl.contact__includemargin': out[78],
|
'_impl.contact__geomcollisionid': out[78],
|
||||||
'_impl.contact__pos': out[79],
|
'_impl.contact__includemargin': out[79],
|
||||||
'_impl.contact__solimp': out[80],
|
'_impl.contact__pos': out[80],
|
||||||
'_impl.contact__solref': out[81],
|
'_impl.contact__solimp': out[81],
|
||||||
'_impl.contact__solreffriction': out[82],
|
'_impl.contact__solref': out[82],
|
||||||
'_impl.contact__type': out[83],
|
'_impl.contact__solreffriction': out[83],
|
||||||
'_impl.contact__worldid': out[84],
|
'_impl.contact__type': out[84],
|
||||||
'_impl.efc__D': out[85],
|
'_impl.contact__vert': out[85],
|
||||||
'_impl.efc__J': out[86],
|
'_impl.contact__worldid': out[86],
|
||||||
'_impl.efc__J_colind': out[87],
|
'_impl.efc__D': out[87],
|
||||||
'_impl.efc__J_rowadr': out[88],
|
'_impl.efc__J': out[88],
|
||||||
'_impl.efc__J_rownnz': out[89],
|
'_impl.efc__J_colind': out[89],
|
||||||
'_impl.efc__Ma': out[90],
|
'_impl.efc__J_rowadr': out[90],
|
||||||
'_impl.efc__aref': out[91],
|
'_impl.efc__J_rownnz': out[91],
|
||||||
'_impl.efc__force': out[92],
|
'_impl.efc__Ma': out[92],
|
||||||
'_impl.efc__frictionloss': out[93],
|
'_impl.efc__aref': out[93],
|
||||||
'_impl.efc__id': out[94],
|
'_impl.efc__force': out[94],
|
||||||
'_impl.efc__margin': out[95],
|
'_impl.efc__frictionloss': out[95],
|
||||||
'_impl.efc__pos': out[96],
|
'_impl.efc__id': out[96],
|
||||||
'_impl.efc__state': out[97],
|
'_impl.efc__margin': out[97],
|
||||||
'_impl.efc__type': out[98],
|
'_impl.efc__pos': out[98],
|
||||||
'_impl.efc__vel': out[99],
|
'_impl.efc__state': out[99],
|
||||||
|
'_impl.efc__type': out[100],
|
||||||
|
'_impl.efc__vel': out[101],
|
||||||
})
|
})
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@@ -1980,6 +2067,10 @@ def _step_shim(
|
|||||||
eq_type: wp.array(dtype=int),
|
eq_type: wp.array(dtype=int),
|
||||||
eq_wld_adr: wp.array(dtype=int),
|
eq_wld_adr: wp.array(dtype=int),
|
||||||
flex_bending: wp.array2d(dtype=float),
|
flex_bending: wp.array2d(dtype=float),
|
||||||
|
flex_centered: wp.array(dtype=bool),
|
||||||
|
flex_conaffinity: wp.array(dtype=int),
|
||||||
|
flex_condim: wp.array(dtype=int),
|
||||||
|
flex_contype: wp.array(dtype=int),
|
||||||
flex_damping: wp.array(dtype=float),
|
flex_damping: wp.array(dtype=float),
|
||||||
flex_dim: wp.array(dtype=int),
|
flex_dim: wp.array(dtype=int),
|
||||||
flex_edge: wp.array(dtype=wp.vec2i),
|
flex_edge: wp.array(dtype=wp.vec2i),
|
||||||
@@ -1988,12 +2079,22 @@ def _step_shim(
|
|||||||
flex_edgenum: wp.array(dtype=int),
|
flex_edgenum: wp.array(dtype=int),
|
||||||
flex_elem: wp.array(dtype=int),
|
flex_elem: wp.array(dtype=int),
|
||||||
flex_elemadr: wp.array(dtype=int),
|
flex_elemadr: wp.array(dtype=int),
|
||||||
|
flex_elemdataadr: wp.array(dtype=int),
|
||||||
flex_elemedge: wp.array(dtype=int),
|
flex_elemedge: wp.array(dtype=int),
|
||||||
flex_elemedgeadr: wp.array(dtype=int),
|
flex_elemedgeadr: wp.array(dtype=int),
|
||||||
flex_elemnum: wp.array(dtype=int),
|
flex_elemnum: wp.array(dtype=int),
|
||||||
|
flex_friction: wp.array(dtype=wp.vec3),
|
||||||
|
flex_margin: wp.array(dtype=float),
|
||||||
|
flex_radius: wp.array(dtype=float),
|
||||||
|
flex_shell: wp.array(dtype=int),
|
||||||
|
flex_shelldataadr: wp.array(dtype=int),
|
||||||
|
flex_shellnum: wp.array(dtype=int),
|
||||||
flex_stiffness: wp.array2d(dtype=float),
|
flex_stiffness: wp.array2d(dtype=float),
|
||||||
|
flex_vert: wp.array(dtype=wp.vec3),
|
||||||
flex_vertadr: wp.array(dtype=int),
|
flex_vertadr: wp.array(dtype=int),
|
||||||
flex_vertbodyid: wp.array(dtype=int),
|
flex_vertbodyid: wp.array(dtype=int),
|
||||||
|
flex_vertflexid: wp.array(dtype=int),
|
||||||
|
flex_vertnum: wp.array(dtype=int),
|
||||||
flexedge_J_colind: wp.array(dtype=int),
|
flexedge_J_colind: wp.array(dtype=int),
|
||||||
flexedge_J_rowadr: wp.array(dtype=int),
|
flexedge_J_rowadr: wp.array(dtype=int),
|
||||||
flexedge_J_rownnz: wp.array(dtype=int),
|
flexedge_J_rownnz: wp.array(dtype=int),
|
||||||
@@ -2001,7 +2102,9 @@ def _step_shim(
|
|||||||
flexedge_length0: wp.array(dtype=float),
|
flexedge_length0: wp.array(dtype=float),
|
||||||
geom_aabb: wp.array3d(dtype=wp.vec3),
|
geom_aabb: wp.array3d(dtype=wp.vec3),
|
||||||
geom_bodyid: wp.array(dtype=int),
|
geom_bodyid: wp.array(dtype=int),
|
||||||
|
geom_conaffinity: wp.array(dtype=int),
|
||||||
geom_condim: wp.array(dtype=int),
|
geom_condim: wp.array(dtype=int),
|
||||||
|
geom_contype: wp.array(dtype=int),
|
||||||
geom_dataid: wp.array(dtype=int),
|
geom_dataid: wp.array(dtype=int),
|
||||||
geom_fluid: wp.array2d(dtype=float),
|
geom_fluid: wp.array2d(dtype=float),
|
||||||
geom_friction: wp.array2d(dtype=wp.vec3),
|
geom_friction: wp.array2d(dtype=wp.vec3),
|
||||||
@@ -2055,6 +2158,7 @@ def _step_shim(
|
|||||||
light_targetbodyid: wp.array(dtype=int),
|
light_targetbodyid: wp.array(dtype=int),
|
||||||
mapM2M: wp.array(dtype=int),
|
mapM2M: wp.array(dtype=int),
|
||||||
mat_rgba: wp.array2d(dtype=wp.vec4),
|
mat_rgba: wp.array2d(dtype=wp.vec4),
|
||||||
|
max_ten_J_rownnz: int,
|
||||||
mesh_face: wp.array(dtype=wp.vec3i),
|
mesh_face: wp.array(dtype=wp.vec3i),
|
||||||
mesh_faceadr: wp.array(dtype=int),
|
mesh_faceadr: wp.array(dtype=int),
|
||||||
mesh_graph: wp.array(dtype=int),
|
mesh_graph: wp.array(dtype=int),
|
||||||
@@ -2077,6 +2181,7 @@ def _step_shim(
|
|||||||
mesh_vertadr: wp.array(dtype=int),
|
mesh_vertadr: wp.array(dtype=int),
|
||||||
mesh_vertnum: wp.array(dtype=int),
|
mesh_vertnum: wp.array(dtype=int),
|
||||||
nC: int,
|
nC: int,
|
||||||
|
nJten: int,
|
||||||
nM: int,
|
nM: int,
|
||||||
na: int,
|
na: int,
|
||||||
nacttrnbody: int,
|
nacttrnbody: int,
|
||||||
@@ -2087,6 +2192,7 @@ def _step_shim(
|
|||||||
nflex: int,
|
nflex: int,
|
||||||
nflexedge: int,
|
nflexedge: int,
|
||||||
nflexelem: int,
|
nflexelem: int,
|
||||||
|
nflexshelldata: int,
|
||||||
nflexvert: int,
|
nflexvert: int,
|
||||||
ngeom: int,
|
ngeom: int,
|
||||||
ngravcomp: int,
|
ngravcomp: int,
|
||||||
@@ -2122,7 +2228,9 @@ def _step_shim(
|
|||||||
pair_solref: wp.array2d(dtype=wp.vec2),
|
pair_solref: wp.array2d(dtype=wp.vec2),
|
||||||
pair_solreffriction: wp.array2d(dtype=wp.vec2),
|
pair_solreffriction: wp.array2d(dtype=wp.vec2),
|
||||||
plugin: wp.array(dtype=int),
|
plugin: wp.array(dtype=int),
|
||||||
plugin_attr: wp.array(dtype=wp.vec3f),
|
plugin_attr: wp.array(dtype=mjwp_types.vec_pluginattr),
|
||||||
|
qLD_all_updates: wp.array(dtype=wp.vec3i),
|
||||||
|
qLD_level_offsets: wp.array(dtype=int),
|
||||||
qLD_updates: tuple[wp.array(dtype=wp.vec3i), ...],
|
qLD_updates: tuple[wp.array(dtype=wp.vec3i), ...],
|
||||||
qM_fullm_i: wp.array(dtype=int),
|
qM_fullm_i: wp.array(dtype=int),
|
||||||
qM_fullm_j: wp.array(dtype=int),
|
qM_fullm_j: wp.array(dtype=int),
|
||||||
@@ -2166,6 +2274,9 @@ def _step_shim(
|
|||||||
site_type: wp.array(dtype=int),
|
site_type: wp.array(dtype=int),
|
||||||
taxel_sensorid: wp.array(dtype=int),
|
taxel_sensorid: wp.array(dtype=int),
|
||||||
taxel_vertadr: wp.array(dtype=int),
|
taxel_vertadr: wp.array(dtype=int),
|
||||||
|
ten_J_colind: wp.array(dtype=int),
|
||||||
|
ten_J_rowadr: wp.array(dtype=int),
|
||||||
|
ten_J_rownnz: wp.array(dtype=int),
|
||||||
tendon_actfrclimited: wp.array(dtype=bool),
|
tendon_actfrclimited: wp.array(dtype=bool),
|
||||||
tendon_actfrcrange: wp.array2d(dtype=wp.vec2),
|
tendon_actfrcrange: wp.array2d(dtype=wp.vec2),
|
||||||
tendon_adr: wp.array(dtype=int),
|
tendon_adr: wp.array(dtype=int),
|
||||||
@@ -2226,6 +2337,7 @@ def _step_shim(
|
|||||||
naccdmax: int,
|
naccdmax: int,
|
||||||
naconmax: int,
|
naconmax: int,
|
||||||
njmax: int,
|
njmax: int,
|
||||||
|
njmax_nnz: int,
|
||||||
act: wp.array2d(dtype=float),
|
act: wp.array2d(dtype=float),
|
||||||
act_dot: wp.array2d(dtype=float),
|
act_dot: wp.array2d(dtype=float),
|
||||||
actuator_force: wp.array2d(dtype=float),
|
actuator_force: wp.array2d(dtype=float),
|
||||||
@@ -2290,7 +2402,7 @@ def _step_shim(
|
|||||||
subtree_angmom: wp.array2d(dtype=wp.vec3),
|
subtree_angmom: wp.array2d(dtype=wp.vec3),
|
||||||
subtree_com: wp.array2d(dtype=wp.vec3),
|
subtree_com: wp.array2d(dtype=wp.vec3),
|
||||||
subtree_linvel: wp.array2d(dtype=wp.vec3),
|
subtree_linvel: wp.array2d(dtype=wp.vec3),
|
||||||
ten_J: wp.array3d(dtype=float),
|
ten_J: wp.array2d(dtype=float),
|
||||||
ten_length: wp.array2d(dtype=float),
|
ten_length: wp.array2d(dtype=float),
|
||||||
ten_velocity: wp.array2d(dtype=float),
|
ten_velocity: wp.array2d(dtype=float),
|
||||||
ten_wrapadr: wp.array2d(dtype=int),
|
ten_wrapadr: wp.array2d(dtype=int),
|
||||||
@@ -2310,6 +2422,7 @@ def _step_shim(
|
|||||||
contact__dim: wp.array(dtype=int),
|
contact__dim: wp.array(dtype=int),
|
||||||
contact__dist: wp.array(dtype=float),
|
contact__dist: wp.array(dtype=float),
|
||||||
contact__efc_address: wp.array2d(dtype=int),
|
contact__efc_address: wp.array2d(dtype=int),
|
||||||
|
contact__flex: wp.array(dtype=wp.vec2i),
|
||||||
contact__frame: wp.array(dtype=wp.mat33),
|
contact__frame: wp.array(dtype=wp.mat33),
|
||||||
contact__friction: wp.array(dtype=mjwp_types.vec5),
|
contact__friction: wp.array(dtype=mjwp_types.vec5),
|
||||||
contact__geom: wp.array(dtype=wp.vec2i),
|
contact__geom: wp.array(dtype=wp.vec2i),
|
||||||
@@ -2320,6 +2433,7 @@ def _step_shim(
|
|||||||
contact__solref: wp.array(dtype=wp.vec2),
|
contact__solref: wp.array(dtype=wp.vec2),
|
||||||
contact__solreffriction: wp.array(dtype=wp.vec2),
|
contact__solreffriction: wp.array(dtype=wp.vec2),
|
||||||
contact__type: wp.array(dtype=int),
|
contact__type: wp.array(dtype=int),
|
||||||
|
contact__vert: wp.array(dtype=wp.vec2i),
|
||||||
contact__worldid: wp.array(dtype=int),
|
contact__worldid: wp.array(dtype=int),
|
||||||
efc__D: wp.array2d(dtype=float),
|
efc__D: wp.array2d(dtype=float),
|
||||||
efc__J: wp.array3d(dtype=float),
|
efc__J: wp.array3d(dtype=float),
|
||||||
@@ -2429,6 +2543,10 @@ def _step_shim(
|
|||||||
_m.eq_type = eq_type
|
_m.eq_type = eq_type
|
||||||
_m.eq_wld_adr = eq_wld_adr
|
_m.eq_wld_adr = eq_wld_adr
|
||||||
_m.flex_bending = flex_bending
|
_m.flex_bending = flex_bending
|
||||||
|
_m.flex_centered = flex_centered
|
||||||
|
_m.flex_conaffinity = flex_conaffinity
|
||||||
|
_m.flex_condim = flex_condim
|
||||||
|
_m.flex_contype = flex_contype
|
||||||
_m.flex_damping = flex_damping
|
_m.flex_damping = flex_damping
|
||||||
_m.flex_dim = flex_dim
|
_m.flex_dim = flex_dim
|
||||||
_m.flex_edge = flex_edge
|
_m.flex_edge = flex_edge
|
||||||
@@ -2437,12 +2555,22 @@ def _step_shim(
|
|||||||
_m.flex_edgenum = flex_edgenum
|
_m.flex_edgenum = flex_edgenum
|
||||||
_m.flex_elem = flex_elem
|
_m.flex_elem = flex_elem
|
||||||
_m.flex_elemadr = flex_elemadr
|
_m.flex_elemadr = flex_elemadr
|
||||||
|
_m.flex_elemdataadr = flex_elemdataadr
|
||||||
_m.flex_elemedge = flex_elemedge
|
_m.flex_elemedge = flex_elemedge
|
||||||
_m.flex_elemedgeadr = flex_elemedgeadr
|
_m.flex_elemedgeadr = flex_elemedgeadr
|
||||||
_m.flex_elemnum = flex_elemnum
|
_m.flex_elemnum = flex_elemnum
|
||||||
|
_m.flex_friction = flex_friction
|
||||||
|
_m.flex_margin = flex_margin
|
||||||
|
_m.flex_radius = flex_radius
|
||||||
|
_m.flex_shell = flex_shell
|
||||||
|
_m.flex_shelldataadr = flex_shelldataadr
|
||||||
|
_m.flex_shellnum = flex_shellnum
|
||||||
_m.flex_stiffness = flex_stiffness
|
_m.flex_stiffness = flex_stiffness
|
||||||
|
_m.flex_vert = flex_vert
|
||||||
_m.flex_vertadr = flex_vertadr
|
_m.flex_vertadr = flex_vertadr
|
||||||
_m.flex_vertbodyid = flex_vertbodyid
|
_m.flex_vertbodyid = flex_vertbodyid
|
||||||
|
_m.flex_vertflexid = flex_vertflexid
|
||||||
|
_m.flex_vertnum = flex_vertnum
|
||||||
_m.flexedge_J_colind = flexedge_J_colind
|
_m.flexedge_J_colind = flexedge_J_colind
|
||||||
_m.flexedge_J_rowadr = flexedge_J_rowadr
|
_m.flexedge_J_rowadr = flexedge_J_rowadr
|
||||||
_m.flexedge_J_rownnz = flexedge_J_rownnz
|
_m.flexedge_J_rownnz = flexedge_J_rownnz
|
||||||
@@ -2450,7 +2578,9 @@ def _step_shim(
|
|||||||
_m.flexedge_length0 = flexedge_length0
|
_m.flexedge_length0 = flexedge_length0
|
||||||
_m.geom_aabb = geom_aabb
|
_m.geom_aabb = geom_aabb
|
||||||
_m.geom_bodyid = geom_bodyid
|
_m.geom_bodyid = geom_bodyid
|
||||||
|
_m.geom_conaffinity = geom_conaffinity
|
||||||
_m.geom_condim = geom_condim
|
_m.geom_condim = geom_condim
|
||||||
|
_m.geom_contype = geom_contype
|
||||||
_m.geom_dataid = geom_dataid
|
_m.geom_dataid = geom_dataid
|
||||||
_m.geom_fluid = geom_fluid
|
_m.geom_fluid = geom_fluid
|
||||||
_m.geom_friction = geom_friction
|
_m.geom_friction = geom_friction
|
||||||
@@ -2504,6 +2634,7 @@ def _step_shim(
|
|||||||
_m.light_targetbodyid = light_targetbodyid
|
_m.light_targetbodyid = light_targetbodyid
|
||||||
_m.mapM2M = mapM2M
|
_m.mapM2M = mapM2M
|
||||||
_m.mat_rgba = mat_rgba
|
_m.mat_rgba = mat_rgba
|
||||||
|
_m.max_ten_J_rownnz = max_ten_J_rownnz
|
||||||
_m.mesh_face = mesh_face
|
_m.mesh_face = mesh_face
|
||||||
_m.mesh_faceadr = mesh_faceadr
|
_m.mesh_faceadr = mesh_faceadr
|
||||||
_m.mesh_graph = mesh_graph
|
_m.mesh_graph = mesh_graph
|
||||||
@@ -2526,6 +2657,7 @@ def _step_shim(
|
|||||||
_m.mesh_vertadr = mesh_vertadr
|
_m.mesh_vertadr = mesh_vertadr
|
||||||
_m.mesh_vertnum = mesh_vertnum
|
_m.mesh_vertnum = mesh_vertnum
|
||||||
_m.nC = nC
|
_m.nC = nC
|
||||||
|
_m.nJten = nJten
|
||||||
_m.nM = nM
|
_m.nM = nM
|
||||||
_m.na = na
|
_m.na = na
|
||||||
_m.nacttrnbody = nacttrnbody
|
_m.nacttrnbody = nacttrnbody
|
||||||
@@ -2536,6 +2668,7 @@ def _step_shim(
|
|||||||
_m.nflex = nflex
|
_m.nflex = nflex
|
||||||
_m.nflexedge = nflexedge
|
_m.nflexedge = nflexedge
|
||||||
_m.nflexelem = nflexelem
|
_m.nflexelem = nflexelem
|
||||||
|
_m.nflexshelldata = nflexshelldata
|
||||||
_m.nflexvert = nflexvert
|
_m.nflexvert = nflexvert
|
||||||
_m.ngeom = ngeom
|
_m.ngeom = ngeom
|
||||||
_m.ngravcomp = ngravcomp
|
_m.ngravcomp = ngravcomp
|
||||||
@@ -2599,6 +2732,8 @@ def _step_shim(
|
|||||||
_m.pair_solreffriction = pair_solreffriction
|
_m.pair_solreffriction = pair_solreffriction
|
||||||
_m.plugin = plugin
|
_m.plugin = plugin
|
||||||
_m.plugin_attr = plugin_attr
|
_m.plugin_attr = plugin_attr
|
||||||
|
_m.qLD_all_updates = qLD_all_updates
|
||||||
|
_m.qLD_level_offsets = qLD_level_offsets
|
||||||
_m.qLD_updates = qLD_updates
|
_m.qLD_updates = qLD_updates
|
||||||
_m.qM_fullm_i = qM_fullm_i
|
_m.qM_fullm_i = qM_fullm_i
|
||||||
_m.qM_fullm_j = qM_fullm_j
|
_m.qM_fullm_j = qM_fullm_j
|
||||||
@@ -2643,6 +2778,9 @@ def _step_shim(
|
|||||||
_m.stat.meaninertia = stat__meaninertia
|
_m.stat.meaninertia = stat__meaninertia
|
||||||
_m.taxel_sensorid = taxel_sensorid
|
_m.taxel_sensorid = taxel_sensorid
|
||||||
_m.taxel_vertadr = taxel_vertadr
|
_m.taxel_vertadr = taxel_vertadr
|
||||||
|
_m.ten_J_colind = ten_J_colind
|
||||||
|
_m.ten_J_rowadr = ten_J_rowadr
|
||||||
|
_m.ten_J_rownnz = ten_J_rownnz
|
||||||
_m.tendon_actfrclimited = tendon_actfrclimited
|
_m.tendon_actfrclimited = tendon_actfrclimited
|
||||||
_m.tendon_actfrcrange = tendon_actfrcrange
|
_m.tendon_actfrcrange = tendon_actfrcrange
|
||||||
_m.tendon_adr = tendon_adr
|
_m.tendon_adr = tendon_adr
|
||||||
@@ -2688,6 +2826,7 @@ def _step_shim(
|
|||||||
_d.contact.dim = contact__dim
|
_d.contact.dim = contact__dim
|
||||||
_d.contact.dist = contact__dist
|
_d.contact.dist = contact__dist
|
||||||
_d.contact.efc_address = contact__efc_address
|
_d.contact.efc_address = contact__efc_address
|
||||||
|
_d.contact.flex = contact__flex
|
||||||
_d.contact.frame = contact__frame
|
_d.contact.frame = contact__frame
|
||||||
_d.contact.friction = contact__friction
|
_d.contact.friction = contact__friction
|
||||||
_d.contact.geom = contact__geom
|
_d.contact.geom = contact__geom
|
||||||
@@ -2698,6 +2837,7 @@ def _step_shim(
|
|||||||
_d.contact.solref = contact__solref
|
_d.contact.solref = contact__solref
|
||||||
_d.contact.solreffriction = contact__solreffriction
|
_d.contact.solreffriction = contact__solreffriction
|
||||||
_d.contact.type = contact__type
|
_d.contact.type = contact__type
|
||||||
|
_d.contact.vert = contact__vert
|
||||||
_d.contact.worldid = contact__worldid
|
_d.contact.worldid = contact__worldid
|
||||||
_d.crb = crb
|
_d.crb = crb
|
||||||
_d.ctrl = ctrl
|
_d.ctrl = ctrl
|
||||||
@@ -2741,6 +2881,7 @@ def _step_shim(
|
|||||||
_d.nf = nf
|
_d.nf = nf
|
||||||
_d.nisland = nisland
|
_d.nisland = nisland
|
||||||
_d.njmax = njmax
|
_d.njmax = njmax
|
||||||
|
_d.njmax_nnz = njmax_nnz
|
||||||
_d.nl = nl
|
_d.nl = nl
|
||||||
_d.qLD = qLD
|
_d.qLD = qLD
|
||||||
_d.qLDiagInv = qLDiagInv
|
_d.qLDiagInv = qLDiagInv
|
||||||
@@ -2868,6 +3009,7 @@ def _step_jax_impl(m: types.Model, d: types.Data):
|
|||||||
'contact__dim': d._impl.contact__dim.shape,
|
'contact__dim': d._impl.contact__dim.shape,
|
||||||
'contact__dist': d._impl.contact__dist.shape,
|
'contact__dist': d._impl.contact__dist.shape,
|
||||||
'contact__efc_address': d._impl.contact__efc_address.shape,
|
'contact__efc_address': d._impl.contact__efc_address.shape,
|
||||||
|
'contact__flex': d._impl.contact__flex.shape,
|
||||||
'contact__frame': d._impl.contact__frame.shape,
|
'contact__frame': d._impl.contact__frame.shape,
|
||||||
'contact__friction': d._impl.contact__friction.shape,
|
'contact__friction': d._impl.contact__friction.shape,
|
||||||
'contact__geom': d._impl.contact__geom.shape,
|
'contact__geom': d._impl.contact__geom.shape,
|
||||||
@@ -2878,6 +3020,7 @@ def _step_jax_impl(m: types.Model, d: types.Data):
|
|||||||
'contact__solref': d._impl.contact__solref.shape,
|
'contact__solref': d._impl.contact__solref.shape,
|
||||||
'contact__solreffriction': d._impl.contact__solreffriction.shape,
|
'contact__solreffriction': d._impl.contact__solreffriction.shape,
|
||||||
'contact__type': d._impl.contact__type.shape,
|
'contact__type': d._impl.contact__type.shape,
|
||||||
|
'contact__vert': d._impl.contact__vert.shape,
|
||||||
'contact__worldid': d._impl.contact__worldid.shape,
|
'contact__worldid': d._impl.contact__worldid.shape,
|
||||||
'efc__D': d._impl.efc__D.shape,
|
'efc__D': d._impl.efc__D.shape,
|
||||||
'efc__J': d._impl.efc__J.shape,
|
'efc__J': d._impl.efc__J.shape,
|
||||||
@@ -2897,7 +3040,7 @@ def _step_jax_impl(m: types.Model, d: types.Data):
|
|||||||
}
|
}
|
||||||
jf = ffi.jax_callable_variadic_tuple(
|
jf = ffi.jax_callable_variadic_tuple(
|
||||||
_step_shim,
|
_step_shim,
|
||||||
num_outputs=104,
|
num_outputs=106,
|
||||||
output_dims=output_dims,
|
output_dims=output_dims,
|
||||||
vmap_method=None,
|
vmap_method=None,
|
||||||
in_out_argnames=set([
|
in_out_argnames=set([
|
||||||
@@ -2979,6 +3122,7 @@ def _step_jax_impl(m: types.Model, d: types.Data):
|
|||||||
'contact__dim',
|
'contact__dim',
|
||||||
'contact__dist',
|
'contact__dist',
|
||||||
'contact__efc_address',
|
'contact__efc_address',
|
||||||
|
'contact__flex',
|
||||||
'contact__frame',
|
'contact__frame',
|
||||||
'contact__friction',
|
'contact__friction',
|
||||||
'contact__geom',
|
'contact__geom',
|
||||||
@@ -2989,6 +3133,7 @@ def _step_jax_impl(m: types.Model, d: types.Data):
|
|||||||
'contact__solref',
|
'contact__solref',
|
||||||
'contact__solreffriction',
|
'contact__solreffriction',
|
||||||
'contact__type',
|
'contact__type',
|
||||||
|
'contact__vert',
|
||||||
'contact__worldid',
|
'contact__worldid',
|
||||||
'efc__D',
|
'efc__D',
|
||||||
'efc__J',
|
'efc__J',
|
||||||
@@ -3275,6 +3420,10 @@ def _step_jax_impl(m: types.Model, d: types.Data):
|
|||||||
m.eq_type,
|
m.eq_type,
|
||||||
m._impl.eq_wld_adr,
|
m._impl.eq_wld_adr,
|
||||||
m._impl.flex_bending,
|
m._impl.flex_bending,
|
||||||
|
m._impl.flex_centered,
|
||||||
|
m._impl.flex_conaffinity,
|
||||||
|
m._impl.flex_condim,
|
||||||
|
m._impl.flex_contype,
|
||||||
m._impl.flex_damping,
|
m._impl.flex_damping,
|
||||||
m._impl.flex_dim,
|
m._impl.flex_dim,
|
||||||
m._impl.flex_edge,
|
m._impl.flex_edge,
|
||||||
@@ -3283,12 +3432,22 @@ def _step_jax_impl(m: types.Model, d: types.Data):
|
|||||||
m._impl.flex_edgenum,
|
m._impl.flex_edgenum,
|
||||||
m._impl.flex_elem,
|
m._impl.flex_elem,
|
||||||
m._impl.flex_elemadr,
|
m._impl.flex_elemadr,
|
||||||
|
m._impl.flex_elemdataadr,
|
||||||
m._impl.flex_elemedge,
|
m._impl.flex_elemedge,
|
||||||
m._impl.flex_elemedgeadr,
|
m._impl.flex_elemedgeadr,
|
||||||
m._impl.flex_elemnum,
|
m._impl.flex_elemnum,
|
||||||
|
m._impl.flex_friction,
|
||||||
|
m._impl.flex_margin,
|
||||||
|
m._impl.flex_radius,
|
||||||
|
m._impl.flex_shell,
|
||||||
|
m._impl.flex_shelldataadr,
|
||||||
|
m._impl.flex_shellnum,
|
||||||
m._impl.flex_stiffness,
|
m._impl.flex_stiffness,
|
||||||
|
m._impl.flex_vert,
|
||||||
m._impl.flex_vertadr,
|
m._impl.flex_vertadr,
|
||||||
m._impl.flex_vertbodyid,
|
m._impl.flex_vertbodyid,
|
||||||
|
m._impl.flex_vertflexid,
|
||||||
|
m._impl.flex_vertnum,
|
||||||
m._impl.flexedge_J_colind,
|
m._impl.flexedge_J_colind,
|
||||||
m._impl.flexedge_J_rowadr,
|
m._impl.flexedge_J_rowadr,
|
||||||
m._impl.flexedge_J_rownnz,
|
m._impl.flexedge_J_rownnz,
|
||||||
@@ -3296,7 +3455,9 @@ def _step_jax_impl(m: types.Model, d: types.Data):
|
|||||||
m._impl.flexedge_length0,
|
m._impl.flexedge_length0,
|
||||||
m.geom_aabb,
|
m.geom_aabb,
|
||||||
m.geom_bodyid,
|
m.geom_bodyid,
|
||||||
|
m.geom_conaffinity,
|
||||||
m.geom_condim,
|
m.geom_condim,
|
||||||
|
m.geom_contype,
|
||||||
m.geom_dataid,
|
m.geom_dataid,
|
||||||
m.geom_fluid,
|
m.geom_fluid,
|
||||||
m.geom_friction,
|
m.geom_friction,
|
||||||
@@ -3350,6 +3511,7 @@ def _step_jax_impl(m: types.Model, d: types.Data):
|
|||||||
m._impl.light_targetbodyid,
|
m._impl.light_targetbodyid,
|
||||||
m._impl.mapM2M,
|
m._impl.mapM2M,
|
||||||
m.mat_rgba,
|
m.mat_rgba,
|
||||||
|
m._impl.max_ten_J_rownnz,
|
||||||
m.mesh_face,
|
m.mesh_face,
|
||||||
m.mesh_faceadr,
|
m.mesh_faceadr,
|
||||||
m.mesh_graph,
|
m.mesh_graph,
|
||||||
@@ -3372,6 +3534,7 @@ def _step_jax_impl(m: types.Model, d: types.Data):
|
|||||||
m.mesh_vertadr,
|
m.mesh_vertadr,
|
||||||
m.mesh_vertnum,
|
m.mesh_vertnum,
|
||||||
m.nC,
|
m.nC,
|
||||||
|
m.nJten,
|
||||||
m.nM,
|
m.nM,
|
||||||
m.na,
|
m.na,
|
||||||
m._impl.nacttrnbody,
|
m._impl.nacttrnbody,
|
||||||
@@ -3382,6 +3545,7 @@ def _step_jax_impl(m: types.Model, d: types.Data):
|
|||||||
m._impl.nflex,
|
m._impl.nflex,
|
||||||
m._impl.nflexedge,
|
m._impl.nflexedge,
|
||||||
m._impl.nflexelem,
|
m._impl.nflexelem,
|
||||||
|
m._impl.nflexshelldata,
|
||||||
m._impl.nflexvert,
|
m._impl.nflexvert,
|
||||||
m.ngeom,
|
m.ngeom,
|
||||||
m.ngravcomp,
|
m.ngravcomp,
|
||||||
@@ -3418,6 +3582,8 @@ def _step_jax_impl(m: types.Model, d: types.Data):
|
|||||||
m.pair_solreffriction,
|
m.pair_solreffriction,
|
||||||
m._impl.plugin,
|
m._impl.plugin,
|
||||||
m._impl.plugin_attr,
|
m._impl.plugin_attr,
|
||||||
|
m._impl.qLD_all_updates,
|
||||||
|
m._impl.qLD_level_offsets,
|
||||||
m._impl.qLD_updates,
|
m._impl.qLD_updates,
|
||||||
m._impl.qM_fullm_i,
|
m._impl.qM_fullm_i,
|
||||||
m._impl.qM_fullm_j,
|
m._impl.qM_fullm_j,
|
||||||
@@ -3461,6 +3627,9 @@ def _step_jax_impl(m: types.Model, d: types.Data):
|
|||||||
m.site_type,
|
m.site_type,
|
||||||
m._impl.taxel_sensorid,
|
m._impl.taxel_sensorid,
|
||||||
m._impl.taxel_vertadr,
|
m._impl.taxel_vertadr,
|
||||||
|
m._impl.ten_J_colind,
|
||||||
|
m._impl.ten_J_rowadr,
|
||||||
|
m._impl.ten_J_rownnz,
|
||||||
m.tendon_actfrclimited,
|
m.tendon_actfrclimited,
|
||||||
m.tendon_actfrcrange,
|
m.tendon_actfrcrange,
|
||||||
m.tendon_adr,
|
m.tendon_adr,
|
||||||
@@ -3520,6 +3689,7 @@ def _step_jax_impl(m: types.Model, d: types.Data):
|
|||||||
d._impl.naccdmax,
|
d._impl.naccdmax,
|
||||||
d._impl.naconmax,
|
d._impl.naconmax,
|
||||||
d._impl.njmax,
|
d._impl.njmax,
|
||||||
|
d._impl.njmax_nnz,
|
||||||
d.act,
|
d.act,
|
||||||
d.act_dot,
|
d.act_dot,
|
||||||
d.actuator_force,
|
d.actuator_force,
|
||||||
@@ -3604,6 +3774,7 @@ def _step_jax_impl(m: types.Model, d: types.Data):
|
|||||||
d._impl.contact__dim,
|
d._impl.contact__dim,
|
||||||
d._impl.contact__dist,
|
d._impl.contact__dist,
|
||||||
d._impl.contact__efc_address,
|
d._impl.contact__efc_address,
|
||||||
|
d._impl.contact__flex,
|
||||||
d._impl.contact__frame,
|
d._impl.contact__frame,
|
||||||
d._impl.contact__friction,
|
d._impl.contact__friction,
|
||||||
d._impl.contact__geom,
|
d._impl.contact__geom,
|
||||||
@@ -3614,6 +3785,7 @@ def _step_jax_impl(m: types.Model, d: types.Data):
|
|||||||
d._impl.contact__solref,
|
d._impl.contact__solref,
|
||||||
d._impl.contact__solreffriction,
|
d._impl.contact__solreffriction,
|
||||||
d._impl.contact__type,
|
d._impl.contact__type,
|
||||||
|
d._impl.contact__vert,
|
||||||
d._impl.contact__worldid,
|
d._impl.contact__worldid,
|
||||||
d._impl.efc__D,
|
d._impl.efc__D,
|
||||||
d._impl.efc__J,
|
d._impl.efc__J,
|
||||||
@@ -3710,32 +3882,34 @@ def _step_jax_impl(m: types.Model, d: types.Data):
|
|||||||
'_impl.contact__dim': out[75],
|
'_impl.contact__dim': out[75],
|
||||||
'_impl.contact__dist': out[76],
|
'_impl.contact__dist': out[76],
|
||||||
'_impl.contact__efc_address': out[77],
|
'_impl.contact__efc_address': out[77],
|
||||||
'_impl.contact__frame': out[78],
|
'_impl.contact__flex': out[78],
|
||||||
'_impl.contact__friction': out[79],
|
'_impl.contact__frame': out[79],
|
||||||
'_impl.contact__geom': out[80],
|
'_impl.contact__friction': out[80],
|
||||||
'_impl.contact__geomcollisionid': out[81],
|
'_impl.contact__geom': out[81],
|
||||||
'_impl.contact__includemargin': out[82],
|
'_impl.contact__geomcollisionid': out[82],
|
||||||
'_impl.contact__pos': out[83],
|
'_impl.contact__includemargin': out[83],
|
||||||
'_impl.contact__solimp': out[84],
|
'_impl.contact__pos': out[84],
|
||||||
'_impl.contact__solref': out[85],
|
'_impl.contact__solimp': out[85],
|
||||||
'_impl.contact__solreffriction': out[86],
|
'_impl.contact__solref': out[86],
|
||||||
'_impl.contact__type': out[87],
|
'_impl.contact__solreffriction': out[87],
|
||||||
'_impl.contact__worldid': out[88],
|
'_impl.contact__type': out[88],
|
||||||
'_impl.efc__D': out[89],
|
'_impl.contact__vert': out[89],
|
||||||
'_impl.efc__J': out[90],
|
'_impl.contact__worldid': out[90],
|
||||||
'_impl.efc__J_colind': out[91],
|
'_impl.efc__D': out[91],
|
||||||
'_impl.efc__J_rowadr': out[92],
|
'_impl.efc__J': out[92],
|
||||||
'_impl.efc__J_rownnz': out[93],
|
'_impl.efc__J_colind': out[93],
|
||||||
'_impl.efc__Ma': out[94],
|
'_impl.efc__J_rowadr': out[94],
|
||||||
'_impl.efc__aref': out[95],
|
'_impl.efc__J_rownnz': out[95],
|
||||||
'_impl.efc__force': out[96],
|
'_impl.efc__Ma': out[96],
|
||||||
'_impl.efc__frictionloss': out[97],
|
'_impl.efc__aref': out[97],
|
||||||
'_impl.efc__id': out[98],
|
'_impl.efc__force': out[98],
|
||||||
'_impl.efc__margin': out[99],
|
'_impl.efc__frictionloss': out[99],
|
||||||
'_impl.efc__pos': out[100],
|
'_impl.efc__id': out[100],
|
||||||
'_impl.efc__state': out[101],
|
'_impl.efc__margin': out[101],
|
||||||
'_impl.efc__type': out[102],
|
'_impl.efc__pos': out[102],
|
||||||
'_impl.efc__vel': out[103],
|
'_impl.efc__state': out[103],
|
||||||
|
'_impl.efc__type': out[104],
|
||||||
|
'_impl.efc__vel': out[105],
|
||||||
})
|
})
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
|||||||
@@ -157,7 +157,16 @@ class ForwardTest(parameterized.TestCase):
|
|||||||
m.ten_J_rowadr,
|
m.ten_J_rowadr,
|
||||||
m.ten_J_colind,
|
m.ten_J_colind,
|
||||||
)
|
)
|
||||||
tu.assert_eq(dx._impl.ten_J, ten_J, 'ten_J')
|
# convert sparse warp ten_J to dense representation
|
||||||
|
warp_ten_J = np.zeros((m.ntendon, m.nv))
|
||||||
|
mujoco.mju_sparse2dense(
|
||||||
|
warp_ten_J,
|
||||||
|
np.asarray(dx._impl.ten_J),
|
||||||
|
mx._impl.ten_J_rownnz,
|
||||||
|
mx._impl.ten_J_rowadr,
|
||||||
|
mx._impl.ten_J_colind,
|
||||||
|
)
|
||||||
|
tu.assert_eq(warp_ten_J, ten_J, 'ten_J')
|
||||||
tu.assert_attr_eq(dx._impl, d, 'ten_wrapadr')
|
tu.assert_attr_eq(dx._impl, d, 'ten_wrapadr')
|
||||||
tu.assert_attr_eq(dx._impl, d, 'ten_wrapnum')
|
tu.assert_attr_eq(dx._impl, d, 'ten_wrapnum')
|
||||||
tu.assert_attr_eq(dx._impl, d, 'wrap_xpos')
|
tu.assert_attr_eq(dx._impl, d, 'wrap_xpos')
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ _cb = mjwp_types.Callback(
|
|||||||
**{f.name: None for f in dataclasses.fields(mjwp_types.Callback) if f.init}
|
**{f.name: None for f in dataclasses.fields(mjwp_types.Callback) if f.init}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ffi.format_args_for_warp
|
@ffi.format_args_for_warp
|
||||||
def _render_shim(
|
def _render_shim(
|
||||||
# Model
|
# Model
|
||||||
@@ -56,6 +57,9 @@ def _render_shim(
|
|||||||
cam_intrinsic: wp.array2d(dtype=wp.vec4),
|
cam_intrinsic: wp.array2d(dtype=wp.vec4),
|
||||||
cam_projection: wp.array(dtype=int),
|
cam_projection: wp.array(dtype=int),
|
||||||
cam_sensorsize: wp.array(dtype=wp.vec2),
|
cam_sensorsize: wp.array(dtype=wp.vec2),
|
||||||
|
flex_edge: wp.array(dtype=wp.vec2i),
|
||||||
|
flex_radius: wp.array(dtype=float),
|
||||||
|
flex_vertadr: wp.array(dtype=int),
|
||||||
geom_dataid: wp.array(dtype=int),
|
geom_dataid: wp.array(dtype=int),
|
||||||
geom_matid: wp.array2d(dtype=int),
|
geom_matid: wp.array2d(dtype=int),
|
||||||
geom_rgba: wp.array2d(dtype=wp.vec4),
|
geom_rgba: wp.array2d(dtype=wp.vec4),
|
||||||
@@ -68,11 +72,11 @@ def _render_shim(
|
|||||||
mat_texid: wp.array3d(dtype=int),
|
mat_texid: wp.array3d(dtype=int),
|
||||||
mat_texrepeat: wp.array2d(dtype=wp.vec2),
|
mat_texrepeat: wp.array2d(dtype=wp.vec2),
|
||||||
mesh_faceadr: wp.array(dtype=int),
|
mesh_faceadr: wp.array(dtype=int),
|
||||||
nflex: int,
|
|
||||||
nlight: int,
|
nlight: int,
|
||||||
# Data
|
# Data
|
||||||
cam_xmat: wp.array2d(dtype=wp.mat33),
|
cam_xmat: wp.array2d(dtype=wp.mat33),
|
||||||
cam_xpos: wp.array2d(dtype=wp.vec3),
|
cam_xpos: wp.array2d(dtype=wp.vec3),
|
||||||
|
flexvert_xpos: wp.array2d(dtype=wp.vec3),
|
||||||
geom_xmat: wp.array2d(dtype=wp.mat33),
|
geom_xmat: wp.array2d(dtype=wp.mat33),
|
||||||
geom_xpos: wp.array2d(dtype=wp.vec3),
|
geom_xpos: wp.array2d(dtype=wp.vec3),
|
||||||
light_xdir: wp.array2d(dtype=wp.vec3),
|
light_xdir: wp.array2d(dtype=wp.vec3),
|
||||||
@@ -91,6 +95,9 @@ def _render_shim(
|
|||||||
_m.cam_intrinsic = cam_intrinsic
|
_m.cam_intrinsic = cam_intrinsic
|
||||||
_m.cam_projection = cam_projection
|
_m.cam_projection = cam_projection
|
||||||
_m.cam_sensorsize = cam_sensorsize
|
_m.cam_sensorsize = cam_sensorsize
|
||||||
|
_m.flex_edge = flex_edge
|
||||||
|
_m.flex_radius = flex_radius
|
||||||
|
_m.flex_vertadr = flex_vertadr
|
||||||
_m.geom_dataid = geom_dataid
|
_m.geom_dataid = geom_dataid
|
||||||
_m.geom_matid = geom_matid
|
_m.geom_matid = geom_matid
|
||||||
_m.geom_rgba = geom_rgba
|
_m.geom_rgba = geom_rgba
|
||||||
@@ -103,10 +110,10 @@ def _render_shim(
|
|||||||
_m.mat_texid = mat_texid
|
_m.mat_texid = mat_texid
|
||||||
_m.mat_texrepeat = mat_texrepeat
|
_m.mat_texrepeat = mat_texrepeat
|
||||||
_m.mesh_faceadr = mesh_faceadr
|
_m.mesh_faceadr = mesh_faceadr
|
||||||
_m.nflex = nflex
|
|
||||||
_m.nlight = nlight
|
_m.nlight = nlight
|
||||||
_d.cam_xmat = cam_xmat
|
_d.cam_xmat = cam_xmat
|
||||||
_d.cam_xpos = cam_xpos
|
_d.cam_xpos = cam_xpos
|
||||||
|
_d.flexvert_xpos = flexvert_xpos
|
||||||
_d.geom_xmat = geom_xmat
|
_d.geom_xmat = geom_xmat
|
||||||
_d.geom_xpos = geom_xpos
|
_d.geom_xpos = geom_xpos
|
||||||
_d.light_xdir = light_xdir
|
_d.light_xdir = light_xdir
|
||||||
@@ -155,6 +162,9 @@ def _render_jax_impl(m: types.Model, d: types.Data, ctx: RenderContextPytree):
|
|||||||
m.cam_intrinsic,
|
m.cam_intrinsic,
|
||||||
m._impl.cam_projection,
|
m._impl.cam_projection,
|
||||||
m.cam_sensorsize,
|
m.cam_sensorsize,
|
||||||
|
m._impl.flex_edge,
|
||||||
|
m._impl.flex_radius,
|
||||||
|
m._impl.flex_vertadr,
|
||||||
m.geom_dataid,
|
m.geom_dataid,
|
||||||
m.geom_matid,
|
m.geom_matid,
|
||||||
m.geom_rgba,
|
m.geom_rgba,
|
||||||
@@ -167,10 +177,10 @@ def _render_jax_impl(m: types.Model, d: types.Data, ctx: RenderContextPytree):
|
|||||||
m.mat_texid,
|
m.mat_texid,
|
||||||
m._impl.mat_texrepeat,
|
m._impl.mat_texrepeat,
|
||||||
m.mesh_faceadr,
|
m.mesh_faceadr,
|
||||||
m._impl.nflex,
|
|
||||||
m.nlight,
|
m.nlight,
|
||||||
d.cam_xmat,
|
d.cam_xmat,
|
||||||
d.cam_xpos,
|
d.cam_xpos,
|
||||||
|
d._impl.flexvert_xpos,
|
||||||
d.geom_xmat,
|
d.geom_xmat,
|
||||||
d.geom_xpos,
|
d.geom_xpos,
|
||||||
d._impl.light_xdir,
|
d._impl.light_xdir,
|
||||||
|
|||||||
@@ -297,17 +297,20 @@ def kinematics_vmap(
|
|||||||
def _tendon_shim(
|
def _tendon_shim(
|
||||||
# Model
|
# Model
|
||||||
nworld: int,
|
nworld: int,
|
||||||
|
body_dofadr: wp.array(dtype=int),
|
||||||
|
body_dofnum: wp.array(dtype=int),
|
||||||
body_parentid: wp.array(dtype=int),
|
body_parentid: wp.array(dtype=int),
|
||||||
body_rootid: wp.array(dtype=int),
|
body_rootid: wp.array(dtype=int),
|
||||||
dof_bodyid: wp.array(dtype=int),
|
|
||||||
geom_bodyid: wp.array(dtype=int),
|
geom_bodyid: wp.array(dtype=int),
|
||||||
geom_size: wp.array2d(dtype=wp.vec3),
|
geom_size: wp.array2d(dtype=wp.vec3),
|
||||||
jnt_dofadr: wp.array(dtype=int),
|
jnt_dofadr: wp.array(dtype=int),
|
||||||
jnt_qposadr: wp.array(dtype=int),
|
jnt_qposadr: wp.array(dtype=int),
|
||||||
ntendon: int,
|
ntendon: int,
|
||||||
nv: int,
|
|
||||||
nwrap: int,
|
nwrap: int,
|
||||||
site_bodyid: wp.array(dtype=int),
|
site_bodyid: wp.array(dtype=int),
|
||||||
|
ten_J_colind: wp.array(dtype=int),
|
||||||
|
ten_J_rowadr: wp.array(dtype=int),
|
||||||
|
ten_J_rownnz: wp.array(dtype=int),
|
||||||
tendon_adr: wp.array(dtype=int),
|
tendon_adr: wp.array(dtype=int),
|
||||||
tendon_geom_adr: wp.array(dtype=int),
|
tendon_geom_adr: wp.array(dtype=int),
|
||||||
tendon_jnt_adr: wp.array(dtype=int),
|
tendon_jnt_adr: wp.array(dtype=int),
|
||||||
@@ -327,7 +330,7 @@ def _tendon_shim(
|
|||||||
qpos: wp.array2d(dtype=float),
|
qpos: wp.array2d(dtype=float),
|
||||||
site_xpos: wp.array2d(dtype=wp.vec3),
|
site_xpos: wp.array2d(dtype=wp.vec3),
|
||||||
subtree_com: wp.array2d(dtype=wp.vec3),
|
subtree_com: wp.array2d(dtype=wp.vec3),
|
||||||
ten_J: wp.array3d(dtype=float),
|
ten_J: wp.array2d(dtype=float),
|
||||||
ten_length: wp.array2d(dtype=float),
|
ten_length: wp.array2d(dtype=float),
|
||||||
ten_wrapadr: wp.array2d(dtype=int),
|
ten_wrapadr: wp.array2d(dtype=int),
|
||||||
ten_wrapnum: wp.array2d(dtype=int),
|
ten_wrapnum: wp.array2d(dtype=int),
|
||||||
@@ -339,17 +342,20 @@ def _tendon_shim(
|
|||||||
_m.callback = _cb
|
_m.callback = _cb
|
||||||
_d.efc = _e
|
_d.efc = _e
|
||||||
_d.contact = _c
|
_d.contact = _c
|
||||||
|
_m.body_dofadr = body_dofadr
|
||||||
|
_m.body_dofnum = body_dofnum
|
||||||
_m.body_parentid = body_parentid
|
_m.body_parentid = body_parentid
|
||||||
_m.body_rootid = body_rootid
|
_m.body_rootid = body_rootid
|
||||||
_m.dof_bodyid = dof_bodyid
|
|
||||||
_m.geom_bodyid = geom_bodyid
|
_m.geom_bodyid = geom_bodyid
|
||||||
_m.geom_size = geom_size
|
_m.geom_size = geom_size
|
||||||
_m.jnt_dofadr = jnt_dofadr
|
_m.jnt_dofadr = jnt_dofadr
|
||||||
_m.jnt_qposadr = jnt_qposadr
|
_m.jnt_qposadr = jnt_qposadr
|
||||||
_m.ntendon = ntendon
|
_m.ntendon = ntendon
|
||||||
_m.nv = nv
|
|
||||||
_m.nwrap = nwrap
|
_m.nwrap = nwrap
|
||||||
_m.site_bodyid = site_bodyid
|
_m.site_bodyid = site_bodyid
|
||||||
|
_m.ten_J_colind = ten_J_colind
|
||||||
|
_m.ten_J_rowadr = ten_J_rowadr
|
||||||
|
_m.ten_J_rownnz = ten_J_rownnz
|
||||||
_m.tendon_adr = tendon_adr
|
_m.tendon_adr = tendon_adr
|
||||||
_m.tendon_geom_adr = tendon_geom_adr
|
_m.tendon_geom_adr = tendon_geom_adr
|
||||||
_m.tendon_jnt_adr = tendon_jnt_adr
|
_m.tendon_jnt_adr = tendon_jnt_adr
|
||||||
@@ -416,17 +422,20 @@ def _tendon_jax_impl(m: types.Model, d: types.Data):
|
|||||||
)
|
)
|
||||||
out = jf(
|
out = jf(
|
||||||
d.qpos.shape[0],
|
d.qpos.shape[0],
|
||||||
|
m.body_dofadr,
|
||||||
|
m.body_dofnum,
|
||||||
m.body_parentid,
|
m.body_parentid,
|
||||||
m.body_rootid,
|
m.body_rootid,
|
||||||
m.dof_bodyid,
|
|
||||||
m.geom_bodyid,
|
m.geom_bodyid,
|
||||||
m.geom_size,
|
m.geom_size,
|
||||||
m.jnt_dofadr,
|
m.jnt_dofadr,
|
||||||
m.jnt_qposadr,
|
m.jnt_qposadr,
|
||||||
m.ntendon,
|
m.ntendon,
|
||||||
m.nv,
|
|
||||||
m.nwrap,
|
m.nwrap,
|
||||||
m.site_bodyid,
|
m.site_bodyid,
|
||||||
|
m._impl.ten_J_colind,
|
||||||
|
m._impl.ten_J_rowadr,
|
||||||
|
m._impl.ten_J_rownnz,
|
||||||
m.tendon_adr,
|
m.tendon_adr,
|
||||||
m._impl.tendon_geom_adr,
|
m._impl.tendon_geom_adr,
|
||||||
m._impl.tendon_jnt_adr,
|
m._impl.tendon_jnt_adr,
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ class BlockDim:
|
|||||||
qderiv_actuator_dense: int
|
qderiv_actuator_dense: int
|
||||||
ray: int
|
ray: int
|
||||||
segmented_sort: int
|
segmented_sort: int
|
||||||
tendon_velocity: int
|
solve_LD_sparse_fused: int
|
||||||
update_gradient_JTDAJ_dense: int
|
update_gradient_JTDAJ_dense: int
|
||||||
update_gradient_JTDAJ_sparse: int
|
update_gradient_JTDAJ_sparse: int
|
||||||
update_gradient_cholesky: int
|
update_gradient_cholesky: int
|
||||||
@@ -141,6 +141,10 @@ class ModelWarp(PyTreeNode):
|
|||||||
eq_ten_adr: np.ndarray
|
eq_ten_adr: np.ndarray
|
||||||
eq_wld_adr: np.ndarray
|
eq_wld_adr: np.ndarray
|
||||||
flex_bending: np.ndarray
|
flex_bending: np.ndarray
|
||||||
|
flex_centered: np.ndarray
|
||||||
|
flex_conaffinity: np.ndarray
|
||||||
|
flex_condim: np.ndarray
|
||||||
|
flex_contype: np.ndarray
|
||||||
flex_damping: np.ndarray
|
flex_damping: np.ndarray
|
||||||
flex_dim: np.ndarray
|
flex_dim: np.ndarray
|
||||||
flex_edge: np.ndarray
|
flex_edge: np.ndarray
|
||||||
@@ -149,12 +153,21 @@ class ModelWarp(PyTreeNode):
|
|||||||
flex_edgenum: np.ndarray
|
flex_edgenum: np.ndarray
|
||||||
flex_elem: np.ndarray
|
flex_elem: np.ndarray
|
||||||
flex_elemadr: np.ndarray
|
flex_elemadr: np.ndarray
|
||||||
|
flex_elemdataadr: np.ndarray
|
||||||
flex_elemedge: np.ndarray
|
flex_elemedge: np.ndarray
|
||||||
flex_elemedgeadr: np.ndarray
|
flex_elemedgeadr: np.ndarray
|
||||||
flex_elemnum: np.ndarray
|
flex_elemnum: np.ndarray
|
||||||
|
flex_friction: np.ndarray
|
||||||
|
flex_margin: np.ndarray
|
||||||
|
flex_radius: np.ndarray
|
||||||
|
flex_shell: np.ndarray
|
||||||
|
flex_shelldataadr: np.ndarray
|
||||||
|
flex_shellnum: np.ndarray
|
||||||
flex_stiffness: np.ndarray
|
flex_stiffness: np.ndarray
|
||||||
|
flex_vert: np.ndarray
|
||||||
flex_vertadr: np.ndarray
|
flex_vertadr: np.ndarray
|
||||||
flex_vertbodyid: np.ndarray
|
flex_vertbodyid: np.ndarray
|
||||||
|
flex_vertflexid: np.ndarray
|
||||||
flex_vertnum: np.ndarray
|
flex_vertnum: np.ndarray
|
||||||
flexedge_J_colind: np.ndarray
|
flexedge_J_colind: np.ndarray
|
||||||
flexedge_J_rowadr: np.ndarray
|
flexedge_J_rowadr: np.ndarray
|
||||||
@@ -173,6 +186,7 @@ class ModelWarp(PyTreeNode):
|
|||||||
light_targetbodyid: np.ndarray
|
light_targetbodyid: np.ndarray
|
||||||
mapM2M: np.ndarray
|
mapM2M: np.ndarray
|
||||||
mat_texrepeat: jax.Array
|
mat_texrepeat: jax.Array
|
||||||
|
max_ten_J_rownnz: int
|
||||||
mesh_polyadr: np.ndarray
|
mesh_polyadr: np.ndarray
|
||||||
mesh_polymap: np.ndarray
|
mesh_polymap: np.ndarray
|
||||||
mesh_polymapadr: np.ndarray
|
mesh_polymapadr: np.ndarray
|
||||||
@@ -191,6 +205,7 @@ class ModelWarp(PyTreeNode):
|
|||||||
nflexelem: int
|
nflexelem: int
|
||||||
nflexelemdata: int
|
nflexelemdata: int
|
||||||
nflexelemedge: int
|
nflexelemedge: int
|
||||||
|
nflexshelldata: int
|
||||||
nflexvert: int
|
nflexvert: int
|
||||||
nmaxcondim: int
|
nmaxcondim: int
|
||||||
nmaxmeshdeg: int
|
nmaxmeshdeg: int
|
||||||
@@ -213,6 +228,8 @@ class ModelWarp(PyTreeNode):
|
|||||||
oct_coeff: np.ndarray
|
oct_coeff: np.ndarray
|
||||||
plugin: np.ndarray
|
plugin: np.ndarray
|
||||||
plugin_attr: np.ndarray
|
plugin_attr: np.ndarray
|
||||||
|
qLD_all_updates: np.ndarray
|
||||||
|
qLD_level_offsets: np.ndarray
|
||||||
qLD_updates: Tuple[np.ndarray, ...]
|
qLD_updates: Tuple[np.ndarray, ...]
|
||||||
qM_fullm_i: np.ndarray
|
qM_fullm_i: np.ndarray
|
||||||
qM_fullm_j: np.ndarray
|
qM_fullm_j: np.ndarray
|
||||||
@@ -240,6 +257,9 @@ class ModelWarp(PyTreeNode):
|
|||||||
sensor_vel_adr: np.ndarray
|
sensor_vel_adr: np.ndarray
|
||||||
taxel_sensorid: np.ndarray
|
taxel_sensorid: np.ndarray
|
||||||
taxel_vertadr: np.ndarray
|
taxel_vertadr: np.ndarray
|
||||||
|
ten_J_colind: np.ndarray
|
||||||
|
ten_J_rowadr: np.ndarray
|
||||||
|
ten_J_rownnz: np.ndarray
|
||||||
ten_wrapadr_site: np.ndarray
|
ten_wrapadr_site: np.ndarray
|
||||||
ten_wrapnum_site: np.ndarray
|
ten_wrapnum_site: np.ndarray
|
||||||
tendon_geom_adr: np.ndarray
|
tendon_geom_adr: np.ndarray
|
||||||
@@ -266,6 +286,7 @@ class DataWarp(PyTreeNode):
|
|||||||
contact__dim: jax.Array
|
contact__dim: jax.Array
|
||||||
contact__dist: jax.Array
|
contact__dist: jax.Array
|
||||||
contact__efc_address: jax.Array
|
contact__efc_address: jax.Array
|
||||||
|
contact__flex: jax.Array
|
||||||
contact__frame: jax.Array
|
contact__frame: jax.Array
|
||||||
contact__friction: jax.Array
|
contact__friction: jax.Array
|
||||||
contact__geom: jax.Array
|
contact__geom: jax.Array
|
||||||
@@ -276,6 +297,7 @@ class DataWarp(PyTreeNode):
|
|||||||
contact__solref: jax.Array
|
contact__solref: jax.Array
|
||||||
contact__solreffriction: jax.Array
|
contact__solreffriction: jax.Array
|
||||||
contact__type: jax.Array
|
contact__type: jax.Array
|
||||||
|
contact__vert: jax.Array
|
||||||
contact__worldid: jax.Array
|
contact__worldid: jax.Array
|
||||||
crb: jax.Array
|
crb: jax.Array
|
||||||
efc__D: jax.Array
|
efc__D: jax.Array
|
||||||
@@ -312,6 +334,7 @@ class DataWarp(PyTreeNode):
|
|||||||
nf: jax.Array
|
nf: jax.Array
|
||||||
nisland: jax.Array
|
nisland: jax.Array
|
||||||
njmax: int
|
njmax: int
|
||||||
|
njmax_nnz: int
|
||||||
njmax_pad: int
|
njmax_pad: int
|
||||||
nl: jax.Array
|
nl: jax.Array
|
||||||
nworld: int
|
nworld: int
|
||||||
@@ -335,6 +358,7 @@ DATA_NON_VMAP = {
|
|||||||
'contact__dim',
|
'contact__dim',
|
||||||
'contact__dist',
|
'contact__dist',
|
||||||
'contact__efc_address',
|
'contact__efc_address',
|
||||||
|
'contact__flex',
|
||||||
'contact__frame',
|
'contact__frame',
|
||||||
'contact__friction',
|
'contact__friction',
|
||||||
'contact__geom',
|
'contact__geom',
|
||||||
@@ -345,12 +369,14 @@ DATA_NON_VMAP = {
|
|||||||
'contact__solref',
|
'contact__solref',
|
||||||
'contact__solreffriction',
|
'contact__solreffriction',
|
||||||
'contact__type',
|
'contact__type',
|
||||||
|
'contact__vert',
|
||||||
'contact__worldid',
|
'contact__worldid',
|
||||||
'naccdmax',
|
'naccdmax',
|
||||||
'nacon',
|
'nacon',
|
||||||
'naconmax',
|
'naconmax',
|
||||||
'ncollision',
|
'ncollision',
|
||||||
'njmax',
|
'njmax',
|
||||||
|
'njmax_nnz',
|
||||||
'njmax_pad',
|
'njmax_pad',
|
||||||
'nworld',
|
'nworld',
|
||||||
}
|
}
|
||||||
@@ -398,6 +424,7 @@ _NDIM = {
|
|||||||
'contact__dim': 1,
|
'contact__dim': 1,
|
||||||
'contact__dist': 1,
|
'contact__dist': 1,
|
||||||
'contact__efc_address': 2,
|
'contact__efc_address': 2,
|
||||||
|
'contact__flex': 2,
|
||||||
'contact__frame': 3,
|
'contact__frame': 3,
|
||||||
'contact__friction': 2,
|
'contact__friction': 2,
|
||||||
'contact__geom': 2,
|
'contact__geom': 2,
|
||||||
@@ -408,6 +435,7 @@ _NDIM = {
|
|||||||
'contact__solref': 2,
|
'contact__solref': 2,
|
||||||
'contact__solreffriction': 2,
|
'contact__solreffriction': 2,
|
||||||
'contact__type': 1,
|
'contact__type': 1,
|
||||||
|
'contact__vert': 2,
|
||||||
'contact__worldid': 1,
|
'contact__worldid': 1,
|
||||||
'crb': 3,
|
'crb': 3,
|
||||||
'ctrl': 2,
|
'ctrl': 2,
|
||||||
@@ -451,6 +479,7 @@ _NDIM = {
|
|||||||
'nf': 1,
|
'nf': 1,
|
||||||
'nisland': 1,
|
'nisland': 1,
|
||||||
'njmax': 0,
|
'njmax': 0,
|
||||||
|
'njmax_nnz': 0,
|
||||||
'njmax_pad': 0,
|
'njmax_pad': 0,
|
||||||
'nl': 1,
|
'nl': 1,
|
||||||
'nworld': 0,
|
'nworld': 0,
|
||||||
@@ -480,7 +509,7 @@ _NDIM = {
|
|||||||
'subtree_angmom': 3,
|
'subtree_angmom': 3,
|
||||||
'subtree_com': 3,
|
'subtree_com': 3,
|
||||||
'subtree_linvel': 3,
|
'subtree_linvel': 3,
|
||||||
'ten_J': 3,
|
'ten_J': 2,
|
||||||
'ten_length': 2,
|
'ten_length': 2,
|
||||||
'ten_velocity': 2,
|
'ten_velocity': 2,
|
||||||
'ten_wrapadr': 2,
|
'ten_wrapadr': 2,
|
||||||
@@ -535,7 +564,7 @@ _NDIM = {
|
|||||||
'block_dim__qderiv_actuator_dense': 0,
|
'block_dim__qderiv_actuator_dense': 0,
|
||||||
'block_dim__ray': 0,
|
'block_dim__ray': 0,
|
||||||
'block_dim__segmented_sort': 0,
|
'block_dim__segmented_sort': 0,
|
||||||
'block_dim__tendon_velocity': 0,
|
'block_dim__solve_LD_sparse_fused': 0,
|
||||||
'block_dim__update_gradient_JTDAJ_dense': 0,
|
'block_dim__update_gradient_JTDAJ_dense': 0,
|
||||||
'block_dim__update_gradient_JTDAJ_sparse': 0,
|
'block_dim__update_gradient_JTDAJ_sparse': 0,
|
||||||
'block_dim__update_gradient_cholesky': 0,
|
'block_dim__update_gradient_cholesky': 0,
|
||||||
@@ -608,6 +637,10 @@ _NDIM = {
|
|||||||
'eq_wld_adr': 1,
|
'eq_wld_adr': 1,
|
||||||
'exclude_signature': 1,
|
'exclude_signature': 1,
|
||||||
'flex_bending': 2,
|
'flex_bending': 2,
|
||||||
|
'flex_centered': 1,
|
||||||
|
'flex_conaffinity': 1,
|
||||||
|
'flex_condim': 1,
|
||||||
|
'flex_contype': 1,
|
||||||
'flex_damping': 1,
|
'flex_damping': 1,
|
||||||
'flex_dim': 1,
|
'flex_dim': 1,
|
||||||
'flex_edge': 2,
|
'flex_edge': 2,
|
||||||
@@ -616,12 +649,21 @@ _NDIM = {
|
|||||||
'flex_edgenum': 1,
|
'flex_edgenum': 1,
|
||||||
'flex_elem': 1,
|
'flex_elem': 1,
|
||||||
'flex_elemadr': 1,
|
'flex_elemadr': 1,
|
||||||
|
'flex_elemdataadr': 1,
|
||||||
'flex_elemedge': 1,
|
'flex_elemedge': 1,
|
||||||
'flex_elemedgeadr': 1,
|
'flex_elemedgeadr': 1,
|
||||||
'flex_elemnum': 1,
|
'flex_elemnum': 1,
|
||||||
|
'flex_friction': 2,
|
||||||
|
'flex_margin': 1,
|
||||||
|
'flex_radius': 1,
|
||||||
|
'flex_shell': 1,
|
||||||
|
'flex_shelldataadr': 1,
|
||||||
|
'flex_shellnum': 1,
|
||||||
'flex_stiffness': 2,
|
'flex_stiffness': 2,
|
||||||
|
'flex_vert': 2,
|
||||||
'flex_vertadr': 1,
|
'flex_vertadr': 1,
|
||||||
'flex_vertbodyid': 1,
|
'flex_vertbodyid': 1,
|
||||||
|
'flex_vertflexid': 1,
|
||||||
'flex_vertnum': 1,
|
'flex_vertnum': 1,
|
||||||
'flexedge_J_colind': 1,
|
'flexedge_J_colind': 1,
|
||||||
'flexedge_J_rowadr': 1,
|
'flexedge_J_rowadr': 1,
|
||||||
@@ -692,6 +734,7 @@ _NDIM = {
|
|||||||
'mat_rgba': 3,
|
'mat_rgba': 3,
|
||||||
'mat_texid': 3,
|
'mat_texid': 3,
|
||||||
'mat_texrepeat': 3,
|
'mat_texrepeat': 3,
|
||||||
|
'max_ten_J_rownnz': 0,
|
||||||
'mesh_face': 2,
|
'mesh_face': 2,
|
||||||
'mesh_faceadr': 1,
|
'mesh_faceadr': 1,
|
||||||
'mesh_graph': 1,
|
'mesh_graph': 1,
|
||||||
@@ -717,6 +760,7 @@ _NDIM = {
|
|||||||
'nC': 0,
|
'nC': 0,
|
||||||
'nJfe': 0,
|
'nJfe': 0,
|
||||||
'nJmom': 0,
|
'nJmom': 0,
|
||||||
|
'nJten': 0,
|
||||||
'nM': 0,
|
'nM': 0,
|
||||||
'na': 0,
|
'na': 0,
|
||||||
'nacttrnbody': 0,
|
'nacttrnbody': 0,
|
||||||
@@ -730,6 +774,7 @@ _NDIM = {
|
|||||||
'nflexelem': 0,
|
'nflexelem': 0,
|
||||||
'nflexelemdata': 0,
|
'nflexelemdata': 0,
|
||||||
'nflexelemedge': 0,
|
'nflexelemedge': 0,
|
||||||
|
'nflexshelldata': 0,
|
||||||
'nflexvert': 0,
|
'nflexvert': 0,
|
||||||
'ngeom': 0,
|
'ngeom': 0,
|
||||||
'ngravcomp': 0,
|
'ngravcomp': 0,
|
||||||
@@ -811,6 +856,8 @@ _NDIM = {
|
|||||||
'pair_solreffriction': 3,
|
'pair_solreffriction': 3,
|
||||||
'plugin': 1,
|
'plugin': 1,
|
||||||
'plugin_attr': 2,
|
'plugin_attr': 2,
|
||||||
|
'qLD_all_updates': 2,
|
||||||
|
'qLD_level_offsets': 1,
|
||||||
'qLD_updates': -1,
|
'qLD_updates': -1,
|
||||||
'qM_fullm_i': 1,
|
'qM_fullm_i': 1,
|
||||||
'qM_fullm_j': 1,
|
'qM_fullm_j': 1,
|
||||||
@@ -856,6 +903,9 @@ _NDIM = {
|
|||||||
'stat__meaninertia': 1,
|
'stat__meaninertia': 1,
|
||||||
'taxel_sensorid': 1,
|
'taxel_sensorid': 1,
|
||||||
'taxel_vertadr': 1,
|
'taxel_vertadr': 1,
|
||||||
|
'ten_J_colind': 1,
|
||||||
|
'ten_J_rowadr': 1,
|
||||||
|
'ten_J_rownnz': 1,
|
||||||
'ten_wrapadr_site': 1,
|
'ten_wrapadr_site': 1,
|
||||||
'ten_wrapnum_site': 1,
|
'ten_wrapnum_site': 1,
|
||||||
'tendon_actfrclimited': 1,
|
'tendon_actfrclimited': 1,
|
||||||
@@ -940,6 +990,7 @@ _BATCH_DIM = {
|
|||||||
'contact__dim': False,
|
'contact__dim': False,
|
||||||
'contact__dist': False,
|
'contact__dist': False,
|
||||||
'contact__efc_address': False,
|
'contact__efc_address': False,
|
||||||
|
'contact__flex': False,
|
||||||
'contact__frame': False,
|
'contact__frame': False,
|
||||||
'contact__friction': False,
|
'contact__friction': False,
|
||||||
'contact__geom': False,
|
'contact__geom': False,
|
||||||
@@ -950,6 +1001,7 @@ _BATCH_DIM = {
|
|||||||
'contact__solref': False,
|
'contact__solref': False,
|
||||||
'contact__solreffriction': False,
|
'contact__solreffriction': False,
|
||||||
'contact__type': False,
|
'contact__type': False,
|
||||||
|
'contact__vert': False,
|
||||||
'contact__worldid': False,
|
'contact__worldid': False,
|
||||||
'crb': True,
|
'crb': True,
|
||||||
'ctrl': True,
|
'ctrl': True,
|
||||||
@@ -993,6 +1045,7 @@ _BATCH_DIM = {
|
|||||||
'nf': True,
|
'nf': True,
|
||||||
'nisland': True,
|
'nisland': True,
|
||||||
'njmax': False,
|
'njmax': False,
|
||||||
|
'njmax_nnz': False,
|
||||||
'njmax_pad': False,
|
'njmax_pad': False,
|
||||||
'nl': True,
|
'nl': True,
|
||||||
'nworld': False,
|
'nworld': False,
|
||||||
@@ -1077,7 +1130,7 @@ _BATCH_DIM = {
|
|||||||
'block_dim__qderiv_actuator_dense': False,
|
'block_dim__qderiv_actuator_dense': False,
|
||||||
'block_dim__ray': False,
|
'block_dim__ray': False,
|
||||||
'block_dim__segmented_sort': False,
|
'block_dim__segmented_sort': False,
|
||||||
'block_dim__tendon_velocity': False,
|
'block_dim__solve_LD_sparse_fused': False,
|
||||||
'block_dim__update_gradient_JTDAJ_dense': False,
|
'block_dim__update_gradient_JTDAJ_dense': False,
|
||||||
'block_dim__update_gradient_JTDAJ_sparse': False,
|
'block_dim__update_gradient_JTDAJ_sparse': False,
|
||||||
'block_dim__update_gradient_cholesky': False,
|
'block_dim__update_gradient_cholesky': False,
|
||||||
@@ -1150,6 +1203,10 @@ _BATCH_DIM = {
|
|||||||
'eq_wld_adr': False,
|
'eq_wld_adr': False,
|
||||||
'exclude_signature': False,
|
'exclude_signature': False,
|
||||||
'flex_bending': False,
|
'flex_bending': False,
|
||||||
|
'flex_centered': False,
|
||||||
|
'flex_conaffinity': False,
|
||||||
|
'flex_condim': False,
|
||||||
|
'flex_contype': False,
|
||||||
'flex_damping': False,
|
'flex_damping': False,
|
||||||
'flex_dim': False,
|
'flex_dim': False,
|
||||||
'flex_edge': False,
|
'flex_edge': False,
|
||||||
@@ -1158,12 +1215,21 @@ _BATCH_DIM = {
|
|||||||
'flex_edgenum': False,
|
'flex_edgenum': False,
|
||||||
'flex_elem': False,
|
'flex_elem': False,
|
||||||
'flex_elemadr': False,
|
'flex_elemadr': False,
|
||||||
|
'flex_elemdataadr': False,
|
||||||
'flex_elemedge': False,
|
'flex_elemedge': False,
|
||||||
'flex_elemedgeadr': False,
|
'flex_elemedgeadr': False,
|
||||||
'flex_elemnum': False,
|
'flex_elemnum': False,
|
||||||
|
'flex_friction': False,
|
||||||
|
'flex_margin': False,
|
||||||
|
'flex_radius': False,
|
||||||
|
'flex_shell': False,
|
||||||
|
'flex_shelldataadr': False,
|
||||||
|
'flex_shellnum': False,
|
||||||
'flex_stiffness': False,
|
'flex_stiffness': False,
|
||||||
|
'flex_vert': False,
|
||||||
'flex_vertadr': False,
|
'flex_vertadr': False,
|
||||||
'flex_vertbodyid': False,
|
'flex_vertbodyid': False,
|
||||||
|
'flex_vertflexid': False,
|
||||||
'flex_vertnum': False,
|
'flex_vertnum': False,
|
||||||
'flexedge_J_colind': False,
|
'flexedge_J_colind': False,
|
||||||
'flexedge_J_rowadr': False,
|
'flexedge_J_rowadr': False,
|
||||||
@@ -1234,6 +1300,7 @@ _BATCH_DIM = {
|
|||||||
'mat_rgba': True,
|
'mat_rgba': True,
|
||||||
'mat_texid': True,
|
'mat_texid': True,
|
||||||
'mat_texrepeat': True,
|
'mat_texrepeat': True,
|
||||||
|
'max_ten_J_rownnz': False,
|
||||||
'mesh_face': False,
|
'mesh_face': False,
|
||||||
'mesh_faceadr': False,
|
'mesh_faceadr': False,
|
||||||
'mesh_graph': False,
|
'mesh_graph': False,
|
||||||
@@ -1259,6 +1326,7 @@ _BATCH_DIM = {
|
|||||||
'nC': False,
|
'nC': False,
|
||||||
'nJfe': False,
|
'nJfe': False,
|
||||||
'nJmom': False,
|
'nJmom': False,
|
||||||
|
'nJten': False,
|
||||||
'nM': False,
|
'nM': False,
|
||||||
'na': False,
|
'na': False,
|
||||||
'nacttrnbody': False,
|
'nacttrnbody': False,
|
||||||
@@ -1272,6 +1340,7 @@ _BATCH_DIM = {
|
|||||||
'nflexelem': False,
|
'nflexelem': False,
|
||||||
'nflexelemdata': False,
|
'nflexelemdata': False,
|
||||||
'nflexelemedge': False,
|
'nflexelemedge': False,
|
||||||
|
'nflexshelldata': False,
|
||||||
'nflexvert': False,
|
'nflexvert': False,
|
||||||
'ngeom': False,
|
'ngeom': False,
|
||||||
'ngravcomp': False,
|
'ngravcomp': False,
|
||||||
@@ -1353,6 +1422,8 @@ _BATCH_DIM = {
|
|||||||
'pair_solreffriction': True,
|
'pair_solreffriction': True,
|
||||||
'plugin': False,
|
'plugin': False,
|
||||||
'plugin_attr': False,
|
'plugin_attr': False,
|
||||||
|
'qLD_all_updates': False,
|
||||||
|
'qLD_level_offsets': False,
|
||||||
'qLD_updates': False,
|
'qLD_updates': False,
|
||||||
'qM_fullm_i': False,
|
'qM_fullm_i': False,
|
||||||
'qM_fullm_j': False,
|
'qM_fullm_j': False,
|
||||||
@@ -1398,6 +1469,9 @@ _BATCH_DIM = {
|
|||||||
'stat__meaninertia': True,
|
'stat__meaninertia': True,
|
||||||
'taxel_sensorid': False,
|
'taxel_sensorid': False,
|
||||||
'taxel_vertadr': False,
|
'taxel_vertadr': False,
|
||||||
|
'ten_J_colind': False,
|
||||||
|
'ten_J_rowadr': False,
|
||||||
|
'ten_J_rownnz': False,
|
||||||
'ten_wrapadr_site': False,
|
'ten_wrapadr_site': False,
|
||||||
'ten_wrapnum_site': False,
|
'ten_wrapnum_site': False,
|
||||||
'tendon_actfrclimited': False,
|
'tendon_actfrclimited': False,
|
||||||
|
|||||||
Reference in New Issue
Block a user