Commit Graph

115 Commits

Author SHA1 Message Date
Yuval Tassa 2f1843f4a7 Redesign the dcmotor controller: setpoint inputs, torque-space gains.
The dcmotor input block is any subset of the canonical list [pos, vel,
ff, voltage], selected with input="pos vel ff voltage" and recorded as
mjtCtrlInput bits in actuator_ctrlspec like pid. Tokens are required in
canonical order: the attribute denotes a set, the block always packs
canonically, and accepting permutations invites reading the string as a
layout choice. The mode flag in gainprm[8] is retired (reserved,
written 0).

Controller gains are now in torque space, as for pid: the controller
commands tau = kp*(q*-l) + kd*(v*-ldot) + ki*x_I + tau_ff over the
present inputs (absent setpoints frozen at zero) and converts to drive
voltage V = R/K * tau + K*ldot. The second term compensates back-EMF,
as the current loop of a real torque-mode driver does (torque commands
are current commands): commanded torque is delivered exactly until a
limit binds, and the torque-speed envelope emerges from the Vmax clamp.
The map uses the nameplate R: thermal resistance growth is not
compensated, so a hot motor under-delivers by R/R(T). A stateless
setpoint dcmotor now matches <pid> exactly, for any K and R; the old
back-EMF droop remains available as the physical behavior of the raw
voltage path. Voltage-space datasheet gains convert by K/R. Controller
inputs require a positive motor constant (the map divides by K), and
controller gains require a controller input.

ff and voltage are distinct inputs, different in kind: ff is a torque
feedforward added to the controller output, uniform with pid's ff
(feedforward in the actuator's output space), while voltage is the raw
terminal voltage of the physical device, injected downstream of the
controller and its Vmax clamp, unclamped (ctrlrange bounds it if
desired). input="voltage" is the default: the plain voltage-commanded
motor, whose behavior is unchanged by this commit. The integrator
always accumulates position error; the old velocity mode's integral
term, ki*(int(u)dt - theta), which tracked the integral of the velocity
command, is retired without replacement, keeping ki mode-independent --
commanded integrated velocity belongs to an integrator activation
state, not to controller gains. slewmax rate-limits the first controller
input -- position setpoint (rad/s), velocity setpoint (rad/s^2) or torque
feedforward (N*m/s), each a real driver feature (reference ramping,
ramped-velocity and ramped-torque input modes); the raw voltage input
is never rate-limited and slewmax requires a controller input.

input="none" selects the empty signature: the actuator owns no controls
at all (nu = 0 is now legal with actuators present) and is purely
passive -- LuGre friction, cogging and back-EMF braking as passive
joint forces. This exists because auxiliary dynamic states (the LuGre
bristle) attach to actuators, not joints. The terminal voltage is
identically zero, i.e. a shorted motor (dynamic braking); motorconst=0
decouples the electrical branch. mjINPUT_NONE is a distinct enum value
because ctrlspec = 0 means "unset, use the type default". History and
delay require an input; the controller voltage override and input read
in mj_fwdActuation are gated on a nonempty block.

The analytic velocity derivative of the controller becomes
dV/dw = -kd*R/K + K, whose second term cancels the back-EMF bias
exactly: the net damping of an unclipped torque-mode motor is -kd, and
of a voltage-mode or passive motor -K^2/R. Viewers label inputs via
mj_actuatorInputName: pos, vel, ff, voltage.

The dcmotor LaTeX design doc is updated accordingly: torque-space
units, the tau->V map and its saturation-generated envelope, the
input-block pipeline figure, and a Passive Operation section.

PiperOrigin-RevId: 965795351
Change-Id: Ibc308ca21bd6bad014e77f950ee08feaad449b73
2026-08-17 00:43:48 -07:00
Yuval Tassa 86e9860106 Rewrite box-box collision: SAT + polygon clipping + true edge-edge contacts.
Replaces the box-box collider's manifold generation and post-filtering with a
single structured implementation, and deletes the accumulated repair logic it
obsoletes. Net 319 lines out of the engine.

Algorithm:
- The separating-axis test keeps the closed-form support evaluation and chooses
  the axis of maximum separation among the 15 candidates by plain argmax.
  Edge-cross axes whose cross product has norm below rounding are skipped: in
  the nearly-parallel regime their direction is cancellation noise, previously
  the source of arbitrary-normal contacts with box-scale spurious depth. A
  winning edge axis within eight degrees of the best face axis is replaced by
  that face unless it is better by five percent (ODE's classic fudge): resting
  stacks otherwise flip between the edge and face contact codes by rounding
  noise from step to step, thrashing the solver warm start until the stack
  explodes. The substitution runs after the search rather than filtering during
  it, so a worse non-aliasing edge cannot steal the contact the substitution
  meant to give to the face.
- Face contacts clip the incident face against the reference face's side planes
  (Sutherland-Hodgman). Depth is measured along the reference normal only,
  never as a Euclidean distance between unrelated points. Contact position is
  midway between the surfaces along the normal, so its distance to either box
  is bounded by half the contact depth. Every surviving vertex of the clipped
  polygon becomes a contact, so the manifold is the actual contact patch, at
  most eight points as before.
- Edge contacts use the closest-point pair between the two supporting edge
  segments. A near-zero axis component makes the support-corner sign ambiguous;
  both signs are enumerated and the closest witness pair wins.
- Margin is an acceptance band throughout: SAT early-out and clip acceptance.
- The rounding thresholds are stated per precision. The separation tests are
  the ones that cost correctness: comparing exactly against the margin reports
  a pair overlapping by less than the rounding error of its own support
  evaluation as separated, and the boxes pass through each other. Over 239k
  overlapping pairs that is eight misses under mjUSESINGLE and none in double;
  the collider this replaces misses the same eight. Slack proportional to the
  summed half-sizes leaves five, which overlap by 7e-9 to 3e-8 of their own
  scale, below single-precision epsilon, where the boxes are not distinguishable
  from touching. Erring toward contact is the safe direction: the driver already
  excludes a contact whose distance reaches the margin.

Deleted: the conditional acceptance cascade keyed on how many points earlier
generators emitted, the u/v clamping that fabricated contacts from out-of-range
projections, the outside-box removal filter and its missing-fallback hole,
exact-floating-point deduplication, and the edge-path depth clamp. The
structure makes those bug classes unrepresentable rather than filtered: depth
is a projection by construction. Every reported depth is the exact support
overlap along the contact's own normal, verified over 246k overlapping poses to
within two ulps; the face preference costs direction, not depth, deviating from
the minimum-translation axis by at most 8.1 degrees and 5.3% of its depth.

The previous implementation is preserved verbatim as mjc_BoxBoxLegacy in
test/engine/boxbox_legacy.c, a static library that only the box-box tests link,
so the claims above are measured rather than asserted. It needs no private
engine symbols. Three tests compare against it:

- NearAlignedManifoldIsExact sweeps the relative angle of a resting pair across
  the regime where the edge-cross axes degenerate into noise, pinning the full
  clipped polygon and a contact normal equal to the face normal exactly, where
  the previous collider drifts off it.
- AlignedTowerStands settles a twenty-box tower, which comes to rest four
  million times quieter than under the previous collider, which never settles
  and eventually topples.
- ShallowOverlapSurvivesRounding pins a pair overlapping by 7e-8 of its scale,
  reported as separated under mjUSESINGLE without slack on the separation tests.

On stacks of plates across aspect ratios from 4:1 to 25:1, five layouts each,
the collider settles into a tight band of 1e-4 to 3e-4 while the previous one
intermittently blows up to as much as 2.6e-2.

engine_collision_box_fuzz_test.cc cross-validates randomized poses against
GJK/EPA on identical box meshes and against a spherical-Fibonacci support
sweep, with hard gates per sample: no phantom penetration, no missed contact at
zero margin, no contact deeper than the true depth, contacts within half their
own depth of both boxes, and one normal per manifold. Both invocations run in
about a second.

EdgeContactAtDepthBound's tolerance widens to the five percent design band; the
three-orders-of-magnitude depth bug it pins is still caught, the deviation
being 0.13 percent of the depth.

The 100-box pile benchmark steps about 7% faster with 1.6% fewer contacts.

PiperOrigin-RevId: 965114952
Change-Id: Ie98cdcce8d1aed3ff2da938cb29703fd9c241258
2026-08-15 01:45:56 -07:00
Kyle Bayes 83e621d771 Implement mesh extrema in a 3x3x3 grid corresponding to each feature of a unit cube. These are used as seeds for a better initial point in mesh hill climbing with up to a 2x speedup in mjc_Convex.
PiperOrigin-RevId: 959645299
Change-Id: I032ae534704e0cc440ddb7691fd21a29a359f521
2026-08-05 07:22:48 -07:00
Yuval Tassa 072e963fa0 Add SO3 transmission and native orientation actuator.
https://youtu.be/17XpwnqyCXs

New transmission type mjTRN_SO3: a relative orientation, targeting a ball
joint or a site+refsite pair. It is the first transmission with more than
one force output: its length is the norm of the expmap vector of the
relative rotation and its moment axes are the 3 rows of the
relative rotational Jacobian, without projecting onto per-actuator gears.

New force law mjGAIN_SO3/mjBIAS_SO3: a geodesic PD servo, force =
kp * log(q_current^-1 * q_target) - kv * velocity, exact for arbitrary axis
combinations with a unique equilibrium at every commanded orientation.
Error, moment rows and velocity all live in the child frame (joint or
site): the right-difference error is the gradient of the geodesic
potential in that frame. The parent-frame (left) error is not: driving
child-frame torques with it pumps energy at large angles, settling into
steady-spinning limit cycles (the SO3LargeAngleConvergence test). The
integrator variant stores the 3D orientation setpoint in act (actnum = 3,
re-anchored to a bounded representative at integration time). Exposed in
MJCF as <orientation joint=|site=+refsite= kp kv|dampratio>, or via
<general gaintype="so3" biastype="so3">.

The setpoint input has two charts: an expmap target (3 controls, default)
or a quaternion target (4 controls) -- <orientation input="quat">, the
first actuator with different input and output widths. The signature is
recorded in a new per-actuator field actuator_ctrlspec (mjtCtrlChart),
whose meaning is scoped by the gain type the way gain/bias parameters are;
ctrlnum is derived from it at compile time and remains the layout
authority. An explicit field rather than width inference or a prm slot:
width-as-chart cannot express same-width signatures (upcoming servo input
subsets), and prm slots are the input_mode pattern this stack retires.
The force law normalizes the commanded quaternion, making it scale- and
antipodally-invariant. The all-zero ctrl still maps to the identity via
mju_normalize4, but it is a degenerate point (a nudge of any component
commands a half-turn), so quat inputs reset to the identity quaternion:
new mj_resetCtrl sets neutral ctrl values (zero, except qw = 1), called
by mj_resetData and the viewers' Clear All. The quat chart is
restricted to dyntype 'none': integrating a quaternion setpoint linearly
is not meaningful on the manifold. New mjsActuator.ctrlspec field carries
the signature through the spec and XML round-trip.

Actuator sensors (actuatorpos/vel/frc) now report one value per force
output; dim = 3 on an SO3 actuator.

As the first actuator with nu != nactuator, this commit also makes the
viewers multi-input aware: the control sliders in simulate and studio,
which indexed per-actuator arrays by control index (out of bounds on
this model class), are generated per control and labeled with the
actuator name plus an input suffix ("orient/qw"), via the new
introspection helper mj_actuatorInputName -- the single source of truth
for input names, extended by each new multi-input type (quaternion
components are w-first: qw, qx, qy, qz). Slider ranges now honor a
defined ctrlrange even when ctrllimited is false: range is the UI hint,
limited is the clamp -- wrapped and expmap setpoints are unbounded but
still want finite sliders, while quat components are truly bounded.

The rotational demo model is orientation.xml under
test/engine/testdata/actuation/, upgraded to a three-way contrast:
per-axis wrapped servos vs an expmap-commanded vs a quat-commanded
orientation actuator, on identical checker-textured boxes. It is loaded
by the mixed-axis contrast and input-name tests, and doubles as the
viewer test model (slider groups of 3 independent, 3 grouped, 4 grouped).

PiperOrigin-RevId: 951607063
Change-Id: If235dba8e2f2ca72672e7c62531a27e967c6a373
2026-07-21 11:36:13 -07:00
Yuval Tassa 4787c8094c Add geom surfacevel: zero-dof conveyors, treadmills and turntables.
https://www.youtube.com/watch?v=PdSdrqhSiZA

The new geom attribute surfacevel (6 numbers: linear and angular velocity in the geom's local frame, angular about the geom frame origin) specifies the velocity of the geom's surface material relative to the geom frame. The relative surface velocity of the two geoms is added to the tangential contact rows of efc_vel in mj_referenceConstraint, so friction drives touching bodies toward the motion of the surface: objects on a conveyor are transported at belt speed, turntables impart omega x r with torsional spin-up for condim >= 4, and surface velocities compose with each other and with body motion. The component along the contact normal is projected out: probe experiments showed that velocity-space emission chatters mass-independently and ingestion merely deepens penetration; normal-direction effects belong to force-space features.

surfacevel is interpreted in the geom frame as authored: for mesh geoms, whose compiled frame absorbs the mesh centering and principal-axes transform, the compiler re-expresses the authored value in the compiled frame.

No special interaction with sleeping: objects being transported do not fall asleep because they are moving; objects at rest on an active surface may sleep like any other resting object.

Includes showcase models (model/surfacevel/): a luggage carousel whose ring is a spinning square-profile supertorus fed by a cascade of belts with matched spinning end rollers, bags dropping in and circulating indefinitely; and a treadmill with a passive humanoid.

PiperOrigin-RevId: 948647785
Change-Id: I0c6559a91cc7ece1237eb8ac2e51986e7342d962
2026-07-15 17:58:17 -07:00
Kyle Bayes 2444defc63 Support arbitrary large meshes in multiccd by reusing EPA memory.
PiperOrigin-RevId: 947709621
Change-Id: Idc4f168434b9d0a8555c0bed989adb0e99770a78
2026-07-14 08:48:25 -07:00
Yuval Tassa c499f7f2b0 Add Nesterov momentum with O'Donoghue-Candès restarts to PGS solver (~2x speedup)
Benchmark on `2humanoid100.xml` (nefc=1785, nv=654):

```
Convergence at fixed iteration count (mean relative error vs Newton):
  20 iters: 2.98e-03 vs 1.54e-02 (5.2x better)
  40 iters: 8.14e-05 vs 2.60e-03 (32x better)
  80 iters: 1.17e-07 vs 1.77e-04 (1500x better)

Pipeline throughput (tolerance=1e-8, islands disabled):
  Nesterov: 243 steps/s, 46 iters/step
  Baseline: 151 steps/s, 95 iters/step
  Solver speedup: 1.8x, overall step speedup: 1.6x

Pipeline throughput (tolerance=1e-8, islands enabled):
  Nesterov: 306 steps/s, 442 iters/step
  Baseline: 175 steps/s, 966 iters/step
  Solver speedup: 2.1x, overall step speedup: 1.7x
```

PiperOrigin-RevId: 936610759
Change-Id: I2978e8bd545971d9151005623967e5cf0ad125cc
2026-06-23 05:52:14 -07:00
Yuval Tassa f712eed4ce Allow flex sleeping
PiperOrigin-RevId: 917817500
Change-Id: Ia3bd5e52e7c2eaa3f70c81352d82c130b1d357f6
2026-05-19 07:15:27 -07:00
Yuval Tassa a4e49f2dff Margin and gap redesign (breaking change)
PiperOrigin-RevId: 914329812
Change-Id: I905665e4c1965bdb8b90587e5b1277cfbfe5cce0
2026-05-12 09:43:43 -07:00
Yuval Tassa 412cee2059 Add Jdot correction for connect and weld constaints
Measured reduction in constraint violations before/after this change:

| Model | Correction ON (Avg Viol) | Correction OFF (Avg Viol) | Reduction |
| :--- | :--- | :--- | :--- |
| `jdotv_connect_2d.xml` | 3.959e-4 | 1.699e-3 | **76.7%** |
| `jdotv_connect_3d.xml` | 1.399e-3 | 5.493e-3 | **74.5%** |
| `jdotv_weld_3d.xml` | 9.472e-3 | 1.148e-2 | **17.5%** |

PiperOrigin-RevId: 899137525
Change-Id: Ic3e33764ebd64239bab916289c23d80c3da0b51b
2026-04-13 12:48:03 -07:00
Yuval Tassa c004d144d1 Correct DC motor derivative calculation and enforce actearly.
PiperOrigin-RevId: 898983657
Change-Id: I008529eacf3e400696d26bd3a52a4cf4c1c12225
2026-04-13 10:56:58 -07:00
Yuval Tassa 81720071b8 Changes to dcmotor:
- Remove `lugre:viscous`, should now be added directly to actuator `damping`. Trying to do this for the user was incompatible with default inheritance (compounding instead of overriding).
- Move voltage limiting from the `saturation` to the `controller` attribute.
- Fix indexing issues in default inheritance.

PiperOrigin-RevId: 897087642
Change-Id: I5388c2633e15c7e223992e7eb5d6a28db75a6438
2026-04-09 06:52:45 -07:00
Yuval Tassa 70a7647ad9 Add <dcmotor> actuator and related docs and tests.
PiperOrigin-RevId: 892927987
Change-Id: I38ed6412801341ba03ddf5fe7b93a6081df24d37
2026-04-01 07:50:23 -07:00
Yuval Tassa efae9157a7 Polynomial stiffness and damping https://youtu.be/aKa3ZlEF9_Y
PiperOrigin-RevId: 884607673
Change-Id: If8088dbf37fed1055304778a7eb84dec52cba920
2026-03-16 13:25:25 -07:00
Yuval Tassa f3ad0eff2b Fix body category check for mocap body descendants in visualization.
PiperOrigin-RevId: 856179240
Change-Id: I29f4758fee0ff3b16d0b9f452c28e640b5558993
2026-01-14 06:06:55 -08:00
Yuval Tassa 70bc7be4bc Add additional data fields that can be reported by rangefinder sensors.
PiperOrigin-RevId: 848316991
Change-Id: Idbf7ba81b4da711a22c23302c8782ab2b0b98d82
2025-12-23 15:33:00 -08:00
Yuval Tassa 9d646e6548 Extend rangefinder sensor to support cameras.
PiperOrigin-RevId: 848255889
Change-Id: I6e1a9ed13d29d2242558625a47e24e47ad6e87db
2025-12-23 12:04:49 -08:00
Yuval Tassa 223ba99ec2 Add mju_rayFlexNormal (not exposed in public header)
PiperOrigin-RevId: 847746174
Change-Id: Ia8f597d296bf6a3eed9bd48b1c39b2ff2b5fcf90
2025-12-22 06:49:22 -08:00
Yuval Tassa c7f5766345 Add frustum visualization for orthographic cameras.
PiperOrigin-RevId: 847698917
Change-Id: I13633e8ba2d4718b127a5838c404ab74c6180e3d
2025-12-22 03:43:54 -08:00
Yuval Tassa b8a4ac5d48 Refactor camera orthographic attribute to projection enum.
PiperOrigin-RevId: 847069028
Change-Id: I7f686fe654e9b56519cab8bd2f37c9cc40091d3f
2025-12-20 03:28:29 -08:00
Yuval Tassa 47e35e632f Add a test for equivalence of different solvers.
PiperOrigin-RevId: 845777469
Change-Id: I76a162b71bea349cca3472001360181654a5d571
2025-12-17 08:21:52 -08:00
Yuval Tassa c064abc3da Change row-flipping logic for heightfields.
Move row-flipping logic from `mjCModel::CopyBack` to `mjXWriter`.

PiperOrigin-RevId: 842220322
Change-Id: I6fb09db6c9e8689f6e435f82f58dd3e7c4314478
2025-12-09 07:02:21 -08:00
Yuval Tassa f65c1cdfd1 Add mj_raySdfNormal (not exposed in public header)
PiperOrigin-RevId: 842178540
Change-Id: I5d2db555e9b6c0fa0daaa8bc14c7781663e4c94e
2025-12-09 04:43:39 -08:00
Yuval Tassa ad24889bb9 Add mj_rayMeshNormal (not exposed in public header)
PiperOrigin-RevId: 838707353
Change-Id: If31d2454e0668f750bcba21ee42f81ef962e9097
2025-12-01 04:13:52 -08:00
Yuval Tassa 7caa3d6703 Add names to some sensors in sleep test XML.
PiperOrigin-RevId: 837611931
Change-Id: Ib077765d795037bdd0d32d19e1c7d5bf9b256d51
2025-11-27 14:09:21 -08:00
Yuval Tassa d1317fd1a5 Add ray normal computation for primitives (currently private)
PiperOrigin-RevId: 834294539
Change-Id: I176f13a8f91dede589338fc44e099a16bac0b580
2025-11-19 08:01:02 -08:00
Yuval Tassa b8512b9d1f Fix bug related to sleeping static children of mocap bodies.
PiperOrigin-RevId: 831376685
Change-Id: I8891a1d7dc6efc037e9ade5c7e8dd5c35c7e455e
2025-11-12 07:20:03 -08:00
Yuval Tassa 22c0b68903 Improve logic and documentation for sleeping sensors
PiperOrigin-RevId: 830891115
Change-Id: Ife8309b165c085b54c9f668d825d69ed12a9a8f0
2025-11-11 06:45:56 -08:00
Taylor Howell 883836848a Fix box-box distance computation.
PiperOrigin-RevId: 829431553
Change-Id: I9e28bc8eb7687c3c83e5ff68c65e93d8a07378a9
2025-11-07 07:37:03 -08:00
Yuval Tassa 769f37b653 Implement sleeping in engine
PiperOrigin-RevId: 829361787
Change-Id: I6f64d8e25c4248cf32c18cd94d37ff5def78946e
2025-11-07 03:33:07 -08:00
Kyle Bayes bdccbcc60a Add multiccd fields to MJX and add simplex box-mesh model.
PiperOrigin-RevId: 813190617
Change-Id: Idc450da59d6420825077a642719525750f6551ec
2025-09-30 03:40:29 -07:00
Yuval Tassa fe8384b6c5 Visualize joint and tendon limits by re-coloring.
PiperOrigin-RevId: 811590674
Change-Id: I5b65f2294a4bcda3c321fb51ebf29501bd0d416d
2025-09-25 19:02:26 -07:00
Taylor Howell d616f11508 Remove references to deprecated nconmax and njmax.
PiperOrigin-RevId: 809987304
Change-Id: I4109497fe108234dd77011d61eb3ef833e6ae111
2025-09-22 06:28:41 -07:00
Yuval Tassa 7443e685ac Allow contact sensor subtree1/subtree2 to be any body.
PiperOrigin-RevId: 799632590
Change-Id: If9cd6c5a3a5f83d89ae024a8f64232ab1f1d603a
2025-08-26 11:00:39 -07:00
Yuval Tassa 996f0040fd Add built-in sphere mesh.
PiperOrigin-RevId: 791162850
Change-Id: I573a414727e79f1a495e0f2282b2faff48ab3443
2025-08-05 05:05:05 -07:00
Alessio Quaglino 89f4789085 Add mjs_makeMesh to create a builtin mesh.
PiperOrigin-RevId: 788538127
Change-Id: I999733399a1a0da07b0f915f34d31364ab8b3b52
2025-07-29 11:31:18 -07:00
Yuval Tassa 576a34bcf2 Add netforce reduction to contact sensor.
PiperOrigin-RevId: 783020713
Change-Id: I0d11ccc4e1fd16d07e6f116d64a26485346d9cf1
2025-07-14 13:27:43 -07:00
Yuval Tassa d0e4771c8c Add contact sensor.
PiperOrigin-RevId: 783011982
Change-Id: Ica56fe9d520fa1d1ee7338e09148b1a55a049912
2025-07-14 13:03:35 -07:00
Yuval Tassa e6c5715903 Add insidesite sensor for detecting when an object is inside the volume of a site.
PiperOrigin-RevId: 780993257
Change-Id: I2dcfc840d222680adc3b934344a0819f4d78b6eb
2025-07-09 04:56:42 -07:00
Yuval Tassa ecb769fc3a Refactor islands to be memory contiguous.
PiperOrigin-RevId: 755803476
Change-Id: I41972b07e0d5ef5d0117c94f565b93367b87458b
2025-05-07 05:06:27 -07:00
Kyle Bayes b1f8d444f2 Fix bug in replaceSimplex3 in nativeccd.
PiperOrigin-RevId: 746014344
Change-Id: I93b32ab5f67ee48ab72238de53f7cda07638cb79
2025-04-10 07:04:27 -07:00
Taylor Howell 96dda6ea75 Add tendon actuator force limits and tendon actuator force sensor.
PiperOrigin-RevId: 745096883
Change-Id: Ib9acb727fbbfc6b0b0323ee6a889053a7a878056
2025-04-08 05:16:35 -07:00
Yuval Tassa d05251af2a Add tendon armature
PiperOrigin-RevId: 743939992
Change-Id: I587214f5d6fabbc0cc273c33d82decbe9ad8f919
2025-04-04 07:44:04 -07:00
Yuval Tassa 05f3e914b0 Improve armature documentation
PiperOrigin-RevId: 742583729
Change-Id: I18d1c95a91f4d70b842c680d4a0f4d0b04476894
2025-04-01 01:16:58 -07:00
Yuval Tassa c931565fdc Add internal functionmj_tendonDot: time derivative of tendon Jacobian for one tendon.
Notes:
- Currently always uses dense math, even for sparse models. This should be easy to change in the future.
- Does not support geom wrapping. This is possible but harder, requires derivatives of mju_wrap.
PiperOrigin-RevId: 740378741
Change-Id: Id39ef2c4bfbb7ee11ec33c97d7d83140441cdab2
2025-03-25 09:36:30 -07:00
Kyle Bayes 024616345d Support edge contacts with multiccd in nativeccd.
PiperOrigin-RevId: 730489114
Change-Id: I02847d84bbc15a1526391d5e1b7109ab83ea4a59
2025-02-24 09:48:43 -08:00
Alessio Quaglino c52d1b3941 Remove the particle composite (replaced by replicate).
PiperOrigin-RevId: 730089997
Change-Id: If8d18fb56ae01241e76f84dbf7951e034026d829
2025-02-23 03:14:11 -08:00
Alessio Quaglino 0fcd20f0da Remove grid from composite types.
Replaced it with flexcomp in the models.

PiperOrigin-RevId: 730070619
Change-Id: Icbc69e4c6784c6252743f689a1eafb6482d0c393
2025-02-23 01:31:41 -08:00
Yuval Tassa 08edde5fd8 Add test for armature, model will be used in upcoming improved documentation for armature.
PiperOrigin-RevId: 719916567
Change-Id: I7f74bd3c3864f43f5f68d458d5b128cfee1d7e6c
2025-01-26 12:01:12 -08:00
Yuval Tassa ec322641b7 Fix bug in mj_mulM2.
PiperOrigin-RevId: 710756899
Change-Id: I30c0725859ba0f1a59750dc89eebb9eba84fa71b
2024-12-30 11:14:56 -08:00