Skip to content

Commit 3ee1179

Browse files
authored
Merge pull request #236 from thowell/tendon_friction
add tendon friction
2 parents 703f3e0 + e665060 commit 3ee1179

File tree

4 files changed

+113
-6
lines changed

4 files changed

+113
-6
lines changed

mujoco_warp/_src/constraint.py

Lines changed: 96 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ def _efc_equality_tendon(
437437

438438

439439
@wp.kernel
440-
def _efc_friction(
440+
def _efc_friction_dof(
441441
# Model:
442442
opt_timestep: float,
443443
dof_invweight0: wp.array2d(dtype=float),
@@ -461,7 +461,6 @@ def _efc_friction(
461461
efc_aref_out: wp.array(dtype=float),
462462
efc_frictionloss_out: wp.array(dtype=float),
463463
):
464-
# TODO(team): tendon
465464
worldid, dofid = wp.tid()
466465

467466
if dof_frictionloss[worldid, dofid] <= 0.0:
@@ -500,6 +499,72 @@ def _efc_friction(
500499
)
501500

502501

502+
@wp.kernel
503+
def _efc_friction_tendon(
504+
# Model:
505+
nv: int,
506+
opt_timestep: float,
507+
tendon_solref_fri: wp.array2d(dtype=wp.vec2),
508+
tendon_solimp_fri: wp.array2d(dtype=vec5),
509+
tendon_frictionloss: wp.array2d(dtype=float),
510+
tendon_invweight0: wp.array2d(dtype=float),
511+
# Data in:
512+
qvel_in: wp.array2d(dtype=float),
513+
ten_J_in: wp.array3d(dtype=float),
514+
# In:
515+
refsafe_in: int,
516+
# Data out:
517+
nf_out: wp.array(dtype=int),
518+
nefc_out: wp.array(dtype=int),
519+
efc_worldid_out: wp.array(dtype=int),
520+
efc_id_out: wp.array(dtype=int),
521+
efc_J_out: wp.array2d(dtype=float),
522+
efc_pos_out: wp.array(dtype=float),
523+
efc_margin_out: wp.array(dtype=float),
524+
efc_D_out: wp.array(dtype=float),
525+
efc_aref_out: wp.array(dtype=float),
526+
efc_frictionloss_out: wp.array(dtype=float),
527+
):
528+
worldid, tenid = wp.tid()
529+
530+
frictionloss = tendon_frictionloss[worldid, tenid]
531+
if frictionloss <= 0.0:
532+
return
533+
534+
efcid = wp.atomic_add(nefc_out, 0, 1)
535+
wp.atomic_add(nf_out, 0, 1)
536+
efc_worldid_out[efcid] = worldid
537+
538+
Jqvel = float(0.0)
539+
540+
# TODO(team): parallelize
541+
for i in range(nv):
542+
J = ten_J_in[worldid, tenid, i]
543+
efc_J_out[efcid, i] = J
544+
Jqvel += J * qvel_in[worldid, i]
545+
546+
_update_efc_row(
547+
opt_timestep,
548+
refsafe_in,
549+
efcid,
550+
0.0,
551+
0.0,
552+
tendon_invweight0[worldid, tenid],
553+
tendon_solref_fri[worldid, tenid],
554+
tendon_solimp_fri[worldid, tenid],
555+
0.0,
556+
Jqvel,
557+
frictionloss,
558+
tenid,
559+
efc_id_out,
560+
efc_pos_out,
561+
efc_margin_out,
562+
efc_D_out,
563+
efc_aref_out,
564+
efc_frictionloss_out,
565+
)
566+
567+
503568
@wp.kernel
504569
def _efc_equality_weld(
505570
# Model:
@@ -1477,7 +1542,7 @@ def make_constraint(m: types.Model, d: types.Data):
14771542

14781543
if not (m.opt.disableflags & types.DisableBit.FRICTIONLOSS.value):
14791544
wp.launch(
1480-
_efc_friction,
1545+
_efc_friction_dof,
14811546
dim=(d.nworld, m.nv),
14821547
inputs=[
14831548
m.opt.timestep,
@@ -1503,6 +1568,34 @@ def make_constraint(m: types.Model, d: types.Data):
15031568
],
15041569
)
15051570

1571+
wp.launch(
1572+
_efc_friction_tendon,
1573+
dim=(d.nworld, m.ntendon),
1574+
inputs=[
1575+
m.nv,
1576+
m.opt.timestep,
1577+
m.tendon_solref_fri,
1578+
m.tendon_solimp_fri,
1579+
m.tendon_frictionloss,
1580+
m.tendon_invweight0,
1581+
d.qvel,
1582+
d.ten_J,
1583+
refsafe,
1584+
],
1585+
outputs=[
1586+
d.nf,
1587+
d.nefc,
1588+
d.efc.worldid,
1589+
d.efc.id,
1590+
d.efc.J,
1591+
d.efc.pos,
1592+
d.efc.margin,
1593+
d.efc.D,
1594+
d.efc.aref,
1595+
d.efc.frictionloss,
1596+
],
1597+
)
1598+
15061599
# limit
15071600
if not (m.opt.disableflags & types.DisableBit.LIMIT.value):
15081601
limit_ball = m.jnt_limited_ball_adr.size > 0

mujoco_warp/_src/io.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,6 @@ def put_model(mjm: mujoco.MjModel) -> types.Model:
4444
if mjm.nflex > 1:
4545
raise NotImplementedError("Only one flex is unsupported.")
4646

47-
if mjm.tendon_frictionloss.any():
48-
raise NotImplementedError("Tendon frictionloss is unsupported.")
49-
5047
if mjm.geom_fluid.any():
5148
raise NotImplementedError("Ellipsoid fluid model not implemented.")
5249

@@ -503,8 +500,11 @@ def create_nmodel_batched_array(mjm_array, dtype):
503500
tendon_limited_adr=wp.array(np.nonzero(mjm.tendon_limited)[0], dtype=wp.int32, ndim=1),
504501
tendon_solref_lim=create_nmodel_batched_array(mjm.tendon_solref_lim, dtype=wp.vec2f),
505502
tendon_solimp_lim=create_nmodel_batched_array(mjm.tendon_solimp_lim, dtype=types.vec5),
503+
tendon_solref_fri=create_nmodel_batched_array(mjm.tendon_solref_fri, dtype=wp.vec2f),
504+
tendon_solimp_fri=create_nmodel_batched_array(mjm.tendon_solimp_fri, dtype=types.vec5),
506505
tendon_range=create_nmodel_batched_array(mjm.tendon_range, dtype=wp.vec2f),
507506
tendon_margin=create_nmodel_batched_array(mjm.tendon_margin, dtype=float),
507+
tendon_frictionloss=create_nmodel_batched_array(mjm.tendon_frictionloss, dtype=float),
508508
tendon_length0=create_nmodel_batched_array(mjm.tendon_length0, dtype=float),
509509
tendon_invweight0=create_nmodel_batched_array(mjm.tendon_invweight0, dtype=float),
510510
wrap_objid=wp.array(mjm.wrap_objid, dtype=int),

mujoco_warp/_src/types.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,8 +769,11 @@ class Model:
769769
tendon_limited_adr: addresses for limited tendons (<=ntendon,)
770770
tendon_solref_lim: constraint solver reference: limit (nworld, ntendon, mjNREF)
771771
tendon_solimp_lim: constraint solver impedance: limit (nworld, ntendon, mjNIMP)
772+
tendon_solref_fri: constraint solver reference: friction (nworld, ntendon, mjNREF)
773+
tendon_solimp_fri: constraint solver impedance: friction (nworld, ntendon, mjNIMP)
772774
tendon_range: tendon length limits (nworld, ntendon, 2)
773775
tendon_margin: min distance for limit detection (nworld, ntendon,)
776+
tendon_frictionloss: loss due to friction (nworld, ntendon,)
774777
tendon_length0: tendon length in qpos0 (nworld, ntendon,)
775778
tendon_invweight0: inv. weight in qpos0 (nworld, ntendon,)
776779
wrap_objid: object id: geom, site, joint (nwrap,)
@@ -1011,10 +1014,14 @@ class Model:
10111014
tendon_num: wp.array(dtype=int)
10121015
tendon_limited: wp.array(dtype=int)
10131016
tendon_limited_adr: wp.array(dtype=int)
1017+
10141018
tendon_solref_lim: wp.array2d(dtype=wp.vec2)
10151019
tendon_solimp_lim: wp.array2d(dtype=vec5)
1020+
tendon_solref_fri: wp.array2d(dtype=wp.vec2)
1021+
tendon_solimp_fri: wp.array2d(dtype=vec5)
10161022
tendon_range: wp.array2d(dtype=wp.vec2)
10171023
tendon_margin: wp.array2d(dtype=float)
1024+
tendon_frictionloss: wp.array2d(dtype=float)
10181025
tendon_length0: wp.array2d(dtype=float)
10191026
tendon_invweight0: wp.array2d(dtype=float)
10201027
wrap_objid: wp.array(dtype=int)

mujoco_warp/test_data/constraints.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@
7777
</body>
7878
</worldbody>
7979

80+
<tendon>
81+
<fixed name="tendon_1" frictionloss=".1">
82+
<joint joint="joint3" coef=".1"/>
83+
<joint joint="joint4" coef="-.2"/>
84+
</fixed>
85+
</tendon>
86+
8087
<equality>
8188
<connect name="c_site" site1="site0" site2="site1"/>
8289
<connect name="connect" body1="anchor1" body2="beam1" anchor="1 0 -1" />

0 commit comments

Comments
 (0)