- Load settings prior to first frame so dockspace layout restores reliably.
- Save settings on exit in App::~App().
- Persist and restore open/closed state of collapsible sections.
PiperOrigin-RevId: 966657100
Change-Id: I64fb5d02912bb36d096d7ac26ce8e0de03e6617b
The timestep, the solver tolerances, and impratio span several orders of
magnitude, where a linear +/- step is useless. Add ImGui_LogStepper, whose
buttons walk a "well-tempered" logarithmic ladder of round numbers that
closes each decade on a power of ten (see WellTemperedStep). It lays out
like ImGui's own InputScalar stepper -- field, then the - / + buttons, then
the label.
Apply it to the timestep, Tolerance, the LS/Noslip/CCD/Sleep tolerances,
and Imp Ratio. Strictly-positive quantities for which zero is meaningful
(the tolerances) take a zero_below floor: the ladder's bottom rung is 0, so
stepping down snaps to zero and stepping up off zero returns to the floor.
The timestep and impratio, which never want zero, leave it unset.
PiperOrigin-RevId: 965888812
Change-Id: I823e60913ecb2be2cade96baa5bf7de9e2334d5a
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
Also add a detailed architectural comment that might be useful in future.
PiperOrigin-RevId: 965500329
Change-Id: Ia6a2a9137f07f726838b0acb28039a394db0efa2
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
- Parallelize asset prefetching (max 4 workers) with retry logic and on-screen error banner, replacing silent failures and cryptic WASM out-of-bounds crashes with explicit missing-file errors.
- Support binary Uint8Array/ArrayBuffer in C++ asset registry via typed_memory_view, preventing Embind string coercion from corrupting binary shader packages into ASCII text.
- Automatically glob .mat files in CMake instead of maintaining a manual list.
- Add missing reflection materials to prefetch arrays.
- Disable caching for index.html in web server so template/script updates apply on normal page reload without stale cache issues, the file is small so caching had a negligible upside.
- Add null resource and payload validation in ObjectManager::LoadMaterial before constructing Filament materials.
PiperOrigin-RevId: 963364509
Change-Id: I7de79df6a5cede4e54683415ee193f1c5a665286
Add public mjprofile.h header with MJ_PROFILE_* macros that get compiled out if Tracy is not enabled.
Integrate Tracy into engine macro timers and build configurations.
PiperOrigin-RevId: 962329763
Change-Id: Iac9d8f9ff0d909beea212a7aa8a6a3dcb512010f
The discrete collision pipeline generates contact points at a configuration;
this module prices gaps along trajectories: differentiable vertex-triangle,
edge-edge and vertex-geom distance kernels with closest-point barycentrics,
swept-volume candidate generation over the flex bounding-volume hierarchy,
per-pair gap evaluation with the gradient's vertex weights, and a conservative
advancement that bounds each contact pair's time of impact.
Engine-internal, with no consumer in this change: it is the groundwork for
continuous-contact (IPC-style) solvers for flex, which will arrive as callers.
The mjcPair type carries the geometric identity of a candidate pair only;
solver state (multipliers, ages) and cached linearizations belong to the
consumer. The two lengths the module needs -- the standoff cap and the
detection band -- are caller-supplied parameters, not constants.
Flex-flex pairs measure their gap at the midsurface rather than skin-to-skin:
where mesh geometry is tighter than the combined radii (a string threaded
through a hem) a skin gap is permanently negative and the pair would be
discarded as invalid, losing CCD coverage exactly where tunneling is likeliest.
The broad phase adds the radii back into its reach, so detection range is
unchanged.
Tests cover the distance kernels, the geom sharp features, the pair gap with
its gradient checked by central differences at every involved vertex, the
conservative advancement (the analytic cap on a crossing sweep, the
conservative closing-rate bound, the small-motion early-out), and candidate
generation on stacked cloths (pairs within reach found, distant ones not).
PiperOrigin-RevId: 962197295
Change-Id: I90e017f4580a288b2a7d341830077fc273c9acde
This change refactors the Python API to use the term "plugins" instead of "handlers" for classes containing decorated handler methods. The term handler is still used for an annotated method of a plugin class that handles a specific message type. Also improved some documentation.
PiperOrigin-RevId: 962150099
Change-Id: I34a8cc410cd784b088605490cfa3baccea5c9e71
Startblock:
* // Put other blockers before this line to avoid churning.
* has lgtm
* is approved
* and then
* all comments are resolved
* and then
PiperOrigin-RevId: 961854282
Change-Id: I9d323a8ef9f36ffe69cc62d449849eac82dc6858
Equivalent JAX retraces rebuilt flattened wrapper functions, causing
Warp to register a new FFI callable for every trace.
Reuse callables with matching structural configurations while keeping
distinct shim functions isolated. This keeps Warp's registry and graph
cache effective without changing callback lifetime.
Document the structural key and lock scope so future changes preserve
the cache's intended boundaries.
Signed-off-by: Eric Shi <ershi@nvidia.com>
Contact of a flex with `passive` collisions enabled was applied as an
explicit spring of fixed stiffness 1e4, which the timestep bounds: any
stiffness worth having oscillates faster than the step can resolve, so
the force was too soft to keep sheets apart and interpenetration was
routine.
Carry its curvature in the effective metric M + K instead, alongside the
flex's own stretch and bending stiffness. The contact block k*J^T*J is
appended to the per-vertex candidate list already assembled for the flex
stencils, so it costs additional entries in an existing matrix rather
than a new one, and the accompanying shift -h*K*v is what damps the
stiff modes. At a 2 ms timestep this holds roughly 50x the stiffness an
explicit force of the same step could.
With the timestep no longer setting the bound, the stiffness is chosen
as a natural frequency scaled by the participating vertex mass rather
than left at a fixed 1e4, so one value suits models of any scale.
Passive handling is scoped to contacts whose every dof is a flex vertex
carried by the metric: flex against flex, flex against itself, and flex
against static geometry, which contributes no dofs of its own. For those
the Hessian is assembled in full. Contact with a body that can move
would have that body's dofs dropped from it, and is left on the
constraint solver.
The feature now requires an integrator whose constraint solve runs in
that metric, and is rejected with an error otherwise.
Add model/flex/drape.xml as the example model, replacing sphere_passive,
whose contacts no longer demonstrated the feature.
This change introduces parallel chunked downloading for large model files (.mjb) directly into WASM linear memory, enables model loading without full page reloads and reduces memory overhead.
Key changes:
- Implement a chunked model endpoint in the Python web server to support range requests.
- Add parallel chunked fetching in the frontend with retry logic and a single-fetch fallback.
- Increase initial WASM memory to 3 GB to accommodate large models and prevent heap fragmentation.
- Support in-place model reloading in the C++ client, including texture cache invalidation when the Filament context is recreated.
- Display a model download progress bar and model parsing/loading banner to the UI.
- Fixes model drag and drop (caused by typo in sessionId, corrected to session_id).
PiperOrigin-RevId: 960249236
Change-Id: Icac89e6a4ca099882aaf9b111744c1b6ab0cc6c1
Add an optional `const char* args` field to `mjResource` to allow passing
resource arguments/hints (such as requested channel count or encoding options)
to resource decoders and encoders.
PiperOrigin-RevId: 959774058
Change-Id: Icc41a2bb3895fef24f98c5fa9a77cdad092a6bc7
This avoids unnecessarily resetting the bvh_active flags when the collision driver returns early due to disabled constraints, disabled contacts, or having fewer than two bodies/flexes.
PiperOrigin-RevId: 959531283
Change-Id: I85caf054b06e3be1018d710f9ab762627fc3356a
The new spotlight attribute softness (real in [0, 1], default 0) is the
fraction of the cone, measured inward from the cutoff, over which
intensity falls to zero. It is used by physically-based lighting models;
the Phong model's corresponding knob remains exponent.
The filament renderer previously hardcoded the inner cone angle to 0,
making the entire beam penumbra: the shader attenuates by the squared
smoothstep ((cos(theta) - cos(outer)) / (cos(inner) - cos(outer)))^2, so
a cutoff-25 spot delivered its rated candela only exactly on-axis and
about a third of it averaged over the light pool, with the deficit
shrinking as the cutoff widens. The inner angle is now
(1 - softness) * cutoff, so at the default the light delivers its full
intensity everywhere inside the cone and illuminance follows E = I/d^2
independent of the cutoff. Setting softness to 1 reproduces the previous
appearance exactly (verified bit-identical), which is the migration path
for models tuned against the old behavior.
The filament light type also changes from FOCUSED_SPOT to SPOT. With
intensity given in candela and the cone set at build time the two types
produce identical output (FOCUSED_SPOT's power-conserving rescale only
applies when the cone changes after the intensity is set), but SPOT
guarantees that candela never rescales with cone angle should the cone
ever become runtime-editable.
Verified with headless renders under a linear tone mapper against an
equal-candela point light at cutoffs 25/45/80: softness 0 gives
spot/point luminance ratio 1.000 at all sampled angles inside the cone;
softness 0.2 is flat over the inner 80% of the cone; softness 1 matches
the previous renderer with zero linear-pixel difference. XML round-trip
and the [0, 1] compile-time check verified. Introspect and wasm bindings
regenerated.
PiperOrigin-RevId: 959334706
Change-Id: I0f0729781899880de1729ea9b3d8c055d715a025
This change defines rotEPS as 1e-6f when mjUSESINGLE is defined, and 1e-9 otherwise. With the larger epsilon for single precision, the algorithm converges in fewer iterations, allowing the test assertion for maximum iterations to be simplified to a constant 150.
PiperOrigin-RevId: 959070496
Change-Id: I4f6fae056cd71955d3921c01a9929af2cdd81fac
This change removes the ViewerMode enum and instead infers whether to launch the Web Viewer or Native Viewer based on the graphics mode (gfx) setting. Specifically, setting gfx to "web" or "webgl" will now launch the Web Viewer (in future "webgpu" would also launch the Web Viewer).
Additionally, this unifies command-line flags across studio scripts and samples by replacing the --mjcf flag with --model (with positional argument fallback) and standardizing absl flags usage. --model is a better name since formats like .mjz and .mjb are also supported by this argument.
PiperOrigin-RevId: 959058940
Change-Id: If4e0ace664ddc6e45cb681d168679148e8c4901d
Interpolated flexes with pinned nodes could not be reloaded after saving:
pinned nodes share their parent body, and their positions within it lived
only in mjsFlex.node, which had no MJCF attribute. On reload the pinned
nodes collapsed onto the parent body origin, degenerating the trilinear
interpolation grid ("flex grid rotation R0 is not orthonormal"). This
made model/flex/strain.xml and gripper_trilinear.xml fail to round-trip.
Add flex/nodecoord, real(3*nnode), the node analog of flex/vertex: local
node coordinates within the corresponding body frames. The reader picks
it up from the regenerated schema tables; the writer emits it with the
precision-aware WriteVector, since VectorToString ignores the XML
precision setting and truncating node coordinates to 6 digits while body
positions carry 17 fails the R0 orthonormality check at full precision.
Add a WritesPinnedFlexNodes round-trip regression test, and remove the
two write-read sweep exclusions documenting this bug. The removed
substring filter "strain" was also matching core_constraint, silently
excluding that entire testdata directory from the sweep; its ~40 models
are now covered and pass.
PiperOrigin-RevId: 959025281
Change-Id: I2fed28c01491c5a8431e813102a423d12b659911
- Declare every nonzero default; make the defaults cross-check total.
- Skip default-valued attributes in the hand-written writer paths.
- Fix type facts on hand-read elements, found by the dm_control diff.
PiperOrigin-RevId: 958999733
Change-Id: I3064ccc6ae1f049c20f273abc234cd02990a8b7e
- Declare the full child lists of the body-alias elements.
- Verify read-table coverage: every generated row array must be consumed.
- Fix stale attribute facts on hand-read elements.
PiperOrigin-RevId: 958685667
Change-Id: I4a914f3136a5078eb8ca24aa4e162d55afafd923
K_stretch was the Gauss-Newton Hessian of the stretch force, not its Jacobian.
With elongation e_a = L_a^2 - L0_a^2 and force f = -sum_ab M_ab e_a grad(e_b)/2,
K = 2 sum_ab M_ab (s_a d_a)(s_b d_b)^T + sum_a Me_a (Laplacian_a (x) I3)
and only the first term was there. The second is proportional to the edge
tension Me_a = sum_b M_ab e_b, so it vanishes at rest and grows with strain:
the operator was first-order correct and no more. Finite-differencing it
against -d(qfrc_passive)/dq on a mesh dilated by 5% gives 7.8% of the force
scale; with the term it is exact to roundoff.
Add only the tensile part. The geometric block is Me_a*[[I,-I],[-I,I]] over the
edge's two vertices, which is positive semi-definite exactly when Me_a >= 0; a
compressed edge would make K indefinite, and both consumers -- the CG
constraint solver and the PCG in mjd_effSolve -- require SPD. The clamp is
structural, so no eigendecomposition is needed, and it is confined to the
operator: mj_flexPassiveStretch keeps the full Me_a, so no force changes.
Both the matrix-free operator and the CSR assembly the effective metric builds
from are updated, since they must agree.
This changes how flexes with elastic2d="stretch" integrate under the implicit
integrators and the effective metric -- bag.xml moves, poncho.xml is
bit-identical because bending energy is quadratic and has no geometric term.
The interpolated-flex path still uses its Gauss-Newton approximation, which
FlexInterpDerivativesDeformed asserts.
The writer consumes the same generated rows as the reader.
mjXWriter::WriteAttrTable drives the mechanical attributes of an
element from its mjXAttr rows: each bound field is compared against
the class default at the same offset -- the default object is the same
struct type, so the rows carry no comparison values -- and attributes
equal to their default are skipped. A null default object means the
element has no defaults, and every defined value is written.
Ranged-arity rows write with trailing-default trimming, which the
reader makes round-trip exact by refilling from the same default.
Call sites upcast to the private mjs base (the friend declarations
permit it; mjCMesh gains the friendship its siblings had); the
comparison object is def->X().spec, a freshly-defaulted struct for
the sections, or zero-initialized for size, whose spec defaults (-1,
auto) are resolved by compilation.
Converted: pair, geom, site, joint, camera, light, material, the
equality family, both tendon types (the fixed rows are the spatial
rows without appearance attributes -- exactly the tag difference), the
actuator, flex with its three sub-elements, mesh, skin, option, the
six visual sub-sections, statistic and size. The remnants keep names,
files, resolved reference strings (the mjC classes null their private
base's string pointers; resolved names live behind accessors), and the
writing=custom policies the schema declares: compile directives never
saved (fromto, springdamper, fitscale), type-dependent lengths and
attributes (sizes, joint pos/axis/limited, shellinertia), and
alternatives (mass/density, fovy-versus-intrinsics, the plugin-gated
gain/bias family). Compiler keeps its write-if-nonzero policy;
keyframe keeps its model-sized vectors.
Saved files are canonical: attributes follow schema declaration order
with remnants trailing, and sections follow the schema's dependency
order (statistic before visual, deformable before the contact and
equality sections that name flexes, tendon before the equality
constraints that name tendons, custom demoted to the data tail).
Uniform behavior fixes fall out: default-equal positionals are
dropped, dynprm is trimmed like every other ranged vector, and mesh
material -- read into the spec but never written -- now survives
save/load round trips. Changelog entries ride along.
Verified: full suite, doc_test, and the two-tier A/B harness --
saved XML reorders attributes, and every corpus model reloads to a
byte-identical binary.
PiperOrigin-RevId: 958255003
Change-Id: I5fe7346014450db88b2f3f8680a8f616f7d31266
Every mechanical attribute read in MJCF now derives from mjcf.schema.
generate_read_table.py emits typed mjXAttr rows (mjcf_read_table.inc,
doc_test-gated) binding each attribute to its spec struct field; field
offsets are offsetof() expressions, so binding mistakes are compile
errors, and the field's C type -- parsed from the headers -- selects the
row kind, so mjtNum-versus-double is decided by the struct, not the
schema. mjXReader::ReadAttrTable is the generic loop; its static core
also serves the section parsers and records XML-authored fields via
mjs_setAuthored for attach conflict resolution. Row kinds cover
strings, string lists, numeric scalars and vectors (exact and ranged),
enums (int- and byte-width), bitwise flag sets, bools, unbounded typed
vectors, fixed char arrays, and identity constants declared by 'set'.
The rows are inline variables, and carry the writing=custom flag,
because the writer will share them.
The keyword maps the rows reference are generated too: the ~48
hand-written mjMap tables become mjcf_map.h, one map and size constant
per enum as C++17 inline variables, retiring the hand-maintained
extern block in xml_base.h. Map names follow the schema enum names
(fluid->fluidshape, TFAuto->FalseTrueAuto, FAuto->FalseAuto,
joint->jointtype, geom->geomtype, jac->jacobian); all maps are
key-order- and value-identical to the hand tables they replace, and
bool_map is hand-emitted (the bool type is built in, not a schema
enum).
The OneX() parsers reduce to genuine irregulars, schema-marked as
reading=custom: orientation alternatives, file attributes (VFS and
asset-dir context), the actuator shorthand remappings and per-type
input maps, springlength's one-value copy, mesh builtin construction,
hfield elevation, texture cube files, flexcomp seeding, the memory
suffix parse, and the flag bit families. All 41 sensors that are pure
identity-plus-references -- including the frame family and insidesite
-- dispatch through a generated tag table; frame-sensor
objtype/reftype vocabulary tightens from the full mju_str2Type
namespace to the documented body/xbody/geom/site/camera subset, so an
invalid keyword now fails at parse time instead of compile time. The
equality family and both tendon types read shared group rows; the
twelve actuator shorthands share the general rows, with per-tag
legality enforced by the schema check. Sections bind non-mjs structs,
the visual sub-sections reaching their anonymous sub-structs through
member paths declared by an element-level field= facet.
Latent irregularities surfaced by the migration and preserved via
schema declarations or remnants: key's name is set even when absent,
eulerseq and gridlayout are fixed char arrays (chars[n], arity in
characters), gridlayout's length-must-match-gridsize stays a
value-conditional remnant, and constructor-style elements (tendon
wraps, asset model, replicate, attach) are annotated as such -- their
attributes are arguments, not field writes.
Two coherence tests guard the schema against the C sources: every
schema enum constant must be a member of the C enum it claims, and
every C member must be a keyword, a count sentinel, or a documented
exemption; and generate_default_table.py emits one row per defaulted
attribute (mjcf_default_table.inc), compared by SchemaDefaultsTest
against a freshly-constructed spec -- the schema cannot disagree with
the C default-constructors without failing the suite.
Verified: doc_test regenerates and diffs every artifact; the full
suite; and an A/B harness compiling the model corpus against the
pre-migration reader -- saved XML and binary models are byte-identical.
PiperOrigin-RevId: 958075724
Change-Id: I9715fe4deeb438eec988fd5084d74ba8b466b10b
The hand-written MJCF[] table in xml_native_reader.cc is replaced by
mjcf_table.inc, emitted from mjcf.schema by generate_mjcf_table.py and
checked for freshness by doc_test. nMJCF is now self-sizing. The two
tables are identical as trees of (tag, cardinality, attribute-set);
within-row attribute order changes where the schema factors shared
groups and projects default-context rows, and top-level rows follow
the schema's dependency order -- neither affects validation, which is
set-based, nor XMLschema.rst, whose generator orders sections itself
(regenerated here, reading the .inc instead of the reader source).
The schema's constraint declarations become enforcement: the emitter
writes a companion MJCF_constraints[] array (row-indexed into MJCF[]),
and mjXSchema::Check evaluates each element's constraints after its
attribute check, with uniform messages derived from the declaration:
"at most one of 'fovy', 'sensorsize' can be specified", "attributes
'reftype', 'refname' must be specified together", and so on.
Multi-attribute bundles render as ('site1', 'site2').
Fifteen hand-written co-occurrence checks across fourteen elements are
deleted -- connect/weld semantics mixing and completeness, the actuator
transmission mutex, camera fovy/sensorsize, light directional/type,
inertial fullinertia-versus-orientation, rangefinder and the distance
family, contact's matching criteria, user-sensor pairing, the frame
family's reftype/refname, size memory exclusivities, mesh builtin
exclusions, and attach body/frame (newly declared). Tests assert the
uniform messages.
Two findings along the way: sensorsize-requires-resolution is a
value-level compiler rule (positive resolution), not a presence rule --
a presence constraint would be wrong and is not declared; and Size()'s
nstack/njmax range checks tested the spec value before assignment, so
they never validated the parsed value -- now they do.
Verified by compiling all 81 models in the model/ corpus.
PiperOrigin-RevId: 958064622
Change-Id: I802cf5c0aee08a62926e36a281320ff9e34c0668
The complete MJCF surface in one hand-maintained file: 144 elements, 8
shared attribute groups, 47 enums, 1,497 typed attributes with
defaults, the presence-constraint inventory previously visible only as
hand-written reader checks, and the save policies previously visible
only as hand-written writer logic.
The language is a small IDL: elements bound to their mjSpec structs,
typed attributes with arities and defaults, enum keyword sets with C
bindings, reusable and variant groups, explicit name/reference
namespaces (id<ns>/ref<ns>, following dm_control's
identifier/reference model), child cardinalities, presence constraints
(exclusive/together/requires/oneof over attribute bundles), bitwise
flag sets, identity constants (set field = CONST), fixed char arrays
(chars[n], arity counting characters), numeric range facets, and two
escape hatches: reading=custom (no typed binding is generated; both
reading and saving are hand-written) and writing=custom (the binding
drives the reader, the save policy is hand-written).
doc/generate/mjcf_schema.py is the dependency-free parser and semantic
validator; errors report file:line; 55 unit tests. The language is
documented by the cheat-sheet legend at the top of the schema file.
The schema was bootstrapped by extraction from the sources of record --
the MJCF[] table, the mjMap keyword tables, the ~660 ReadAttr*/MapValue
call sites, mjspec.h struct fields, and the default-constructors in
user_init.c and engine_init.c -- then hand-curated. Same-tag elements
that differ by context are distinct declarations carrying an xml=
facet; worldbody, frame and replicate carry alias=body, mirroring
mjXSchema::NameMatch. The top-level order is by dependency, what a
saved file should read like: front matter, declarations before use,
the tree, the sections that reference it, the data tail.
PiperOrigin-RevId: 958060695
Change-Id: Ie10fd9f0ef202a3626f4d635d02c8731a4d287df
When penetration exceeds a box's smallest half-size, the midpoint
between the contact surfaces can land outside both boxes. The outside-
box filter in mjc_BoxBox then removed every contact of the manifold,
returning nothing for a visibly overlapping pair, letting boxes fall
through each other. Fixes#1800.
If the filter would remove all contacts, restore the penetrating ones.
This is strictly additive: configurations where any contact survives
the filter are unchanged.
The removed midpoints are bitwise-identical to the witness midpoints
computed by mj_geomDistance for these configurations, so the positions
follow the engine-wide contact position convention; re-anchoring them
onto a box surface would not.
Fixes#1800
PiperOrigin-RevId: 957867315
Change-Id: Ia9c858661d4badeb2a832d25455e33402936011d
In the edge-edge path of the box-box collider, when line clipping yields
no points, the corner generators accept points whose projection
parameters are out of range and clamp them into the valid range. The
depth of such a point is the Euclidean distance between two unrelated
points, mixing lateral offset into penetration depth, and on the
penetrating side it is admitted with no margin check. For thin boxes
meeting edge-to-face within margin, this produced a contact with
penetration three orders of magnitude larger than the boxes' true
separation, exploding resting stacks.
No contact can penetrate deeper than the support-interval overlap along
the separating axis, which the SAT stage has already computed. Enforce
this bound on all points emitted by the edge-edge path. The bound
carries margin plus relative and size-scaled slack covering rounding
error: the depth of the deepest legitimate point is algebraically equal
to the bound, so an exact comparison would drop real contacts. The
slack is precision-dependent: in mjUSESINGLE builds the two
computations of the same overlap disagree by tens of ulps, and slack
calibrated for double precision rejects real single-precision contacts.
Differential fuzzing against the nativeccd oracle over 200k random
near-contact thin-box configurations, in both precisions: impossibly
deep contacts drop from 1018 to 4 (worst excess from 2.5x the bounding
diameter to 0.001x), with no legitimate shallow-penetration contact
lost.
PiperOrigin-RevId: 957628830
Change-Id: Iaa1f10742f91c55bf831296cba0936eb50ea09b0
<pid kp kv|dampratio [ki imax] [slewmax]> is a PID controller with real position and velocity setpoint inputs on a single force output, plus an optional feedforward input. With a zero velocity setpoint it reproduces <position> bit-exactly; the input signature is any subset of [pos, vel, ff], selected with input="..." and recorded as mjtCtrlInput bits in
actuator_ctrlspec; absent setpoint inputs are fixed at zero, so the control vector contains no inert entries.
kp and kv are single-sourced in the affine bias parameters (biasprm[1,2]) with no gainprm mirror: every consumer of the position-servo shape
(dampratio conversion, inheritrange, qDeriv) reads one location, which is what makes the bit-exact <position> parity possible. Controller state uses dyntype 'pid' with slot-gated activations in the order [slew, integral], following the dcmotor slot idiom: slewmax (dynprm[1]) rate limits the effective position setpoint through an activation holding it;
ki (gainprm[0]) integrates the position error -- wrapped on rotational transmissions -- with anti-windup clamping of the integrand at imax (dynprm[0]). Both features require the pos input. Servo input unpacking is shared with the dcmotor controller (unpackServoInputs); per-input ranges are exposed as posrange/velrange/ffrange.
This subsumes the functionality of the mujoco.pid plugin with proper activation state: correct under all integrators, visible to keyframes, act sensors and reset. Migration: kp/ki/kd map to kp/ki/kv, plugin imax is in force units (divide by ki), slewmax carries over; the single ctrl becomes input="pos".
PiperOrigin-RevId: 957588898
Change-Id: Id2786836ca6e76f58e5b5cc8323fc23be0a53784
- Add a hidden directional light to Filament scenes with no lights to work around soft shadow blackout bug.
- Respect quality/shadowsize as default shadow map resolution.
- Interpret light/bulbradius in correct units for each shadow type and update XML reference docs.
- Support updating the shadow map resolution of live Filament lights.
- Clamp light intensities to non-negative values in the Filament debug panel.
PiperOrigin-RevId: 957305808
Change-Id: Ic7a3430aaa3b117be7fbb7ace836d68e54cdf65a
- Draw complete wireframes in the Filament renderer.
- Bind the 'W' key to toggle the wireframe render flag in Studio.
PiperOrigin-RevId: 957230911
Change-Id: Ib583c81ddcfa834686c7cf01d2b12842479993ea
Projectile parameters are positive scale factors, best adjusted
multiplicatively. Replace the input boxes with logarithmic sliders
spanning 0.1x to 10x the seeded default, which sits at the geometric
midpoint of the range; mass spans 0.1x to 100x since heavy projectiles
are a common want. Ctrl+Click still allows typing values outside the
slider range, and each slider gets a reset button restoring its
default. Adds an ImGui_SliderLog widget operating on mjtNum.
PiperOrigin-RevId: 957071873
Change-Id: Id46eae28f73308d98681ccbeb2764c949f98f9d9
The launch key binding was gated behind a checkbox because it stayed
active with the plugin window closed. Condition it on the window being
open instead: the arming state is visible, so the checkbox is redundant
and the press-proof chord can relax to plain Enter. Text fields and
dialogs are unaffected: plugin chords are not checked while ImGui
captures the keyboard, and built-in shortcuts dispatch first.
PiperOrigin-RevId: 956796864
Change-Id: I4e5b2bdcaafbcc1b1ba113dd37ef8314b3ade49e
Plugin windows could only be closed from the Plugins menu. Pass the
plugin's active flag to ImGui::Begin so the window gets a close button
that writes the same persisted state as the menu toggle. Skip the
update callback while the window is collapsed.
PiperOrigin-RevId: 956795070
Change-Id: I61cb5c26e7af935b6bb296f1b89142a72b0daca1
The classic renderer supports only directional and spot lights, but initLights() set GL light colors for every scene light before dispatching on type, and the render passes enabled GL light slots without filtering. Since no position was ever set for unsupported types (mjLIGHT_POINT, mjLIGHT_IMAGE), OpenGL's default eye-space position turned them into phantom headlights with the model light's diffuse color, washing out the scene. A cast-shadow image light additionally triggered a full shadow pass with an unset light projection.
Filter all light setup and enable sites on a shared type predicate, so unsupported light types contribute nothing. The no-lights ambient fallback now applies when no supported lights are present.
PiperOrigin-RevId: 956696548
Change-Id: Ic29763df7f9330f21d94f14501ae2559fd460f2b
Slider rows in the joints and controls tabs could only be reset through
a hidden right-click context menu. Replace it with a visible reset
button at the right edge of each row, disabled while the value is at
its reset target so the button column doubles as a modified indicator.
Rows split the remaining width equally between slider and label, and
labels clip at the button column. Adds an ImGui_ResetButton widget.
PiperOrigin-RevId: 956627705
Change-Id: I9c178f6cd1cc806c7ffd6f531acf7f2d470d9346
mj_nextActivation indexed actuator_velocity with the actuator id, but the
array is laid out by output address. The two coincide only when all
preceding actuators are single-output, so a DC motor placed after a
multi-output SO3 actuator integrated its bristle state with another
actuator's velocity, while act_dot (computed in mj_fwdActuation with the
correct velocity) disagreed with the actual evolution of the state.
Fixes DCMotorTest.LuGreBristleVelocityOrderInvariance.
The DC motor's LuGre bristle state must integrate the velocity of its own
transmission, so actuator ordering cannot affect it. The test places a
multi-output SO3 actuator before the DC motor, making the motor's actuator
id and output address diverge, and requires the bristle state to match the
motor-first ordering. Currently fails: the exact ZOH update in
mj_nextActivation reads actuator_velocity[actuator_id] instead of the
motor's own actuator_velocity[outadr], so the bristle integrates the SO3
actuator's velocity.
OpenFileDialog and SaveFileDialog hardcoded the user's Documents directory
and placed the full seed path in the name field. Studio seeds dialogs with
the current model's path, so File > Open now starts in the model's
directory with the filename pre-filled, falling back to Documents when no
path is available. Also avoids passing a potentially non-NUL-terminated
string_view to stringWithUTF8String.
PiperOrigin-RevId: 955869713
Change-Id: I7563f2cb2e39089883d5e37a3d259055c26e146c
Every step, the flex block of the implicit effective metric M + K was
factorized by sparse Cholesky, because K depends on the configuration. On
model/flex/bag.xml, added here, that is roughly half the step, against a
comparable share for the constraint solve it exists to accelerate.
Keep only the metric's per-vertex 3x3 diagonal blocks, prefactored. Neither
consumer needs the exact inverse: the CG constraint solver only wants a
preconditioner, and qacc_smooth can come from an iterative solve using those
blocks. They are O(n) to build and to apply, but weaker, so CG runs about twice
the iterations and qacc_smooth becomes an iteration rather than a direct solve.
Net, the bag model steps roughly twice as fast.
The preconditioner, by metric state. Inactive, meaning no flex elasticity or an
explicit integrator: M^-1, unchanged. Bending only (nefmK == 0): M^-1 plus the
exact constant bending factor from mj_setConst on the dofs it covers,
unchanged; that factor is built at model compile time and costs nothing per
step. Per-step stiffness: M^-1 plus the 3x3 blocks, where before it was a
per-step sparse Cholesky, or, when M couples across the flex block, an inner
PCG of up to 50 iterations run once per outer CG iteration.
Only models carrying per-step stretch stiffness change in wall-clock. Both
ponchos hold their timing and take slightly fewer CG iterations than before,
because the preconditioner is now symmetric: it applies M^-1 and the covered
blocks to disjoint sets of dofs, where previously the two overlapped and the
operator was not symmetric, which PCG requires.
mjd_effSolve is the accurate solve of (M + K)x = b; what used to carry that
name only preconditions and is now mjd_effPrec. Its CG guarded the division by
pAp with mjMINVAL, an absolute floor on a quantity that scales with the square
of the right-hand side, so a small b aborted the solve while the curvature was
healthy: four flex models were quietly left short of tolerance. For an SPD
metric the guard is positivity, and with that the same solves converge. The qacc_smooth call site in
mj_fwdAcceleration is textually unchanged but now reaches the iterative solve,
which converges on opt.tolerance rather than a hardcoded threshold, floored in
mjUSESINGLE builds where the squared target is unreachable in float. Reaching
the iteration cap names the ill-conditioned flex stiffness and then reports it
through mjWARN_INERTIA, rather than returning an under-converged result.
Covered dofs are located by walking the covered rows of the stiffness matrix,
as they need not be 3-aligned from dof 0: any joint declared before a flexcomp
shifts them.
mjData.efm_L_rownnz, efm_L_rowadr and efm_L_colind described the sparsity of
the deleted factorization and are removed: left NULL with nonzero mjxmacro
extents they made the Python bindings hand back uninitialized arrays.
efm_active loses the value 2 for the same reason, nothing selects a solve path
on preconditioner exactness any more. Both are recorded under breaking changes.
model/flex/bag.xml is added because no shipped model carried per-step stretch
stiffness. The ponchos are bending-only and trampoline.xml uses an explicit
integrator, so the metric never activates there. It is excluded from
WriteReadCompareTest: stretch stiffness amplifies rest geometry that XML rounds
on save.
needhull_ was only set while iterating geoms, so a mesh whose inertia is
computed from its convex hull never got one unless some geom pointed at
it. mjCMesh::ComputeVolume and ComputeInertia then read graph_[1] and
GraphFaces() off a null pointer and the compiler crashed.
Whether a mesh needs its hull for inertia is a property of the mesh, not
of any geom, so move that condition out of the geom loop and apply it to
every mesh.
Fixes#3431
Convert the four remaining mju_mulMat{,T}{Vec,Mat}3 call sites in this
file to their inlined mji_ equivalents, so the file is consistent after
the review change to the stretch paths. Aliasing is unaffected: the
inlined variants mark the result restrict, and every call already
required a distinct result (the public versions overwrite res while
reading vec).
Per review on #3437: add the missing blank line above the new comment
block, and use the internal inlined mji_mulMat{,T}{Vec,Mat}3 helpers
rather than the public mju_ ones, matching fe9dc584. Six call sites in
the two stretch paths; pre-existing mju_ calls elsewhere in the file are
left alone.
The implicit effective metric assembles the stretch stiffness from
world-space edge vectors, but a flex vertex body's slide dofs are
expressed in its parent body's frame. When that frame is rotated the
assembled operator is therefore not the Jacobian of the passive stretch
force, which mj_flexPassiveStretch already maps into the dof frame with
xmat^T. The metric is then inconsistent with the force it linearizes:
implicit integration loses its stability guarantee, and models that the
same flex handles comfortably in an unrotated frame diverge.
Apply the matching change of basis in both places that build or apply the
stretch stiffness: mjd_flexStretch_mul rotates the input dof vector into
world and the scattered result back, and mjd_flexStiff_assemble sandwiches
each 3x3 block as R_bi^T * blk * R_bj. Both are no-ops when the parent is
unrotated. Bending needs no change: its blocks are isotropic, and
R^T (q I) R = q I.
This completes the fix in fe9dc584, which covered the passive force paths
and the interp (trilinear) derivative but not the standard stretch one.
On a mesh flex inside a body with a 90-degree rotation, the metric's
directional agreement with the force Jacobian goes from cos = 0.57 to
cos = 1.0, and a hanging sheet that previously reached 176% strain
settles at 0.87%.
This change introduces a get_frame method to the viewer protocol, replacing the previous is_running check. This allows the viewer loop to skip rendering and lifecycle events when no active frame is ready (for example, when no browser is connected to the web viewer).
Additionally, this change:
- Adds a shutdown hook to ViewerHandle to wait for the viewer to cleanly release resources before exiting.
- Implements an ExitEvent handler in the viewer protocol to stop the run loop.
- Adds an http_port configuration option for the web viewer.
- Prevents double-closing in the viewer.
PiperOrigin-RevId: 954603868
Change-Id: Iaba7d131dc94191de51150464514dd10fa7834b0
Avoid mutating ImGui draw lists in place by scaling clip rects locally during scissor computation instead of calling ScaleClipRects. This prevents clip rects from growing exponentially on persistent draw lists, such as streamed remote UI. Additionally, clamp the scaled clip rects to the viewport boundaries to prevent Filament's scissor test from rejecting out-of-bounds rects, while avoiding resetting to full-window scissors which would disable clipping.
The draw geometry is now immutable in the Update function (ImGui texture state is still mutated).
PiperOrigin-RevId: 954277141
Change-Id: Ifdf6866bb4eabaca44b020ea40acc246428b4f0b
Also updates MuJoCo files needed to address changes in Filament.
- "build with clang on windows" patch to sync context lines, remove some
upstream conflicts, disable Clang thread-safety attribute errors, and
allow running on MSYS2.
- Skip building Filament samples.
- Add missing <string_view> to material_manager.cc.
This forces git to treat the current directory as the git checkout to apply the
patch to, which avoids issues where a non-git checkout (e.g. from an unpacked
cached tarball) can cause git to find a higher-level git checkout and try to
apply the patches there, which then fails when the files to patch aren't found.
PiperOrigin-RevId: 953377327
Change-Id: I86f51d4e2823b64c825070139479089c7f30e53e
Fast path in mj_flexPassiveInterp, mj_flexPassiveBendInterp, and
mj_flexPassiveStretch assumed body slide joints are world-aligned
(J = I). When parent body has a non-identity quaternion, joint axes
are rotated (J = R_body), causing wrong force mapping and instability
(NaN/Inf in QACC).
Fix: project world-frame forces onto body local frame via
mju_mulMatTVec3(R_body^T, force) before adding to qfrc_spring/damper.
Also fix the derivative paths:
- mjd_flexInterp_kernel fast path: R^T * K_rot * R * vec
- mjd_flexStiff_assemble (CSR): R_bi^T * K_rot_block * R_bj
The CSR-assembled stiffness matrix is the actual path used by the
implicit CG solver (mj_flexCG gate). The test uses solver="CG" to
activate this path; without it, flex stiffness is integrated
explicitly and no derivative fix can help.
Ported from GitHub PR https://github.com/google-deepmind/mujoco/pull/3379
Original author: Devansh (https://github.com/devansh0703)
Fixes https://github.com/google-deepmind/mujoco/issues/3364
PiperOrigin-RevId: 952789284
Change-Id: If924f7160dd16c0cc88170d80e6e605da0fe2e04
This var was missing from the "clean up" step for all the path vars, causing
the cmake cache lookups to silently fail due to path mismatch.
PiperOrigin-RevId: 952410036
Change-Id: I5c542e821317497e899de95e5c62d76f88836e60
* Enhances ImGui dialogs to support keyboard shortcuts (Enter/Escape) and filters.
* Adjusts GUI layouts for simulation speed and compiler settings.
* Exposes additional model fields in the XML spec generator.
PiperOrigin-RevId: 951988061
Change-Id: I4927c12a8882ba4e91e6098355ec2f5db35c2747
Each pybind extension module holds its own copy of the ImGui/ImPlot globals (extension modules are loaded RTLD_LOCAL), so the viewer that owns the contexts must share the pointers explicitly. Without this, client plotting GUIs and user plotting scripts (e.g. the implot sample) crash on null context pointers.
PiperOrigin-RevId: 951917287
Change-Id: I639a173c2ae9f1af4feaf57aff7b5c81854b7393
Updates CONTRIBUTING.md to suggest that contributors who do not require Git authorship attribution let maintainers know in the PR, which allows for faster direct incorporation of changes.
PiperOrigin-RevId: 951751097
Change-Id: I521f1ad1978987c71a90e85c1bed71392a07ee7b
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
RenderableManager is responsible for rendering the "skinned" flexes
which represent the correct "final" look of a flex. This now includes
1D flexes which are rendered as a sequence of capsules (similar to
tendons).
SceneDecorator is responsible for rendering the debug (unskinned)
versions of flexes. This includes the vertices (small spheres for each
vertex), edges (thin cynlinders for each edge), and faces (triangles
for each face, including sublayers).
PiperOrigin-RevId: 951595046
Change-Id: Iebc6fd7a747a602813b6457333bd9fa5915e28d3
Store island topology in `mjData` so repeated island solves can reuse stable connect/weld equality partitions. Add cache invalidation checks for active equality changes and cover the fast path with an island regression test.
Signed-off-by: teerthsharma <teerths57@gmail.com>
https://youtu.be/GioWwB36XHI
The new geom attribute adhesion (units of force, signed; pair-level
override) translates the contact friction cone along its normal so
that the force origin lies strictly inside it. Consequences: each
contact can pull with up to the given force before breaking, and the
tangential friction budget becomes mu*(f_N + adhesion) -- the
Mohr-Coulomb yield condition with cohesion c = mu*adhesion -- so
lightly-squeezed grasps retain a guaranteed friction floor.
A translated cone factors exactly into {constant attractive force}
+ {original cone}, so no solver kernels change. The implementation is
this factorization: a constant attraction along contact normals
accumulated into the new mjData.qfrc_adhesion (summed into
qfrc_passive), plus a bias of adhesive contact rows' reference
acceleration (aref += R*adhesion), which makes resting penetration
exactly independent of adhesion. Contacts of adhesive pairs remain
active throughout the gap zone, producing rows with positive violation
whose reference acceleration pulls: a tether that resists pull-off
smoothly, captures objects released within the band into steady
contact, and detaches at the specified force. Adhesion values of the
two geoms combine by sum; explicit pairs override.
mj_contactForce reports the net interface force (cone force minus the
adhesive pull), whose normal component can now be negative. Negative
adhesion is allowed and produces a repulsive offset (air hockey).
PiperOrigin-RevId: 950858148
Change-Id: I879c08eba7ae501e5c0f8c2f807167344da4c2bc
These fields (`flg_gravcomp` and `flg_surfacevel`) replace the fast-path checks originally guarded by `ngravcomp` and (recently) `nsurfacevel`. Since the engine uses these integers only as flags (zero vs non-zero), migrating them to actual booleans makes them writeable from the Python bindings at runtime without violating size/dimension constraints.
The legacy integer field `ngravcomp` is marked as deprecated and will be removed in a future release.
PiperOrigin-RevId: 949779204
Change-Id: Ifab1f026063a4239302e6ad689663b611b59dda8
--
7f117fa7a7060b36687e7544e8d7393d14a1fa90 by Yuval Tassa <tassa@google.com>:
Handle clang AST loc nodes with elided 'line' in introspect codegen.
Apple's math.h (included directly by mujoco.h) contains an anonymous union
whose clang-JSON 'loc' lacks the 'line' key (clang elides it when unchanged
from the previous node), crashing AstProcessor._make_anonymous_key with a
KeyError during bindings regeneration on macOS. glibc's math.h has no such
union, so this never bites on Linux.
Fall back to an offset-based key for line-less nodes; these system-header
structs are never referenced by MuJoCo types, so the key only needs to be
unique.
COPYBARA_INTEGRATE_REVIEW=https://github.com/google-deepmind/mujoco/pull/3411 from yuvaltassa:introspect-loc-fallback 7f117fa7a7060b36687e7544e8d7393d14a1fa90
PiperOrigin-RevId: 949626713
Change-Id: I9d99b427885ede18b075db6d4e507aa8bc0d049a
- Wrapping in force path is local; act is re-anchored at integration time.
- Remove hardcoded `actrange` for intvelocity actuators.
PiperOrigin-RevId: 949566477
Change-Id: I349fdf17eedfbb2174d698cc1a6a91d52810b4a3
Add a changelog entry documenting that flex elasticity (stretch, bending,
interpolation stiffness) is now integrated implicitly inside the CG
constraint solver via an effective metric, replacing the previous post-hoc
CG correction.
PiperOrigin-RevId: 948963146
Change-Id: Id9c2a2920aabd0776f630b2f3a1ab30a214d9bf2
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
This CL replaces the post-hoc implicit flex correction (`flexInterp_cgsolve`) with a **linearly-implicit effective metric** `M̃ = M + (h² + h·damping)·K` carried by the CG constraint solver itself. Contact/friction forces and implicit flex elasticity are now computed against one consistent metric, instead of the solver seeing `M` and a post-solve correction changing `qacc` behind its back.
Gate (unchanged semantics): `solver="CG"` + implicit/implicitfast integrator + pyramidal cones + flex stiffness present. Newton and PGS are untouched. `solver="CG"` remains the user-facing contract — the factorization is an implementation detail of the preconditioner.
### What's in the metric
- **mjData `efm_*`** (arena, efc-like lifetime/skip semantics; built in `mj_fwdPosition`, value-refreshed in `mj_fwdVelocity`): the per-step stiffness CSR `efm_B_*`, its reverse-Cholesky factor `efm_dofid` + `efm_L_*` (nested-dissection ordered, separators-first for the reverse factorization), and the smooth-force shift `efm_c = h·K·qvel`.
- **`mjd_flexStiff_assemble`** now assembles stretch (Gauss–Newton), standard dim-2 bending, and — via the cached corotated stiffness `d->flexelem_krot` — interp stiffness (all node bodies on simple sliders: point Jacobian is I₃, `flex_centered` not required; fixed nodes drop like pins) into one dof-level CSR. `mjd_effMulAdd`/`mjd_effSolve` apply the metric, with matrix-free operator fallbacks where assembly does not apply.
- **mjModel `efm0_*`** (`nefm0dof`/`nefm0L`): the constant part of the metric factor — currently the dim-2 bending factor, computed once in `mj_setConst` — so bending-only models pay zero per-step factorization cost. Naming mirrors mjData's `efm_*` with the standard `0`-suffix (reference/constant) idiom, and is deliberately not bending-specific: future constant contributors extend it without renames.
- The solver consumes the metric through pre-shifted `qfrc_smooth` and the metric products `Ma`/`Mv`/`Mgrad`; `qacc_smooth` becomes the unconstrained minimizer of the implicit dynamics, which makes the no-constraint shortcut and the warmstart choice consistent by construction.
- **`mj_inverse` adds `B·qacc − c`**, making inverse dynamics discrete-consistent with the gated forward dynamics — exact, since the gated path has no qDeriv term (new test `ForwardTest.GatedFlexInverseConsistency`).
### Performance
All numbers: ms/step over the same 2000-step window, models as shipped on each side (old code with the old model settings vs this CL with the new ones).
The new solver path activates on exactly two shipped models — the ponchos, the only flex models that need an implicit integrator (poncho on Euler degenerates to >200 ms/step). For them, this CL trades speed for consistency: the implicit bending solve now runs inside every solver iteration, where the contact solve can see the stiffness, instead of once after the solve. Solver iterations drop because the curvature is visible, but each iteration pays for the implicit solve:
| model | before | after | solver iters/step |
|---|---|---|---|
| poncho | 2.47 | 3.30 (1.33×) | 16.8 → 11.8 |
| poncho_edgeequality | 1.96 | 2.72 (1.39×) | 13.2 → 10.0 |
What that price buys: contact forces consistent with the implicit elasticity (previously the post-hoc correction changed `qacc` after the constraint solve), discrete-consistent inverse dynamics, and the removal of the post-hoc special case from the integration path. Raising poncho's timestep from 2 to 5 ms leaves its per-step cost nearly flat, so the consistency price can be recovered by taking fewer steps where accuracy allows.
Every other flex model was measured stable on Euler at its shipped timestep and switches to it (these models predate the post-hoc integrator; implicit was never load-bearing for them). They end up equal or faster than before: bunny_multicell 0.47 → 0.40, trampoline 0.28 → 0.25, plate 1.02 → 0.99, pancake 0.34 → 0.33.
Finally, the per-step factorization makes configurations practical that the old code could only integrate explicitly: implicit stretch elasticity (`elastic2d="stretch"`/`"both"`, dim-3 solids) and factorized interp stiffness. No before/after exists for these — stock has no implicit treatment of stretch at all.
### Behavior changes
- With the post-hoc correction deleted, interp/bending models running `solver="Newton"` (or elliptic cones, or islands) now integrate flex elasticity **explicitly** (previously: post-hoc implicit). Affects e.g. `gripper_trilinear` (stable, and faster, but different semantics). Follow-up options: Newton-side metric support, or a documented fallback.
- With the gate on, `mj_forward` outputs are timestep-dependent for gated models (they answer the linearly-implicit discrete problem); `qacc_smooth` and `mj_inverse` change accordingly. Non-gated models are bit-identical (full suite green throughout).
### Validation
- 1737/1737 tests, including new: `FlexStretchDerivatives` (FD-validated GN operator), `FlexStiffAssemble`/`FlexStiffAssembleInterp` (CSR ≡ operators), `GatedFlexInverseConsistency` (fails pre-change), equivalence tests vs the old post-hoc treatment (bending matches to 2e-11).
- Fingerprint discipline throughout: bending-only models bit-exact across every refactor; permutation/kernel changes verified iteration-identical.
### Known follow-ups (not in this CL)
3×3-block sparse Cholesky kernel (the numeric factorization is index-bound; projected ~3× on the factor); mjModel persistence of the factor's symbolic pattern (rest-pose ND makes sizes compile-time); the general effective-metric mode (all solvers, all PSD-safe force classes, behind an enable flag).
PiperOrigin-RevId: 948561856
Change-Id: I8b8e32ebd0428042af71647d0470d10773bf6daf
The gyroscopic (bias) derivatives applied to standalone free bodies by the
implicitfast integrator provide comparable stability for spinning bodies,
with none of midpoint's restrictions: they apply under contacts, fluid
forces and constraints, and preserve the linear force-velocity relation
required by discrete-time inverse dynamics. The invdiscrete flag reverts to
its original single meaning and no longer affects forward dynamics.
Restore implicitfast coverage in the DiscreteInverseMatch test, removed
when midpoint made discrete inverse dynamics untestable.
Add implicit gyroscopic (bias) derivatives for free bodies in implicitfast.
The implicitfast integrator drops the RNE (bias) derivative to stay on the
symmetric Cholesky path, so fast-spinning free bodies integrate gyroscopic
forces explicitly and can gain energy. Symmetrizing the gyroscopic Jacobian
is not an option: its stabilizing content is the antisymmetric part, and
adding only the symmetric part is destabilizing.
Instead, exploit the fact that for a standalone free body the 6x6 block of
M - h*D is decoupled from the rest of the system (qDeriv sparsity is
tree-local): after the global solve, rebuild the block with the exact bias
derivative in closed form (mjd_freeBias_vel) and re-solve it with dense
unsymmetric LU, overwriting the block's rows of qacc. For lone spinning
bodies this makes implicitfast match implicit to rounding, at ~150ns per
eligible body: cheaper than the midpoint machinery it will replace.
Eligibility is structural only; contacts, fluid and constraints need no
gating. The same block is mirrored in discrete inverse dynamics
(mj_discreteAcc), making invdiscrete exact for spinning free bodies.
PiperOrigin-RevId: 948472495
Change-Id: I813ef3d98c7b399881bc8603b9f9208cfb02eb58
An actuator now owns a block of consecutive controls
(actuator_ctrladr/ctrlnum, width defined by the actuator type) and a block
of consecutive force outputs (actuator_outadr/outnum, width defined by the
transmission type). Force outputs are the scalars of actuation space: one
force, length, velocity and moment row each. nout = dim(actuator_force) is
derived from transmission types; all current types have width 1, so all
three counts coincide for every existing model and behavior is bit-exact.
Array re-keying: ctrlrange/ctrllimited by nu; forcerange/forcelimited/gear/
acc0/length0/lengthrange and the moment row structure by nout; everything
else per actuator. The mjModel actuator block is re-sorted by size key.
Layout-breaking, not behavior-breaking: saved .mjb files are invalidated
(size list changed) and recompilation is required.
PiperOrigin-RevId: 948351772
Change-Id: Icbc196ffa083cb1eaa6f1a3710869c89d8f62540
The primal cost has curvature of at least M in every zone, making it strongly
convex in the M-norm and bounding the suboptimality of any point by the
Fenchel duality gap at its constraint forces:
cost(qacc) - cost* <= 0.5*grad'*M^-1*grad
Since M's factorization always exists, this certificate is evaluable before
the solver does any work: one triangular solve and one dot product. When the
warmstarted solution is already certified to satisfy the tolerance, CG and
Newton now return with zero iterations; for Newton this skips building and
factorizing the Hessian. If the certificate declines, Newton gets a second
exit after factorization: the Newton decrement, checked before the first
line search.
Because the gap bounds cost suboptimality, stiff constraints can convert it
into force errors of order sqrt(2*gap*stiffness). Newton solutions are
characteristically force-accurate, so Newton zero-iteration exits also
require the gradient criterion, preserving constraint-force accuracy at
rest; CG solutions are characteristically cost-accurate and exit on the gap
alone.
On a settling pile of 50 boxes (300 dofs, ~200 contacts), end-to-end time
per step drops 13% over a settle-then-rest run and 27% in the quiescent
limit, with Newton iterations falling from 0.98 to 0.40 per step.
Tests: WarmstartZeroIterations sweeps solver/cone/jacobian on a settled box,
asserting zero iterations, forward/inverse consistency, and agreement with a
tolerance=0 control solve from the same state. WarmstartZeroIterationsIslands
checks per-island exits with a kicked box next to a settled one.
RefsiteConservesMomentum now requests an exact solve (tolerance=0), since it
asserts momentum conservation tighter than the solver tolerance contract.
PiperOrigin-RevId: 947993735
Change-Id: I2fd855774bff619709b2c386f1ba2714286e0821
The F1 overlay lists only the most common commands, and there was no
complete shortcut list anywhere in the docs. Add one to the simulate
section, derived from the shortcut declarations in simulate.cc,
simulate.h, mjVISSTRING and mjRNDSTRING.
Fixes#3306
After an accepted line-search step, the solver has already rebuilt the gradient
and Hessian and solved for the next search direction, so the Newton decrement
0.5*g'*H^-1*g -- the quadratic model's predicted cost improvement of the next
iteration -- costs one dot product. Terminating when it falls below tolerance
avoids running one more iteration only to observe a correspondingly small
actual improvement.
This is a C port of Alain's proposal in MJWarp:
https://github.com/google-deepmind/mujoco_warp/pull/1520
PiperOrigin-RevId: 947768034
Change-Id: I94e5c71a4e2b4a7775611edd1dad254bba2633b4
mju_factorLU6/mju_solveLU6: same algorithm as mju_factorLU/mju_solveLU
with compile-time size, allowing full unrolling. At n=6, factor+solve is
25% faster than the runtime-sized version (93 vs 124 ns), and fixed-size
LU factorization is faster than generic dense Cholesky (55 vs 61 ns):
at this size, runtime-n loop overhead outweighs Cholesky's 2x flop
advantage. See new lu_benchmark_test. Results agree with the generic
version to rounding, not bitwise: the compiler may fuse (FMA) the
unrolled version differently.
Also add two DenseLU tests: a pivoting-required matrix with zero
diagonal, and fixed-vs-generic agreement.
PiperOrigin-RevId: 947705056
Change-Id: I24c54c9510964aa376886e9dd721890eda9889d3
The mid-phase BVH descent filter prunes body pairs using body_margin,
which was compiled as the max over geom margins, excluding gap. Broadphase
and the leaf-level test both use margin+gap, so any multi-geom body relying
on gap could silently lose its in-gap contacts when raw AABBs don't
overlap. Single-geom bodies take the leaf-leaf path and were unaffected.
PiperOrigin-RevId: 946967548
Change-Id: I6d92baa296f1a83be68b4dbfd64a96d1c7efd3c4
Reformulate the cost difference calculation (`ellipticCostDif`) to use mathematically equivalent formulas that avoid subtracting large, nearly equal values (cancellation errors) in single precision at high normal forces.
This is a C port of Alain's formulation in MJWarp:
https://github.com/google-deepmind/mujoco_warp/pull/1512
Also adds an integration test (`EllipticLineSearchPrecisionDiagnostics`) that reproduces the precision issue under large normal forces in the sliding regime, and asserts that the solver does not produce large negative improvements in either precision. This test failed before the change.
PiperOrigin-RevId: 946137815
Change-Id: Ia8fc1c4823b5fee770140c8989b9465737d22ad7
The code for the timeline scrubber widget has been moved from `App::ModelOptionsGui` into a new method `App::TimelineScrubberGui`. This new method is now called in both `App::ModelOptionsGui` and `App::ToolBarGui`, replacing the thread count slider in the toolbar.
PiperOrigin-RevId: 945565640
Change-Id: I6d5cab0b2397e8b32a2b335e8a709bb9e19bdb48
Extend mjpResourceProvider with an optional write callback (write)
so that mj_encode, mj_saveXML, and mj_saveModel can write to any
registered provider.
PiperOrigin-RevId: 945202741
Change-Id: I37903425260932e555f4a8c2392c4ff8c2e6cc06
Introduces a new timeline widget in the Studio UI, replacing the previous integer slider for simulation history. The new widget displays the current and maximum simulation times, formatted with appropriate units (µs, ms, s), alongside the actual step number, and allows scrubbing through the history via a custom-drawn spine and knob.
This change also modifies the history recording logic to record every solver step rather than only every rendered frame. This enables the step forward/backward buttons to navigate exactly 1 solver step at a time.
This change also fixes `SimHistory::SetIndex()` range checks in `sim_history.cc` to clamp `offset_` against `1 - size_` (`Size()`) rather than total vector capacity (`history_.size()`).
PiperOrigin-RevId: 944671699
Change-Id: Iaa34668a1e257e5c0c1840c827370d81c4935b3d
The flexcomp compiler previously rejected pins on dim-2 flexes with
bending (elastic2d bend/both). Allow them: mj_flexPassiveBend treats a
pinned vertex (body without 3 free slide dofs) as static -- zero
velocity, and no bending force applied to it (the reaction is carried
by the pin) -- while its position still enters every neighbor's
bending force, which is exactly what the pin constrains.
PiperOrigin-RevId: 944410969
Change-Id: Ib0a69c8d5fb6f64d3e2a76af3b6b2c7be1898191
Testing on 50 million random doubles we have branchless clip is 1.14x faster than the branched version and branchless sign is 2.27x faster than the branched version.
PiperOrigin-RevId: 943812426
Change-Id: If8003a602365601a31bec1d8b080c44d16000a4e
This example demonstrates how to use Studio's `extra_geoms` feature to render semi-transparent, time-delayed copies of the model's geoms, creating a "ghost" effect.
PiperOrigin-RevId: 943672439
Change-Id: I8ae640672945b55dd25dd3d444f52d0b2fa7f0f8
ViewerApp is simplified, interacting with the endpoint and handlers through the Viewer instance. This change makes it possible to write simulation viewers without using the UI/UX provided by ViewerApp (which should be renamed StudioApp)
PiperOrigin-RevId: 943642660
Change-Id: Id8eb3d4e6a27ceda93833367fec4699fa6bc838e
There is a single remaining exception for mjb as it's a special case by bypassing mjSpec.
PiperOrigin-RevId: 943556676
Change-Id: Iaf480ea6d2d42a6007b35c23435b25c9eb24ead0
On Windows, std::filesystem::path::string() returns backslashes while
zip entries use forward slashes. This caused lookup mismatches making
MJZ decoding fail on Windows with 'could not decode content'.
Use generic_string() (which always returns forward slashes) for all
path operations used in zip entry lookups, and normalize the archive
name at construction time.
PiperOrigin-RevId: 943538265
Change-Id: I50cafff82fd7f5f315ccfc890f660e138e4448a2
When `from __future__ import annotations` is active or forward references are used as strings, type annotations are not directly class objects. This change uses `get_type_hints` to resolve these string annotations to their actual types, ensuring correct validation of message handler signatures.
PiperOrigin-RevId: 942608060
Change-Id: Ic2b214ee85e835616cc3a18ec2699eba6deebb6a
Deletes mj_factorI_legacy and mj_solveLD_legacy from the engine and headers.
Updates factorI, solveLD, and inertia benchmarks to remove legacy targets
and only benchmark CSR.
Rewrites engine_core_smooth_test to verify CSR solver against mj_mulM
instead of legacy solver.
PiperOrigin-RevId: 942507341
Change-Id: I4281decb7018cfa3e46cb446efd5fe1179f6ae1f
Support named CLI flags, physics overrides, and refactor global state.
- **Named CLI Flags**: Replaced standard positional arguments with named flags (`--nstep`, `--nthread`, `--noisestd`, `--noiserate`, `--npoolthread`) and preserved Google-wide flags compatibility (via custom argv compacting and InitGoogle).
- **Physics Option Overrides**: Added support for configuring loaded model settings directly from the command line (`--solver`, `--cone`, `--jacobian`, `--integrator`, `--iterations`, `--tolerance`, `--sleep_tolerance`, `--noslip_iterations`).
- **Encapsulated Thread State**: Consolidated loose global variables and per-thread rollout statistics arrays into a single data structure, `RolloutRunner runner`, simplifying mutli-threaded data boundaries.
- **Readable Physics Options Printing**: Logged configured non-default options dynamically prior to rollout. Enums and active bitmask flags (e.g. disableflags/enableflags) are decoded into friendly strings (e.g., `Sleep : Enabled`).
- **Tests & Docs**: Added testspeed_test.sh running testspeed over dominos.xml to check all overrides, registered shell test target in BUILD and CMakeLists.txt, and updated samples.rst documentation.
PiperOrigin-RevId: 942285912
Change-Id: Idb966fadfa0ccba0f1862f9d62bf83458b61939a
Also add manual `Py_GIL_DISABLED` macro definition in CMakeLists as well, since there are some STATIC libraries that aren't getting it automatically through pybind11. As originally proposed in PR #3259.
Co-authored-by: Devansh Raulo <151062727+devansh0703@users.noreply.github.com>
PiperOrigin-RevId: 942216446
Change-Id: I9ef5f457491ae776c452912fbfa8617b8509d47c
The `body_sameframe`, `geom_sameframe`, and `site_sameframe` flags are now recomputed within `mj_setConst` based on the current model geometry. This allows these flags to be updated if the model's body/geom/site frames are modified after the initial compilation. Tests are added to verify the correct recomputation and its effect on forward kinematics. The compiler also checks that its initial computation matches the result of `mj_setConst`.
Fixes#3029, #1628.
PiperOrigin-RevId: 941758649
Change-Id: I7b995f8c67ad305bca5b52732436ba578c905d73
This change replaces fixed callback protocols (e.g., ViewerGuiHook, ViewerUpdateHook, SimEventHandler) with a general-purpose, priority-based message and event handling mechanism.
Key changes:
- Handler decorator and registry: Introduced the `@messages.handler(priority=...)` decorator and `HandlerRegistry` (`handler_registry.py`). Methods marked as handlers are automatically discovered and dispatched by priority (CRITICAL, USER, LIBRARY, INTERNAL) or method resolution order.
- Local lifecycle events: Added `ViewerAppInitEvent`, `BuildGuiEvent`, and `UpdateEvent` to `messages.py`. Custom GUI rendering and per-frame update logic can now be implemented as standard event handlers without needing separate interface protocols.
- Streamlined launch and app APIs: Replaced individual hook and handler arguments in `launch_passive`, `ViewerApp`, and `ViewerHandle` with unified `viewer_handlers` and `sim_handlers` lists.
- Module restructuring: Extracted simulation-side message handling and `ViewerHandle` from `sim_app.py` into a dedicated `viewer_handle.py` module, removing `sim_app.py`.
- Sample updates: Migrated existing examples (such as `implot.py`) to use the new handler pattern and lifecycle events.
PiperOrigin-RevId: 941729322
Change-Id: I93e7c0edf0a13a8dc854f9e2083451f7c25a1825
Undo mistaken auto-format of the schema table, revert it to be more human-readable.
PiperOrigin-RevId: 941628625
Change-Id: Ifc51996da9a7df9d1a03392a0ade256fb8b1c151
The line search now requires a negative cost (improvement) in addition to a small derivative to declare convergence, preventing premature termination when no actual improvement has been made.
Follows the proposal in github.com/google-deepmind/mujoco_warp/pull/1471
PiperOrigin-RevId: 941579503
Change-Id: I8fcd20f7b959e50d77cd5d6de0a3c6d95f86b9e1
Similar to LightManager, the RenderableManager manages
renderables based on an mjModel and its mjData.
PiperOrigin-RevId: 941510745
Change-Id: I97b44cc857f136aa7c90ceb85a42e299fc759b73
The `<attach>` element now supports a "frame" attribute, allowing users to specify either a "body" or a "frame" to attach to, but not both. The XML parser has been updated to handle this new attribute and the mutual exclusivity constraint.
PiperOrigin-RevId: 941245904
Change-Id: I4c0edeed5f3a9e456aed96c373b1647fe79841d9
The lazy init of log_config used a single atomic flag (env_checked) with
a load-then-store pattern, allowing two threads to both enter the init
path and concurrently write to the non-atomic log_config.topics field.
Replace with a two-phase atomic init: an atomic exchange on
env_init_claimed ensures exactly one thread enters the init, while
env_init_done (with acquire/release semantics) signals completion and
provides the happens-before edge that makes log_config writes visible to
other threads.
Also adds mj_atomic_exchange_bool to engine_crossplatform.h (both MSVC
and GCC/Clang variants).
PiperOrigin-RevId: 941202181
Change-Id: I59b6801c7b4b8b0e1647d82d2aeb534a90fb66fb
Deleted async examples since they add noise and are not particularly useful
PiperOrigin-RevId: 941117641
Change-Id: I4f621801f652e0b410a7acf905cda58143dc3fb0
Introduce a new header `gil.h` defining `MutexLockIfGilDisabled` to support thread-safety in both standard and free-threaded CPython builds.
Protect critical shared states and registries:
- Guard global Python callback pointers in `callbacks.cc` using a mutex. Move `gil_scoped_acquire` into local blocks around refcount modifications to prevent `longjmp` from bypassing destructors.
- Protect raw pointer maps in `structs_wrappers.cc` with static mutexes.
- Replace TOCTOU race in `mjcb_time` initialization with thread-safe `std::call_once`.
- Add synchronization to lazy indexer array cache initialization in `indexers.cc` and `indexer_xmacro.h`.
- Protect vector mutations in `StructListBase::PopulateUpTo` in `structs.h` with a mutex.
- Revert unnecessary atomic changes to threadpool counters.
- Declare free-threading compatibility by passing `pybind11::mod_gil_not_used()` to all extension modules.
Fixes#3259Fixes#3256Fixes#2978
PiperOrigin-RevId: 941101502
Change-Id: Iec4ce58afcbc75d4b0be6a9a21fc8a47854242e3
- `sim_app.py` provides a SimEventHook and a Handle class for the simulation process to interact with the viewer, including sending state snapshots and processing viewer events.
- `viewer_app.py` implements the main viewer application logic, handling user input, building the Dear ImGui GUI, and managing communication with the simulation process. It also includes hooks for custom viewer behavior.
PiperOrigin-RevId: 940994701
Change-Id: I82786872cd885b15454843b3a4d1160ff0b4be2b
The ViewerEndpoint can now send Snapshot messages to the SimEndpoint. The SimEndpoint has a new method, `get_viewer_snapshots`, to retrieve these. Thsi channel will be used for UI state needed for the simulation (e.g., `MjOption` and `StepControl`).
PiperOrigin-RevId: 940981799
Change-Id: Ib9bd6ad848cd5479bc49492a34fddd82569cb09f
StepControl methods SetSpeed, SetNoiseParameters, and SetPauseState now return a boolean indicating whether the state was actually changed. The GUI functions NoiseGui and StepControlGui also return a boolean reflecting if any parameters were modified. Noise parameters are now directly managed by StepControl rather than being stored in UxState. The StepControlEvent message has been expanded to include all step control parameters. Keyboard event handling has been slightly refactored to better align with event-based updates.
PiperOrigin-RevId: 940656342
Change-Id: I3701623a2fdcfc4c084b5db0ae19048669040de4
--
83a17d2844770fc2bbff37eda73b82df56076414 by Martin Schuck <martin.schuck@tum.de>:
Fix overflow cast
--
d12211c6665e1d791f77338daf8c62fa2374e3c8 by Martin Schuck <martin.schuck@tum.de>:
Prevent skipping warnings from cached jax functions by clearning the cache before invokation
COPYBARA_INTEGRATE_REVIEW=https://github.com/google-deepmind/mujoco/pull/3369 from amacati:fix.overflow_cast d12211c6665e1d791f77338daf8c62fa2374e3c8
PiperOrigin-RevId: 939914544
Change-Id: I0ab6e9ad1e7c45f352d2f49642049ad930955f0b
- `messages.py`: Defines base classes for `Message`, `Snapshot`, and `Event`, along with `SnapshotChannel` and `EventChannel` protocols. It also includes concrete message types for state, reset, model, perturbation, pause state, and exit events.
- `endpoints.py`: Provides `ViewerEndpoint` and `SimEndpoint` classes to manage message routing between the simulation and the viewer via the defined channels. A `make_endpoints` function is included to create both endpoints.
PiperOrigin-RevId: 939659912
Change-Id: I61a52a7d25431bc4ed38a184813882145eb421d1
Introduced a ViewerConfig dataclass to encapsulate common viewer window parameters. The NativeViewer now accepts a ViewerConfig and no longer requires a model at initialization. The Viewer protocol has been updated to include a close method (renamed from stop) and an upload_image method. Added checks for None models/data in studio event handling.
PiperOrigin-RevId: 939631378
Change-Id: Ibc07d0e775efa0d79ce5552ee52102e943a9b290
The `StepControl.advance` method now checks if the provided `model` or `data` Python objects are `None` before attempting to cast them to `MjModelWrapper` or `MjDataWrapper`, passing `nullptr` to the underlying C++ function if they are `None`.
This fixes an oversight in the python bindings, C++ code already supported null models.
PiperOrigin-RevId: 937243996
Change-Id: Ie67b8603517e7390fb54bfefbfed79ccf7b2bc5e
Also ensure material texture hashes are unique so that the material
cleanup works correctly.
PiperOrigin-RevId: 937206048
Change-Id: Ibed53457ee271f4faae3bcac5fb479b5ce9fc352
When reporting conflicts between parent and child elements during attachment, the warning message now indicates if a value is derived from the default rather than being explicitly authored in the XML. This improves clarity in conflict resolution warnings.
PiperOrigin-RevId: 936724265
Change-Id: I68c677b19020c19bf0260f5b3b77fe6ca3661bb9
KTX textures crash the classic OpenGL renderer and the Python viewer with
"Number of channels not supported: 1": mjCTexture::LoadKTX stores the file as
an opaque single-channel blob for the Filament renderer, and mjr_uploadTexture
aborts via mju_error because the classic path only handles 3- or 4-channel
textures.
Skip textures the classic renderer can't upload (nchannel not 3 or 4) with a
warning instead of aborting, so the model still loads and the other textures
render. LoadKTX and the Filament path are unchanged. The guard also covers the
cube/skybox path, which previously over-read a single-channel blob as RGB.
Add a render_test.py regression test that builds a model with a KTX texture and
constructs an MjrContext; it aborts before this change and passes after.
Addresses #3343.
--
6ab68a057443f038a3d844807f205b1c99cab944 by Kevin Zakka <kevinarmandzakka@gmail.com>:
Fix pickle code-execution vulnerability in sysid loaders
Serialize signal_mapping as JSON so the trajectory and time series loaders can use allow_pickle=False, preventing arbitrary code execution from untrusted .npz files.
COPYBARA_INTEGRATE_REVIEW=https://github.com/google-deepmind/mujoco/pull/3353 from kevinzakka:sysid-disable-pickle-load 6ab68a057443f038a3d844807f205b1c99cab944
PiperOrigin-RevId: 935400242
Change-Id: Iecd907174441fbcfd02c106b912a7ff375c9098c
- Added "Info" and "Profiler" to the "View" menu.
- Deleted the obsolete "Charts" menu entirely
- Removed the "Stats" toggle item from the "Help" menu.
PiperOrigin-RevId: 935314037
Change-Id: I01ee30cbba5c1b4aa54c2940b0265401cc965c07
Also:
- Patched Filament to support building with Clang, so the default MuJoCo build
mode doesn't need to change. This should probably be upstreamed.
- Added missing Windows deps to MuJoCo Platform CMake config.
- Updated Studio CMake config to fix unresolved symbols issues on Windows.
PiperOrigin-RevId: 934612701
Change-Id: I3a34a5d274e1452c9cfef0e2868f2788b4b0c7e8
Also:
- Packages MuJoCo Studio as MuJoCoStudio.app in the MuJoCo.dmg.
- Fixes a Filament compile issue.
- Patches libwebp to fix compile error related to universal builds and forces
it to build as static.
- Removes the separate, obsolete "build_studio" step.
PiperOrigin-RevId: 934564785
Change-Id: I50c83283b5e138062e37d53926a5a77fdf99dbfa
For example when loading parent_merge.xml:
```
WARNING: Attach conflict when attaching 'child' to 'parent_merge', policy is 'merge'
timestep: parent has 0.005, child has 0.002, taking the minimum
iterations: parent has 50, child has 100, taking the maximum
flag 'Damper': added from child
```
When loading parent_error.xml:
```
XML Error: Attach conflict when attaching 'child' to 'parent_error', policy is 'error'
timestep: parent has 0.005, child has 0.002
iterations: parent has 50, child has 100
Element 'attach', line 10
```
PiperOrigin-RevId: 933620810
Change-Id: Ib477863b5ef763474d27fb4be5a4148be1d5d500
CMake adds the imported mujoco target's include dir as -isystem, so with
system_headers sloppiness ccache stopped hashing the public MuJoCo headers.
A header-only change (new mjData field, new enum value) then went undetected
and ccache reused objects compiled against the old struct layout, yielding an
ABI-mismatched binding: wrong field offsets (garbage in struct/pickle tests),
stale mjENABLESTRING/mjNENABLE, and mjSpec-vs-mjData signature mismatches.
Removing system_headers makes ccache hash these headers and recompile on
change. The mtime/ctime flags stay (they absorb pip's per-run temp-dir churn
without affecting content detection).
Compiler warnings are now accumulated in a vector of strings within the mjSpec object. New API functions `mjs_numWarnings` and `mjs_getWarning` are added to access these warnings. The compiler's log handler now chains warnings to the global log handler, ensuring they are still displayed immediately. Call sites in `mj_loadXML`, `mj_compile`, and the Python and WASM bindings have been updated to use the new warning API.
PiperOrigin-RevId: 933361650
Change-Id: I47cab98a460c57b0898c0a1a43fce2a5b9648eb1
--
8ce7d8199ace95d0f429b0ca9169d290d167cee1 by Anas <anaselghoudane@gmail.com>:
Use box midpoint to choose finite-difference direction in jacobian_fd
When bounds are provided, `jacobian_fd` chooses each coordinate's
finite-difference direction so the perturbation steps away from the nearer
bound. It compared `x` against `0.5 * (bounds[1] - bounds[0])`, which is half
the box *width*, not the box midpoint. For bounds that are not centered on the
origin this selects the wrong direction, and at the lower bound the perturbation
steps outside the box.
Compare against the midpoint `0.5 * (bounds[0] + bounds[1])` instead. Adds a
regression test checking that all residual evaluations stay within an off-center
box when `x` is at the lower bound; it fails before this change and passes after.
--
cfa085484c30df808362898e322de8adc6660b59 by Kevin Zakka <kevinarmandzakka@gmail.com>:
Expand jacobian_fd bounds test and avoid midpoint overflow
Use the distributive form `0.5*lo + 0.5*hi` instead of
`0.5*(lo+hi)` to avoid overflow for extreme bound values.
Expand the single-case test into a parameterized subTest covering
all four boundary positions (lower/upper of positive and negative
off-center boxes), and rename it to `test_jacobian_fd_respects_bounds`.
COPYBARA_INTEGRATE_REVIEW=https://github.com/google-deepmind/mujoco/pull/3301 from Nas01010101:fix/minimize-fd-box-midpoint cfa085484c30df808362898e322de8adc6660b59
PiperOrigin-RevId: 933224876
Change-Id: I833cfe3324876cdeb7ca680c23d1d8a4d16adcf1
Switch MJX DataJAX to use the CSR-format `M` as its primary sparse inertia representation, matching MuJoCo C `mjData.M`. This allows both `mjData.qM` and `mjModel.mapM2M` to be deleted in the future.
PiperOrigin-RevId: 932433465
Change-Id: I194ffbfdba0cdd9c718277ee0d5de7ac20f2b06f
Correct argument types for timeconst and range parameters in pybind11
python bindings from C arrays to std::array.
Fixes#3282, #3282, #3318
Thanks to @Abzaek for original PRs
PiperOrigin-RevId: 932423401
Change-Id: Ic30ba076913693f5c0e545789690e8b0fa444390
Allows other files (e.g. mjrfilament) to define functions that
will be added to the introspection output.
PiperOrigin-RevId: 932403177
Change-Id: Ie2d2c6be67f0706463fdec4fc498364125e05dad
- Move SimToView and ViewToSim dataclasses from async.py to viewer_protocol.py (adding a user_data field) to consolidate IPC protocol definitions.
- Remove the simulated Network class and latency UI controls from async.py to simplify the example and focus on core multiprocessing communication.
- Use parser.parse() in main() for cleaner and more direct MuJoCo model loading.
- Add cancel_join_thread() to multiprocessing queues and a join timeout to prevent atexit handlers from blocking during process shutdown.
PiperOrigin-RevId: 932327625
Change-Id: If91777dba934814b3f9faa17f9055869920575d7
Widen mju_error_msg buffer from 1024 to 2048 and replace strncpy with
snprintf to avoid -Wformat-truncation and -Wstringop-truncation.
PiperOrigin-RevId: 930982013
Change-Id: I0fcd726e5ed1ad28594bd4ef55b8b1ae72020043
Widen err_msg buffer in MjuErrorMessageFrom to 2048 and use snprintf
instead of strncpy to avoid truncation warnings.
PiperOrigin-RevId: 930932293
Change-Id: Iea43d28cf209356d66cf16be48e750e947242b14
Widen snprintf buffer from 1024 to 2048 bytes in mju_defaultLogHandler
to avoid truncation warning when formatting "func: subject".
PiperOrigin-RevId: 930823501
Change-Id: I0b2246f23c44e983bea76976b684d2efdfdff29c
This change adds py::gil_scoped_release to various functions in the parser, renderer, sim and ux modules of the MuJoCo Studio Python bindings. This allows other Python threads to execute while these C++ functions, which can sometimes be time-consuming, are running. The two heaviest operations Present() (rendering) and Advance() (physics) now both release the GIL in C++.
PiperOrigin-RevId: 930645361
Change-Id: Ib239fb54edc7ac0d8b1d94bec8c57a447d5f4d27
Adds py::gil_scoped_release no_gil; to mujoco::studio::Viewer methods to release the Python GIL during C++ execution.
PiperOrigin-RevId: 930482271
Change-Id: I590794109418516ec5d9e8b536085560a1d36314
Also:
- renames the main header file to mjrfilament.h.
- moves filament_util under a "support" folder.
PiperOrigin-RevId: 930448415
Change-Id: Iad89756aaf1ddf4c3e67e1afc3a13776f71fa20f
--
3439d8a5cd745dfd2776593916eead65cb456afc by Kevin Zakka <kevinarmandzakka@gmail.com>:
Respect an explicit CMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF
The default-LTO guard checked the value rather than whether it was DEFINED, so an
explicit -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF (used in CI to cut build time)
was silently flipped back ON. Check DEFINED instead; default-on for Release is
preserved when the caller makes no choice.
--
bd15d1b264e5ab9594669b58fa1e0388d0a16f6b by Kevin Zakka <kevinarmandzakka@gmail.com>:
Speed up CI
~10x faster on the POSIX jobs (~45m -> ~4-5m) and ~2x overall wall-clock.
- Build Studio/Filament and WASM only in their dedicated canary jobs, not in
every matrix job (WASM uses emcc, which ignores the host compiler).
- Compiler matrix -> build_matrix.json with core/extended tiers: PRs build the
core set, pushes to main run the full sweep.
- ccache across build jobs (studio cache keyed on the Filament pin); fix the
Python-bindings build so ccache hits (CCACHE_BASEDIR).
- Disable IPO/LTO on POSIX (it was silently on); keep it on Windows where /GL-off
exposes a latent test bug and build time is not the bottleneck.
- Run ctest in parallel on POSIX (~2x); uv for Python installs (~29s -> ~8s).
- Move MJX (compiler-independent) to a single dedicated job.
- Restrict GITHUB_TOKEN to contents: read; bump actions off deprecated Node20.
--
c0618ab7aef524b238e0a30f2f23c50c4ce0c9b1 by Kevin Zakka <kevinarmandzakka@gmail.com>:
Build the gcc jobs with LTO off too
Restores LTO-off for gcc (recovering the build-time win). That surfaces known
gcc-12 -Wrestrict false positives in libstdc++ <char_traits> at -O3; two clean,
behavior-preserving rewrites in the XML writer avoid them. Confirmed gcc-12 and
gcc-14 build clean with LTO off (PR #3325).
--
2c38da0f48f77635e58e4b7931b86d60f3c253c7 by Kevin Zakka <kevinarmandzakka@gmail.com>:
Respect explicit IPO=OFF in the Simulate and Sample options too
Apply the same DEFINED check as cmake/MujocoOptions.cmake to the simulate/ and
sample/ subprojects (which carry identical copies of the guard) to keep the three
in sync, as the internal import requires. Since the guard now honors =OFF, stop
forcing IPO=OFF on the tiny samples/simulate CI builds so they keep their default
LTO and don't expose the gcc -Werror false positives that -O3-without-LTO triggers.
COPYBARA_INTEGRATE_REVIEW=https://github.com/google-deepmind/mujoco/pull/3315 from google-deepmind:speed-up-ci 2c38da0f48f77635e58e4b7931b86d60f3c253c7
PiperOrigin-RevId: 930008698
Change-Id: Ic41dc87881833c95f2ebfc0602de1ed438db3d4f
Corrected the comparison from `max_window_width != window_height_` to `max_window_height != window_height_` when checking if the window dimensions have changed.
PiperOrigin-RevId: 929825452
Change-Id: I4ae46502495e16f86c19d4efabe8c048d708789b
When an mjpResourceProvider's open callback returns 0 (failure), MuJoCo does
not invoke the corresponding close callback. Previously, several resource
provider implementations allocated heap memory or system file handles before
encountering an error, failing to clean them up before returning 0. This change addresses these leaks across the codebase and clarifies the API contract.
PiperOrigin-RevId: 929803942
Change-Id: Ib7344033726895cdf037a8d9356ffc183c78c2d3
Use the jump flood algorithm to render an outline around selected
objects. This requires using custom post-processing shaders and
render passes which is managed by a new "Outliner" class.
PiperOrigin-RevId: 929212147
Change-Id: Ie6f475c7c677df7b0d4fc030a8e9520ff9dd03af
The test verifies that contact sensors on subtrees and touch sensors on sites correctly register contacts involving Flex components.
PiperOrigin-RevId: 929109418
Change-Id: I1865311a6da838d75ef33989ac7f3c2d975cdbff
This rename was overlooked in the previous commit which updated
the prefixes for all filament-specific render objects.
PiperOrigin-RevId: 928710590
Change-Id: I0ff09cb077f7d5643371d43a43fc992352e6d85d
Instead, use materials to determine the layer mask of an object.
This hides the details/complexities of how layers are used
to render different passes from the user and will allow the
renderer to do more advanced rendering passes.
PiperOrigin-RevId: 928682525
Change-Id: I1f53dc8d12d2e574de6528977f55e79f896c6e42
The sensor engine now correctly retrieves body IDs for contacts involving Flex elements by using mj_flexBody when a geom ID is -1. This allows contact sensors to detect and report forces/torques on bodies involved in Flex contacts.
PiperOrigin-RevId: 928607416
Change-Id: Ia815e1b3345bcfb393c9c4a829dc98959f2da50c
The obj_decoder plugin is updated to parse line segments ('l') from OBJ files and represent them as degenerate triangles. The user_flexcomp compiler now supports flex dimensions of 1, using these parsed line segments to define the 1D flex elements. The compile sample's error reporting is also improved.
PiperOrigin-RevId: 928566870
Change-Id: I6920729d1b1d5aeb391401c3245ebb1d4784c190
- Update rollout.py to use mujoco.MJTNUM_DTYPE instead of np.float64.
- Update rollout_test.py to use DTYPE for all state/control/sensor arrays to avoid copies and type mismatches.
PiperOrigin-RevId: 928539946
Change-Id: Iee2250c049de799cb0e23ffe5558fe6eea8b3fd8
The ValidateSwapChains function will correctly set up swap chains
before any render calls, negating the need to have something done
in the constructor.
PiperOrigin-RevId: 928529339
Change-Id: Ie584d57f649730adc092f8683f18697892a5a14f
- Default rendering but without textures.
- Island coloring based on sleep state.
- Selected object highlighting.
PiperOrigin-RevId: 928482603
Change-Id: I5eda1307bc6e71a4b0b2933b5b941e945cb9de75
memcpy is more appropriate here as the source and destination buffers have the same size, ensuring the entire buffer is copied.
PiperOrigin-RevId: 927395770
Change-Id: Idbe9dade3160f593060fae5783743b28c0452695
mujoco.minimize.least_squares now supports x_scale natively, so the
sysid wrapper becomes a thin pass-through. 'jac' is adaptive per
iteration (was static at x0).
Renderables may be created/destroyed frequently causing issues with
the underlying RenderTargets used for reflections. Instead, use a
ReflectionManager (associated with a Scene) to manage the RenderTargets.
PiperOrigin-RevId: 926072766
Change-Id: I56c70000183417a92ab9297bc6fec5779f484cbd
Drag-and-drop uploads go through Module.loadFile and never reached the prefetcher. This is a guard for future provider schemes (e.g., vfs) that shouldn't be passed to fetch().
PiperOrigin-RevId: 926042158
Change-Id: I119d5b1a7512f8e84bb4c752414797593a1e98cd
Add function for getting the material. Remove unused/unneeded functions.
PiperOrigin-RevId: 925847769
Change-Id: Iefaf9112b7419830eb2dc4d1323e9c27725c4b16
This change allows users to provide an optional `step_fn` callable to `StudioApp.update` and `StudioApp.update_from_viewer`. When provided, this function is called to advance the physics simulation instead of the default `step_control.advance`.
PiperOrigin-RevId: 925439890
Change-Id: Ia833503f6dd0c22fb8d75af6c5f06757496853e5
The StepControl::Advance method now accepts an optional std::function to be used instead of mj_step. This allows for custom simulation logic to be executed within the stepping loop. The Python bindings for StepControl::advance have been updated to support passing a Python callable as the custom step function.
PiperOrigin-RevId: 925393132
Change-Id: Id2820c4b55cbdfee6b01adc2395e99a990d4e7a3
Following the export declarations in Dear ImGui and ImPlot METADATA, this change updates MuJoCo's Copybara configuration (copy.bara.sky) to export and transform the Python bindings. `//third_party/dear_imgui/google/py` exports to `python/mujoco/experimental/dear_imgui` and `//third_party/implot/google/py` exports to `python/mujoco/experimental/implot`.
PiperOrigin-RevId: 925293624
Change-Id: Ie6e32d247a6f7fc24bb36ae7060f2075d8efeb26
Previously shell mode required cellcount=1 along at least one axis. This CL
adds support for cellcount > 1 in all three axes by pinning interior grid nodes
to the parent body and reconstructing their positions from boundary nodes via
Transfinite Interpolation (TFI).
PiperOrigin-RevId: 924314800
Change-Id: I8c2438f4866dd4133feed65f535a1ab69f0c9188
The field now stores either an approximate or exact diagonal of the constraint matrix A, so the name is made more general.
PiperOrigin-RevId: 924244954
Change-Id: I62b2f76531fb88b7b3bf96e6769940197596702b
Fixes#2313
This CL combines two complementary improvements to the Conjugate Gradient (CG) solver, significantly improving numerical precision, stability, and efficiency, particularly in single precision (float32).
1. Line Search Cost Evaluation Refactor: Previously, solver improvement was calculated by subtracting absolute costs: cost(alpha) - cost(0). In highly converged states or single precision, this is susceptible to catastrophic cancellation. We refactor PrimalSearch to compute the cost delta directly, dramatically improving precision.
2. Improved Solver Termination Condition: Near the float32 precision limit, line search deltas can occasionally be slightly negative due to numerical noise. Previously, any value below m->opt.tolerance (including negative values) triggered termination, halting the solver and locking in destabilizing steps. We update the termination condition to require positive improvement (0 < improvement < m->opt.tolerance), allowing the solver to continue iterating and recover stability.
Together, these changes yield substantial improvements, see reduced tolerances herein.
PiperOrigin-RevId: 924229669
Change-Id: Ic0bbefaed090f3a8b1e79ab8d45422c3e86fb56c
Also add MJTOL_SCALE to fixture to allow tests to be run with zero tolerance. This is useful when assesing the impact of code changes (A/B comparison of failure values)
PiperOrigin-RevId: 924219083
Change-Id: Ifdd09ac850904ca8dd79179930ce738a4b37d284
Two performance optimizations for interpolated flex objects:
1. Hoist loop-invariant stride calculations in `mju_cellLookup` out of nested loops.
This reduces multiplications from 16 to 6 (linear) and 54 to 12 (quadratic)
per vertex.
2. Extract and consolidate optimized 3D interpolation logic into a new
reusable utility `mju_evalBasisArray` in `engine_util_misc.c`. This function
uses nested loops and precomputed 1D shape functions to avoid expensive
dynamic `phi` calls and branching, and leverages stack-buffered outputs to
eliminate compiler pointer-aliasing barriers. We propagate this optimization
to both kinematics (`mju_interpolate3D`) and constraint setup
(`engine_core_constraint.c`).
Together these changes yield a ~50% overall speedup in `mj_fwdKinematics` for interpolated flexes with ~10k vertices in the collision meshes and ~10 nodes in the deformation grid.
PiperOrigin-RevId: 922198093
Change-Id: I9c804e65cd532e2f9ac6e9a71d01c30cd64186fa
Update Renderable so that it can switch its own draw states (material
instance, shadow casting, reflection textures, etc.) per render request.
This allows us to use the same Renderable with different effects from
different views within the same frame.
PiperOrigin-RevId: 922102817
Change-Id: I1cf02fddb7a00345a741db1bee88e716517765f4
- C++ Platform UX: Added a "Copy Camera" button to copy XML camera definitions to clipboard.
- C++ Platform UX: Extracted `SetSpeedIndex` and `GetExpectedLabelWidth` into reusable platform helpers.
- C++ Platform UX: Fixed combo box widths and removed auto-hide tab bar flag from dockspace.
- C++ Studio App: Deduplicated label width and speed index logic by adopting platform helpers.
- C++ Studio App: Updated the toolbar layout to use a 2-column table.
- Python Bindings: Added pybind definitions for `set_camera_index`, `set_speed_index`, and `camera_to_string`.
- Python Studio App: Aligned toolbar UI with C++ using a 2-column table and fixed immediate theme switching.
- Python Studio App: Added a Help menu displaying the MuJoCo version and Stats toggle.
- Python Events: Added `-`/`=` shortcuts for simulation speed and `Esc`/`[`/`]` shortcuts for camera selection.
PiperOrigin-RevId: 922097319
Change-Id: Iec74afe37bf5c7a1ebf1cab4141e47fff5fe9274
The MSVC fallback path in safeAddToBufferSize() performed unchecked
arithmetic (type_size*nr*nc) on attacker-controlled values read from
.mjb binary model files. This could cause integer overflow, leading
to an undersized heap allocation followed by a heap buffer overflow
when data is copied into the buffer.
The fix adds manual overflow detection using SIZE_MAX/INTPTR_MAX
comparisons, matching the behavior of the existing __builtin_*_overflow
path used on GCC/Clang.
Also adds a regression test that crafts a binary model buffer with
overflow-inducing size fields and asserts safe rejection.
The normal component of the tactile sensor now reports the maximum penetration depth at each taxel, instead of a derived normal force. The depth is negated so that positive values indicate penetration.
PiperOrigin-RevId: 921980899
Change-Id: Ide4103c0aff465e25a81cfdda650f6a0e2da9e0b
Per-parameter scaling via change of variables z = x / D. Supports
'jac' (adaptive D_i = 1/||J(:,i)|| per iteration, matches scipy's TRF),
explicit array, or a positive scalar. Default 1.0 is a no-op.
The prefetcher asks mju_getXMLDependencies for the transitive asset
list, fetches every URL with Promise.all, and primes the bytes into the
WASM-side FetchCache. When the compiler runs, every resource it opens
is already in memory. Cold-load on a typical Menagerie model drops from
~9 s to ~2 s.
The function called tinyxml2's LoadFile directly, which only works on
the OS file system. Reading through mju_openResource lets it work
against any registered backend (VFS, HTTP, github:, ...).
Support Ctrl+Option+Left Click Drag (maps to Ctrl+Alt+Left Click Drag in the application) to apply point force perturbations (translation) on the robot in the WebGL live viewer. This matches the Mac experience in the native MuJoCo simulate app and provides a fallback for Mac users where Right Click is difficult to trigger.
PiperOrigin-RevId: 919767954
Change-Id: I4a1d1c05784a8257d13f64f738af5b4841a615b3
This provides visual feedback to the user while loading large models.
PiperOrigin-RevId: 918708877
Change-Id: I77ea475cce6d9718e6cf8b33cb72b3f524a6ee63
* Changed window.cc to not pass `SDL_WINDOW_OPENGL` for headless opengl graphics modes since this requests a [GLX visual](https://tronche.com/gui/x/xlib/window/visual-types.html#Visual) but CRD's virtual X11 display has no GLX visuals causing window creation to fail with "Couldn't find matching GLX visual".
* Changed `TryLoadEgl` so it fails if `eglBindAPI(EGL_OPENGL_API)` does not return true, causing `CreateFilamentPlatform` to fallback to OSMesa on CRD.
PiperOrigin-RevId: 918029935
Change-Id: Id88338811949b1402578de19bc4d31f4ee1783c1
For example, `compile mujoco_menagerie/robotis_op3/scene.xml` now outputs
```
Compile 1 (cold cache):
total: 317.2 ms
assets: 284.8 ms (wall clock)
load: 616.1 ms
hull: 26.4 ms
poly: 137.8 ms
inert: 177.8 ms
bvh: 568.2 ms
octr: 1.6 ms
tex: 25.3 ms
other: 32.4 ms
Compile 2 (warm cache):
total: 79.9 ms
assets: 54.5 ms (wall clock)
load: 888.5 ms
hull: 0.0 ms
poly: 0.0 ms
inert: 0.0 ms
bvh: 0.0 ms
octr: 0.0 ms
tex: 21.4 ms
other: 25.3 ms
```
PiperOrigin-RevId: 917850214
Change-Id: Iaec86230bec0faf2e47820e20cbff61de5b2621e
Renames MjrFilamentRenderer to CompatContext and makes it an
internal detail of the compatibility layer. This allows us to
remove all legacy functions from the mjrf namespace, making
them available only in the compatibility layer.
Update studio to use non-legacy mjrf APIs. This requires it to
use some of the compat helper classes. These will be refactored
in the future to make them reusable components.
PiperOrigin-RevId: 917730783
Change-Id: Ic8f68e6e75059f7d394ea3266a346cbd6c1fcaed
Warp is not a true stretch mode but a parasitic shear mode so it should be scaled like bending (~thickness^3) rather than stretching (~thickness). The thickness parameter can therefore be used to set the stretch to warp stiffness ratio of the strain constraints.
PiperOrigin-RevId: 916900311
Change-Id: I52e54210fbb2a6d309abc1f084934830adce3423
mju_boxQP documents that only the lower triangle of the Hessian H is
read, but the gradient and search-direction updates inside
mju_boxQPoption still called the dense mju_mulMatVec, which reads the
upper triangle as well. This violated the documented contract and
prevented callers from safely leaving the upper triangle uninitialized.
Add a file-local mulMatVecSym helper that computes res = H*vec while
reading only the lower triangle of H (mirroring the convention of the
existing mulVecMatVecSym quadratic-form helper), and use it in place of
mju_mulMatVec in both call sites. Extend the BoxQP test suite with
UpperTrianglePoisoned, which fills the strict upper triangle of H with
NaN and verifies that the solver produces the same result as on the
clean symmetric input.
Reported by @lshdlut.
Fixes#3275
The swap chain dimensions are a union of all render request
viewport sizes that use the swap chain.
PiperOrigin-RevId: 916078573
Change-Id: If26a9e1486006ed346227120a361773bfa23f292
Introduce a fast path in mj_addFlexDerivatives for centered flexes where all nodes are attached to bodies with only 3 translational DOFs and no DOF-contributing ancestors. This allows for a direct scatter of K*vec, avoiding the overhead of sparse Jacobian construction and multiplication.
PiperOrigin-RevId: 916063477
Change-Id: I824728a5bdc3b975b04b46ecf22994922e307a8c
This resolves to https://raw.githubusercontent.com/... under the hood.
PiperOrigin-RevId: 916050807
Change-Id: I1630e29a5b5aad0e39cdd8aa4cfc1ff1a71f19d9
The global node indices stored in face_gidx are now checked to ensure they are within the valid range of node numbers, raising an error if any index is out of bounds.
PiperOrigin-RevId: 916025763
Change-Id: I1d2dcb11603137c337493541066b62b2ed2854c0
In `mj_flexPassive`, precompute and cache face positions, global indices, and corotational quaternions for all faces. This avoids redundant calls to `mju_flexGatherFaceState` for each bending edge, as each face can be part of multiple bending edges. This gives a 3-4x speedup in mj_passive.
PiperOrigin-RevId: 915912918
Change-Id: I3e1c00cf2d989f85398a0750a0faf359249cfe01
Reflections, shadows, and post-processing can be specified per render
request rather than per scene.
PiperOrigin-RevId: 915910030
Change-Id: I8ce773b42870aa76a2d8219347ca1cafaec1a97b
Skip flexedge velocity calculation for rigid and interpolated flexes, as they are not used in those cases. The computation is now done per-flex, only for the edges within each non-rigid, non-interpolated flex.
PiperOrigin-RevId: 915907396
Change-Id: I0beb1f98f0115c83da13fed184e89101f57563ab
This gives a 3x speedup in implicitfast.
Also cleanup old code that was used in the dense factorization of the stiffness matrix before we switched to CG.
PiperOrigin-RevId: 915900315
Change-Id: Id6973c4bfd7d371a43ec6db982703969b23a3550
Install steps aren't needed for WASM builds, and are causing issues with EXPORT relating to lodepng and miniz.
PiperOrigin-RevId: 914891405
Change-Id: If653fe7449b0166ad6762a3fad6b95e02f3532b1
The flex interp stiffness matrix is Negative Semi-Definite (NSD). When forming the RHS for implicit integration, the term involving the velocity and stiffness should be added, not subtracted. A new test is added to ensure energy stability for flex interp stretch stiffness with the implicitfast integrator.
PiperOrigin-RevId: 914845245
Change-Id: Iaaf0914909128e64e195f17cc5f2f344a8a43bc2
Standard flex (flex_interp=0) with thin-plate bending treated bending forces purely explicitly. This caused contact-induced vertex vibrations and non-physical energy injection for flat resting sheets, because the solver treated each vertex as an independent mass during contact and contact normals are orthogonal to stretch constraints.
Fix: extend the existing preconditioned CG solver to include the constant bending stiffness K_bend in the implicit operator via matrix-free mat-vec.
PiperOrigin-RevId: 914774020
Change-Id: I45e0d6749abb6f873566203bccae956514b2576b
Removes the DoRender and DoReadPixels functions which allowed
FilamentContext to "call" SceneView functions even though
SceneView depended on FilamentContext.
Adds a mjrf_setClearColor function so that we no longer rely
on SceneView setting the clear color.
PiperOrigin-RevId: 914253362
Change-Id: I33c1cc9dfc7cb2f4c3cc855a600cccb0c54ae31c
This is in preparation for a future CL that will disable backface culling.
PiperOrigin-RevId: 914136370
Change-Id: Ie8db1268faaa306c3f3356efc5e1305d791cf525
with a preconditioned Conjugate Gradient (CG) solver that operates
on the full system matrix.
The previous approach extracted flex DOFs into a reduced banded system,
factored it separately, and overwrote the global solve. This required
precomputed bandwidth (makeFlexBandwidth), parent-joint detection,
coupling corrections, and a FlexInterpContext struct — and only worked
for standalone flex trees without parent joints.
The new CG solver uses the already-factored global system (M - h*qDeriv)
as a preconditioner and adds the flex stiffness contribution via
matrix-free products (mjd_flexInterp_mulKD/mulK). This handles any
kinematic configuration — including flexes attached to articulated
chains or with parent joints — without sparsity pattern restrictions.
Before (`bunny_multicell`):
```
Simulation time : 50.80 s
Steps per second : 197
Realtime factor : 0.20 x
Time per step : 5080.3 µs
CG iters / step : 3.16
Contacts / step : 31.04
Constraints / step : 124.15
Degrees of freedom : 178
Dynamic memory usage : 0.4% of 100M
```
After:
```
Simulation time : 9.52 s
Steps per second : 1051
Realtime factor : 1.05 x
Time per step : 951.7 µs
CG iters / step : 3.21
Contacts / step : 30.90
Constraints / step : 123.61
Degrees of freedom : 178
Dynamic memory usage : 0.3% of 100M
```
PiperOrigin-RevId: 913758038
Change-Id: If5aa617b2d535c86aec9bd71c9e0003a2b38bdd7
This shell test was extremely slow (taking up to 26 minutes under ASAN). In any case the compilation pipeline takes one kick-the-tires step, so the RecompileCompare test effectively does the same thing.
PiperOrigin-RevId: 913646840
Change-Id: If659705b88d0ac64722f88ddf2ae377932e5ef0f
The coordinates for flex interpolation are now computed using the absolute values of the vertex weights. The sign of the first vertex weight is then applied to the resulting barycentric weights. This correctly handles cases where the flex is both the first and the second entity in the contact pair.
PiperOrigin-RevId: 913590928
Change-Id: I970b35fba3d209e13b5b33bb5f945e3c6a43d487
The normal jump residual in flex elasticity calculations now rotates the rest-frame normal jump into the current frame using the face's corotational quaternion before subtracting the jump from the current normal difference.
PiperOrigin-RevId: 913242127
Change-Id: Ia62b28ecccd59e79225737d8225ef4131b333c96
The maximum depth of the octree used for SDF generation can now be specified in the mesh definition via `mjsMesh::octree_maxdepth`. The default value is 6.
PiperOrigin-RevId: 912494999
Change-Id: I6d828d1d3999b99d1210a6829a05b04fac591e1f
Combines the "Solver" and "Performance" chart windows into a single "Profiler" window for better ergonomics and visual layout:
- Unified Dashboard: Groups the Solver block (Counts & Convergence) and the Performance block (Dimensions & CPU Time) in a single viewable window that scales cleanly without vertical scrollbars.
- Adaptive Stacking: Uses ImGui grouping so each block internally stacks its charts vertically, but tiles side-by-side horizontally when the window is stretched wide.
- Default Docking & Width: Integrates the Profiler into the default dockspace layout attached to the right of the main viewable area, with an optimized initial width scaling factor of 0.42.
- Shortcut and Menus: Adds a toggle shortcut bound to `F3`, updates the Help Shortcuts overlay, and replaces old separate entries in the Charts menu.
PiperOrigin-RevId: 912491435
Change-Id: I1f9215e5498866a01ce48b6aeb4a7461191fa01d
- allow reloading of files that failed to load
- clear errors on successful reload
PiperOrigin-RevId: 912458744
Change-Id: Ie6af87508f10e83461bc998c99c9c66e2d58312e
- RHS: Make Inspector be focused by default.
- RHS: Remove Noise pane, put the functionality in the Controls pane.
- Improve Frame and Label dropdowns.
PiperOrigin-RevId: 912434712
Change-Id: I2ee5b647febfc4a90a0cf9387b1d416f5a0dd4a1
Since the mjz format is just an archive for MJCF assets this seems like a sensible place. The upcoming mjz encoder will also need to make use of the full precision XML utility that is local to src/xml.
PiperOrigin-RevId: 912044746
Change-Id: I6a9fef24b1c3fec5b5edc3a8d4c8e22584273264
Merge shading model, material params, and material textures into a
single "mjrMaterial" type.
Remove redundant decor_line material.
PiperOrigin-RevId: 911960222
Change-Id: Icce3772a8ea48467dfd610799c0c2f2ba752323e
The new function mjs_getOriginSpec returns the mjSpec that was used to define a given mjsElement. Unlike mjs_getSpec, this value remains constant even after the element has been attached to a different model.
PiperOrigin-RevId: 911930951
Change-Id: Ia9cd79d9dfabc513d6121eadcffc5d41075224c9
Move filament_util to the main folder so as to indicate that
these utilities can be used by anyone and aren't internal to
the filament renderer implementation.
PiperOrigin-RevId: 911884375
Change-Id: Ieb58184263bdac7e44a07f1e44a4649c68c6bf77
The Renderable class now internally knows which built-in meshes
to use for a given geom type. It gets these meshes from the
ObjectManager which now stores the collection of built-ins based
on the nstack/nslice/nquad quality arguments.
PiperOrigin-RevId: 911782530
Change-Id: I6698ec3964a5c657f6a9495809cc795eec2e346f
Get the camera and drawmode from the bridges rather than recalculating
it unecessarily.
PiperOrigin-RevId: 911406470
Change-Id: Ia295846bb80105a2b0ad5da21912ca82b25e04bd
- Compute efc_J_rowsuper incrementally in mj_addConstraint instead of post-hoc via mju_superSparse.
- Better exploitation of supernodes in A matrix pipeline: precount and fill skip redundant chain traversals for supernode rows.
- Redundant B_rowsuper computation via mju_superSparse is eliminated (indentical to efc_J_rowsuper).
PiperOrigin-RevId: 910787825
Change-Id: I6eda9996659602b7051ee1090aeedb862603c84e
This change adds a new passive force computation for flexes with elastic2d="bend" and dof="trilinear". The bending energy is based on the squared difference of normals between adjacent face elements at their shared edge midpoint. The edge data is precomputed during model compilation and stored in flex_bending.
PiperOrigin-RevId: 910772638
Change-Id: I3b12c7b7f1ba6ac1875df495d89e8cfec921ca80
Rename mjrf_render to mjrf_renderScene to avoid naming collision.
This function is will be removed in a future CL.
PiperOrigin-RevId: 910764245
Change-Id: If4d05e806a9699570ca4bbc882f28bfdd05dbd8d
There are still a few places where the compat library is downcasting
to the internal types due to limitations in the public APIs.
PiperOrigin-RevId: 910646480
Change-Id: I1ccb6714db08a2010d9535f59338e5eba06d1d35
Modify EigendecomposeStiffness to project out rigid body translations and rotations from the stiffness matrix eigenvectors. This prevents "ghost damping" from rigid body modes being incorrectly constrained. Update hollow_vs_solid.xml with solimp parameters for edge constraints. Adjust engine_core_constraint_test.cc to reflect the reduced number of equality constraints due to the projection.
PiperOrigin-RevId: 910631207
Change-Id: Ibaaa59bc030cfc6ae657d8f0d1b2a51002cc8d4e
Total testspeed runtime for `2humanoids100.xml` reduced by 19.6% (49.5 -> 39.8s).
PiperOrigin-RevId: 910608140
Change-Id: Ided0ae5bdb8e4e8196f84e08354a9ae8cfa5b626
Also provide a header-only C++ library that wraps created objects into
unique_ptrs.
PiperOrigin-RevId: 910607824
Change-Id: I0427f6dedab6aa299b3128031b055bd4d0c8e497
This change introduces MjVFS, an explicit object to mirror the C mjVFS. This is meant to replace the MjSpec.assets dict. This latter while convenient guides users towards harmful authoring patterns with respect to data duplication and spec attachment workflows. Making VFS management explicit should encourage better memory usage and allow us to make better compile time optimizations.
From this change, `spec.assets` is deprecated. However we will temporarily support backwards compatibility due to the wide spread usage. An error will be thrown if calling code tries to use a spec that uses both the assets dict and the new MjVfs.
PiperOrigin-RevId: 908772050
Change-Id: I77c6d0369307fc300c954768fed17401261e18da
mjSENS_INSIDESITE uses xipos to test containment, but for massless flex
parent bodies xipos equals the static body frame origin and does not
track the actual flex position.
Fix: in the INSIDESITE sensor case, when the object is a massless body
with positive subtree mass (i.e., a flex parent), use subtree_com
instead of xipos. This correctly reflects the mass-weighted centroid of
the flex child bodies without changing the global semantics of xipos.
PiperOrigin-RevId: 908745144
Change-Id: I527f0efb7b419345188411c9da883505156ebeea
The `vert0` array, used for parametric vertex coordinates in flexes, is now computed in the flex's local, unrotated frame when using interpolation. This ensures that the parametric coordinates are independent of the flex's initial orientation. A new test confirms that `flex_vert0` is identical for an unrotated and a rotated flex grid.
PiperOrigin-RevId: 908196464
Change-Id: I47d6bcc2bc5df581479d485480e0e947ec6d3ffd
The code for computing passive forces for flex elements is moved into new static functions `mj_flexPassiveInterp`, `mj_flexPassiveBend`, and `mj_flexPassiveStretch`. This improves the structure of `mj_springdamper`.
PiperOrigin-RevId: 907671516
Change-Id: I6d1e781bbd370331ae645a954b78092ecb1925b9
When elastic2d="stretch" is set on an interpolated flexcomp, treat the bounding box boundary as membrane elements rather than volumetric cells. This computes plane-stress stiffness over the boundary faces and updates the runtime force/derivative kernels accordingly.
Interior vertex tracking (moving vertices that follow the deforming shell) is not yet implemented so all mesh vertices need to be on the bounding box surface or the background grid should have no interior nodes (i.e. cellcount should be 1 on at least one axis).
PiperOrigin-RevId: 907654080
Change-Id: I51b90e2f6a1d1b036f9604e42de20e377dc5d3f9
Moves all internal types and structs to the "public"
render_context_filament.h header file.
PiperOrigin-RevId: 906929736
Change-Id: I7e7c315fb99a3601b09841073eaeec795718b999
Total testspeed runtime for `2humanoids100.xml` reduced by 27.6% (63.4 -> 49.5s) due to early termination on small islands
PiperOrigin-RevId: 906910915
Change-Id: If55ad468c3680ef44eda7000455a77f8003b3122
- Remove hard-coded button sizes (48×32) from toolbar icons; buttons now use default ImGui sizing, matching the existing copy-camera button.
- Remove the Unload button (available via menu).
- Add ImGui_ColorButtonEx widget with per-corner rounding via ImDrawFlags, enabling segmented button-group visuals.
- Use segmented rounding for the pause/viscous/play triplet: rounded-left, square, rounded-right.
- Make pause and play buttons 40% wider than the viscous button for emphasis.
- Replace the theme combo dropdown with a cycling button.
- Reduce toolbar height from 48px to 34px and vertically center content via WindowPadding.
- Zero out table CellPadding in the toolbar for precise vertical centering.
- Remove the speed combo's inflated vertical padding.
PiperOrigin-RevId: 906853958
Change-Id: I6e4ec7243adb9e0f1f06f8779fa896a6865c46c7
* **Dynamic Full-Window Scaling**: Charts in the Performance and Solver panels now expand to fill the entire pane, automatically arranging side-by-side or stacked based on window orientation to eliminate scrollbars.
* **Responsive Decorators**: Added reusable C++ ImPlot helper functions that auto-hide titles, legends, and tick labels when the plot surface is small.
* **Cleaner Visualization**: Refined chart titles (e.g., "CPU msec vs frame", "Convergence vs iter") and removed redundant axis labels for improved scannability.
These changes were based on the plot behavior of //third_party/mujoco/src/experimental/py/sample/implot.py This is an incremental improvement, we can make the plots even nicer in future.
PiperOrigin-RevId: 906351914
Change-Id: I8cb19c19bf807f0107c717066250a71bcf7e325f
- Reorder Physics section, move Actuator Groups to end.
- Rename "Physics Settings" → "Physics", "Rendering Settings" → "Rendering".
- Reduce IndentSpacing from 20 to 6.
- Reduce FramePadding Y from 6 to 2 for narrower buttons and popups.
- Remove explicit Unindent/Indent overrides in Rendering and Visibility Groups
sections so buttons are naturally indented under their tree nodes.
- Dynamically adjust convergence and counts plot X-axis limits based on actual
solver iterations instead of hardcoded 20.
PiperOrigin-RevId: 906244477
Change-Id: Ic3e6e6e793395158c8cb6692af885884ca3f7f50
Texture IDs were assigned using textures_.size() + 1, which is not monotonic: after erasures the map shrinks and previously used IDs can be reassigned to new textures. This causes multiple ImGui images to reference the same underlying Filament texture, rendering them all with the same pixel data. This fix replaces the size-based scheme with a monotonically increasing counter (next_tex_id_) that never reuses IDs.
PiperOrigin-RevId: 906214496
Change-Id: I5a388861ad9565c8e00e27b39cc9c76c9750ca1e
This change modifies the Warp JAX FFI to register callbacks for both CUDA and CPU platforms, allowing Warp kernels to be launched on CPU devices. MJX's io.py is updated to allow Warp to use CPU devices if no CUDA GPU is available. Tests are adjusted to no longer skip when CUDA GPUs are absent. A minor fix for sorting precision in test_util.py is also included.
Kristian Hartikainen
- https://github.com/google-deepmind/mujoco/pull/2948
Github issue - https://github.com/google-deepmind/mujoco/issues/2947
PiperOrigin-RevId: 906018844
Change-Id: I9c026b4a4e2a0276d5d3af3954fd027cf75b6d7a
* Remove the explicit io.Fonts->Build() call from InitImGui, which was deprecated in Dear ImGui v1.92.0. With ImGuiBackendFlags_RendererHasTextures already set, the font atlas is now built lazily by ImGui and communicated to backends via the ImTextureStatus_WantCreate protocol.
* Add proper texture shutdown in ~ImguiBridge by iterating ImGui::GetPlatformIO().Textures and destroying all tracked textures, per the //third_party/dear_imgui/docs/BACKENDS.md instructions.
* Remove the "OK but missing" and "WantUpdates but missing" texture recovery hacks from Update(). These handled a state where ImGui thought textures were alive but the Filament-side storage had been torn down. With proper destruction acknowledgement (SetStatus(Destroyed) + SetTexID(Invalid)), ImGui will now transition destroyed textures to WantCreate on the next frame, and the normal creation path handles it cleanly.
PiperOrigin-RevId: 905886622
Change-Id: Ic449eeaf083740a67eae9c637fb53546a6192b28
Always execute the engine in non-threading (wasm) builds.
And stop rendering if any beginFrame call returns false.
PiperOrigin-RevId: 905000139
Change-Id: I0a6f06a07a8fc0ab0251a67be13a9d170d4a905d
This is a combination of minor tweaks to the existing Studio WASM application, CMake cleanup to make it buildable, and integration with GitHub Actions for deployment.
The new features added are drag-and-drop, model specification through `?model=` URL parameter, HTTP and HTTPS resource provider, and a user-visible loading message while the model is loading.
PiperOrigin-RevId: 904594610
Change-Id: I3a73b1ca0fcd6fc9ba192469942b2dab010a9308
The filament library provides APIs for creating the low-level
objects such as meshes and textures. The compat library provides
the high-level compatibility layer between mjvScene and the core
library.
PiperOrigin-RevId: 904504900
Change-Id: Ida1aecab4b9a8aefbbf6b0a0c4ba7ff164864b8e
Refactor FilamentContext to allow multiple render requests to
be submitted onto a single RenderTarget. The main scene and the
ux scene are then submitted as two separate requests that share
the same target, resulting in a single, composited render.
PiperOrigin-RevId: 904324801
Change-Id: I7c47ec4f8d159320612fa33384c01e8db3414daa
Do not allow a mix of `elastic2d != none` with `dof = trilinear` since the latter assumes 3d elasticity.
Also, do not assume that `flex_interp > 0` in the engine. This will enable to use, e.g., `flex_interp = -1` to mean a linear surface finite element instead of a 3d finite element which is currently identified with `flex_interp = 1`.
PiperOrigin-RevId: 903852035
Change-Id: Ia6290b4a05e9e510ffb7f36d141cd525b40d3110
The reference node positions and the positions used for computing stiffness eigenvectors were previously stored in world frame. However, the runtime expects these quantities in the unrotated local frame. This caused non-zero constraint residuals and simulation instability when the grid was rotated — either by the parent body's initial orientation, or by the flexcomp's own frame attributes.
Rather than tracking each rotation source individually, this change extracts the total grid rotation directly from the cell geometry. All node positions are then un-rotated before computing the stiffness matrix.
PiperOrigin-RevId: 903232388
Change-Id: If877af89025ce1e61a76b38c29403d593d892749
Previously specs that were attached to some parent spec would resolve its asset paths relative to the modelfiledir of the parent spec. This means path resolution would change depending on the source of the parent spec. Instead, this change makes asset file path resolution relative to the "owning spec" i.e. the spec where the asset was created.
This enables workflows such as loading a parent spec via resource provider, then loading a child spec via `from_zip` or in memory providing `spec.assets` and resolution will work as intended.
PiperOrigin-RevId: 903207910
Change-Id: Ia58020ab372a3ceadf31e804d145e2ae53d8e5f9
The previous implementation only checked whether grid cells contained mesh vertices to determine occupancy. For coarse meshes with large faces, most cells were incorrectly marked empty and pruned—even cells fully inside the object volume. This change improves the algorithm by:
- Marking cells that overlap with any mesh element's AABB as non-empty.
- For surface meshes, running a flood-fill from the grid boundary through non-overlapping cells to identify truly exterior cells. This preserves empty interior cells, preventing incorrect pruning of the object's core.
- For volumetric meshes, defaulting to element-AABB overlap detection directly.
Limitations for non-watertight meshes: If the mesh contains holes larger than the grid cell size, the flood-fill will leak into the interior. In this case, all non-element cells (including interior ones) will be marked as empty.
PiperOrigin-RevId: 902675331
Change-Id: I5a84303a33d5ca7436213e7ce9aca3806c9f5a0f
Also allow multiple Meshes to be assigned at once rather than one at a
time.
This simplifies both the usage and implementation of Renderable.
PiperOrigin-RevId: 902665683
Change-Id: I23ff365a54fd6a3814ed3452b1e094ae9f698a1b
Add clamping to slider values in both ImGui widgets and mjUI to ensure they remain within the defined min/max ranges, preventing potential floating point inaccuracies from causing values to slightly exceed the bounds.
PiperOrigin-RevId: 902660458
Change-Id: Ia153ae7907f07b890f2b5ac2e3a4be93ecae7bd3
This overload allows `StringToVector` to accept a `char*` argument when parsing into a `std::vector<std::string>`, by converting the `char*` to `std::string` before processing.
PiperOrigin-RevId: 902611443
Change-Id: I2048918f915c1bac74522f368ea28f23ca9a6885
This change introduces an optimization for flexcomp objects defined by a mesh. It identifies grid cells that do not contain any mesh vertices and marks them as empty. Nodes that are exclusively part of empty cells are pinned, preventing them from moving. Stiffness computations are skipped for empty cells, reducing computational cost. The total mass is now distributed only among the non-pinned nodes.
PiperOrigin-RevId: 902565735
Change-Id: Id0a9a685536d5e18a3e42124a25ab08ff3a918f2
This CL addresses link failures when building MuJoCo with GCC and Link Time Optimization (LTO) enabled:
- Declared the `StringToVector<std::string>(const std::string&)` specialization in `user_util.h` to prevent the compiler from incorrectly trying to instantiate the general template.
- Added an explicit instantiation for `StringToVector<unsigned char>(char*)` in `user_util.cc` to provide the definition needed by its `const std::string&` counterpart.
PiperOrigin-RevId: 902557141
Change-Id: I27b585cf1deb276d4150a5cbe6cf7e59c323a20a
Combine sparse vectors in-place by first counting total `nnz` and then working backwards from the end. This removes the need for temporary buffers in `mju_combineSparse` and its callers and speeds up the function by ~10%.
PiperOrigin-RevId: 902530210
Change-Id: I4f48c327103552ab968d3915399c6067367bec9f
This provides a reduction from 26 to 18 constraints for trilinear and from 162 to 75 for quadratic. The assembly of the constraints becomes trivial. In total the speedup for a trilinear 3x3x3 grid is about 3x.
PiperOrigin-RevId: 902502398
Change-Id: I764772c7adef78da5a644f64701f842d36e4b543
Collect all entries from the recursive directory iterator, sort them, and then check for the filename. This ensures that if multiple files with the same name exist in different subdirectories, the one found is always the same, regardless of the filesystem's directory iteration order.
PiperOrigin-RevId: 902487291
Change-Id: Ia4c45cd2e3cab4a4e3825c267fc47c3134f99f76
Simplifies Renderable as it no longer has the option of owning
any Meshes. Instead, the ModelObjects owns the Meshes for
flex and skin geom (just like it owns all the other mjModel
Meshes).
PiperOrigin-RevId: 902485912
Change-Id: I8b9f9d394de6c46f7e25aa4b3885a374aad05294
Each mjEQ_FLEXSTRAIN equality now represents a single cell within a flex. This allows for more efficient sparse Jacobian computation by only considering the degrees of freedom of the nodes within each specific cell. This change gives a speedup of about 10x on a 3x3x3 model.
PiperOrigin-RevId: 902164069
Change-Id: I78eedf1d5cf39b8989fe9863c22d164922fc0efb
The flex interpolation stiffness matrix within the implicit/implicitfast solvers is now built and factorized in a banded format instead of a dense one. This involves:
- Calculating the bandwidth based on the sparsity of the mass/damping matrix and the connectivity within flex cells.
- Allocating and populating a banded matrix `H`.
- Using `mju_cholFactorBand` and `mju_cholSolveBand` for factorization and solving.
This change improves performance for flexes with many DOFs but local coupling.
PiperOrigin-RevId: 901297952
Change-Id: I3efe06353d1903ea65ab30dc49685cede228bb68
This change introduces a `flex_cellcount` field to `mjModel` to specify the number of cells in each dimension for interpolated flexes. The stiffness computation, passive force calculation, and Jacobian derivatives are updated to operate on a per-cell basis, significantly improving performance by localizing computations to the nodes within each cell.
PiperOrigin-RevId: 901216393
Change-Id: Ic23132e609de11e71bb7fef8d1f139daad2ec264
Allows the Renderable to update its own MaterialInstances whenever
Material textures or parameters are modified. Each Renderable now
also knows how it is intended to be used (i.e. scene objects or ux)
which allows it to correctly pick the underlying filament::Material
to use.
PiperOrigin-RevId: 901161990
Change-Id: Ic280731d39c272c50d6ad100cec7116e683cbc79
* Ensure compiler.usethread=0 is set before compilation in single-threaded WASM builds
* Explicitly enable exceptions for the single-threaded WASM module
* Test the single-threaded module in addition to the multi-threaded module in internal and external CI
* Consolidate wasm/tests/CMakeLists.txt into wasm/CMakeLists.txt, fixing the single-threaded benchmark test build which was missing shared linker flags
PiperOrigin-RevId: 901149728
Change-Id: If4946e29e5116610782d218906cf3f5940c1cdd0
ObjectManger now manages low-level filament Texture and
Material objects directly. Moves the IBL Texture to the
SceneBridge class.
PiperOrigin-RevId: 900626110
Change-Id: Idd39464bfb324188dd54975a500954d4ebb29006
If Renderer.__init__ raises before the rendering contexts are assigned
(e.g. width > offwidth raises ValueError, or MjrContext construction
fails), __del__ calls close() which accesses self._gl_context and
self._mjr_context unconditionally, raising AttributeError. This masks
the real __init__ failure with a noisy "Exception ignored in..." message
during garbage collection.
Pre-initialize both attributes to None at the top of __init__ so that
close() is safe on a partially-constructed instance. Add a regression
test that captures sys.unraisablehook and asserts that __del__ raises
nothing when __init__ fails via the width > offwidth path.
Fixes#3213.
The top-level CMakeLists.txt unconditionally added -pthread for all Emscripten builds, but PTHREAD_POOL_SIZE was only set when MUJOCO_WASM_THREADS=ON. This gave the ST build a live pthread runtime with zero pre-spawned workers, causing CompileMeshesAndTextures to deadlock when it tried to spawn a ThreadPool on the main thread.
Fix by making -pthread conditional on MUJOCO_WASM_THREADS. Without -pthread, hardware_concurrency() returns 0 and the existing nthread < 2 guards naturally select the serial compilation path.
PiperOrigin-RevId: 900191420
Change-Id: I0481b81fc6f7cccb52c7d7592dcf9dd317b5bad1
This change introduces `nflexstiffness` and `flex_stiffnessadr` to allow flex stiffness matrices to have sizes other than the fixed 21 per element. Higher-order flexes can now store larger stiffness matrices based on their number of nodes. The `flex_stiffnessadr` array provides the starting index for each flex's stiffness data within the `flex_stiffness` array.
PiperOrigin-RevId: 899632263
Change-Id: Ie49182c46c3777acf0c6b492345edfcf62fb5e44
Use an unlit material for decorative elements and do not render them
in the reflection pass.
PiperOrigin-RevId: 899560291
Change-Id: I3b035d556432c850ce8240e0c4c4c2d6645d7bf2
Instead, use a set of functions to create/update a Renderable
from an mjvGeom.
This completely isolates mjvScene/mjvGeom from SceneView,
making SceneView a more general purpose class.
PiperOrigin-RevId: 899475268
Change-Id: I48a3a45bc8fff3e1f514847c7a1ca8ab3a1ff16e
*** Original change description ***
Add protocols for authoring simulation environments. This is for preview only, we discourage users from using this in production code.
PiperOrigin-RevId: 899425542
Change-Id: Ifb6c5d3b762789d821bfa9826f5d6d983e8af7d3
This is an early upload of https://github.com/google/filament/pull/9867 and necessary material changes
Original PR commits:
FL0 materials are always compile via spirv-cross
postfx materials now support sRGB emulation in FL0
PiperOrigin-RevId: 899262890
Change-Id: I52c002d60790d84269674c1f0d0c5f7d6a58000c
This default forces users to use the `spec.assets` dictionary or to do other filepath gymnastics when loading URDF. Instead we encourage users to just modify file paths directly if necessary.
PiperOrigin-RevId: 899009853
Change-Id: I4bb84606a95b65be79ccc77ccbe78062d6de8773
Split up the Update function into parts and allow SceneBridge
to call them individually, passing in the ModelObjects or
ObjectManager as needed.
PiperOrigin-RevId: 898851732
Change-Id: I25c6bf920b85caa7b2ddee045475f11fb7a8bac8
This change disallows calling `mjs_delete` on an mjSpec that has been attached to another mjSpec via `mjs_attach`. Attempting to delete an element from an attached spec will now result in an error. The Python bindings for `mjSpec.delete` have been updated to raise a ValueError when this occurs.
PiperOrigin-RevId: 897266695
Change-Id: Ic0670125a3028191ec50eca890f02b5910ec8b03
This removes the need to load these decoders via mj_loadAllPluginLibraries when using MuJoCo built with CMake. Other plugins are unchanged.
PiperOrigin-RevId: 897114719
Change-Id: Iee914cc5e05798186f384a67901f1cf86bc2f887
- 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
Restore the existing Warp/CUDA-gated render_util test setup so the review change stays minimal while preserving the new batched shape coverage.
Made-with: Cursor
SceneView owns the filament Scene, View, and Camera objects.
is responsible for rendering the Scene (to which Entities
have been added).
SceneBridge takes the mjvScene as an input and updates the
corresponding light and drawable Entities in the SceneView.
PiperOrigin-RevId: 897007401
Change-Id: I3ec245f5bd48c3654672b11a55fb011f113454cc
Previously on MSVC we used DllMain to register plugins, you cannot have multiple definitions of DllMain in a single unit so you would get errors if you tried to register two plugins. This modifies the implementation to insert a function pointer into the C runtime initialization instead.
PiperOrigin-RevId: 896612678
Change-Id: I07732147b955d741c836acff6da986db0e9b9eff
Profiling `leaves.xml` with contacts disabled, this function takes up most of the time (in the implicit integrator). Total `testspeed` run time:
BEFORE: 18.5s
AFTER: 16.5
PiperOrigin-RevId: 896525902
Change-Id: I57f4a984d178956a2902212deb857bf53f53f01b
Add a note about mjswan, which extends the JavaScript/WebAssembly bindings with real-time policy control and interactive features. Requested by tatsuki.
PiperOrigin-RevId: 896513129
Change-Id: I984a41d281ffa1ad307f0b3db909140a201dd717
Consolidate all Vertex and Index buffer creation inside the
Mesh class. Users now set data pointers in the MeshData
from which the Mesh class will create the filament buffers.
PiperOrigin-RevId: 895871213
Change-Id: Ie086fcb5c31adf90e54cba168b03501e21720726
A future change will update all callers to use this
method for creating Meshes after which we will remove
the constructor that takes explicit filament objects.
PiperOrigin-RevId: 895807063
Change-Id: I50833817961ae57fbb9ed6b875c1ef286b9fdd26
Update the Mesh class so that it manages the lifetime of the
vertex and index buffers.
PiperOrigin-RevId: 895794022
Change-Id: I5eda578b8b7ed7f918e792f6181ec724729b5215
TextureConfig describes the properties of the texture (e.g.
width, height, pixel format, etc.). TextureData contains
the binary payload of the texture.
PiperOrigin-RevId: 892854578
Change-Id: I604b926ac38ff1050cac8fdf9ec767b789c0798e
All objects that are specific to the mjModel (meshes, textures, etc.)
are now managed by a ModelObjects class which is owned by the SceneView
and not the FilamentContext.
PiperOrigin-RevId: 892250776
Change-Id: Iddad66fd3ab1a60c4becdcb5d0c935ed9ea8ad90
Separate out the parts of the FilamentContext initialization that
depends on the mjModel into a separate Init function.
PiperOrigin-RevId: 890373341
Change-Id: I06b524668cd60dad804d437958f4f6606c46200b
Setting values in the mjrContext is only useful for the classic
renderer.
PiperOrigin-RevId: 890345656
Change-Id: Ie3d34dc260d13f74b569dcf575e88dde894d652b
Add a warning in user_model.cc if a flex is not rigid and has no edge equality constraints or passive forces (edge stiffness, edge damping, or vertex damping). Such flexes would not affect the simulation. A test case is added to verify the warning.
PiperOrigin-RevId: 889215981
Change-Id: I481128e1456921b632719547c676d201fdfbe931
Reflective surfaces (planes) use a custom shader to blend their
texture with a texture that contains the reflected image. The
reflected image is rendered to a texture as a separate render
pass in the SceneView.
Because reflective textures are generated after the preparation
phase, additional functions are needed to reapply the texture
to the drawable.
PiperOrigin-RevId: 889213413
Change-Id: I7bad39d62e3e5ba38cf6ac667fec5b87bfa7b2a2
A future CL will implement reflective surfaces and make use of these materials.
PiperOrigin-RevId: 889200524
Change-Id: Icbe5c0c390f89789ed0f5d5c6058a2ef31105608
Add a new mjpEncoder plugin type mirroring the existing mjpDecoder pattern.
Encoders serialize an mjSpec + mjModel to an mjResource for a given format.
New API functions:
- mjp_registerEncoder: globally register an encoder
- mjp_defaultEncoder: zero-initialize an encoder struct
- mjp_findEncoder: look up an encoder by filename extension or content type
The mjfEncode callback takes (mjSpec*, mjModel*, mjVFS*, mjResource*) and
returns 0 on success. Writing to mjResource keeps symmetry with the decoder
reading from mjResource and leaves the door open for writable resource providers.
PiperOrigin-RevId: 889187898
Change-Id: I180771b2255b91dea188ac5e2cdc3a8f0fb85364
The computation of tactile sensor values for each taxel is now parallelized using the MuJoCo threadpool when the number of taxels exceeds a threshold. Each thread processes a batch of taxels, accumulating forces from all colliding geoms.
PiperOrigin-RevId: 888606457
Change-Id: I98abf3e98a7318fc14080054bea7093ab46e8b8b
This test verifies that geom.plugin and mesh.plugin are accessible and can be assigned a plugin instance.
PiperOrigin-RevId: 888576511
Change-Id: Id17885de5fdf1f4543ac195a8b04bb01139d1bfa
This forces `CMAKE_REQUIRED_FLAGS` to be treated as a string instead of list,
so none of the args get dropped when passed through `check_c_source_compiles`.
PiperOrigin-RevId: 886717366
Change-Id: I6314f9bfabd9d62bdcad5070c8801c453c381b79
The `vertcollide` attribute in flex and flexcomp contact specifications has been removed since the next mjWarp release will support flex collisions. This attribute was previously used to enable vertex-based collisions by adding sphere geoms at flex vertices. The functionality associated with this attribute has been deprecated and removed from the XML parser, documentation, and internal data structures. Affected example XML files have also been updated.
PiperOrigin-RevId: 885595503
Change-Id: I6a78975f1bc540c09ea8b5306ff3be0962b7ab24
*** Reason for rollback ***
Rolling back obj/stl decoder inclusion as sources due to broken windows build.
*** Original change description ***
Include obj and stl decoder plugins as sources in CMake builds.
This removes the need to load these decoders via mj_loadAllPluginLibraries when using MuJoCo built with CMake. Other plugins are unchanged.
***
PiperOrigin-RevId: 885576586
Change-Id: I31e6fa4d10697862f7d800d0d771ca752747e36d
This removes the need to load these decoders via mj_loadAllPluginLibraries when using MuJoCo built with CMake. Other plugins are unchanged.
PiperOrigin-RevId: 885555524
Change-Id: I20aa5b6c55b678398345d49cb1c47667ae2bebcf
model_holder.cc modified to disable multi-threaded compilation for WASM builds. index.html `animate()` function modified so the animation rendering loop executes asynchronously with async/await calls. These changes are sufficient to make xml files without references work (e.g., humanoid.xml), more work is needed to make the vfs work so multi-file models can load.
PiperOrigin-RevId: 885537402
Change-Id: I3469cae48e7268073be334b99bf907c5ed8c27a7
This CL replaces the header-parsing autowrap system for generating
MuJoCo C# bindings (MjBindings.cs) with a new generator that uses
the mujoco.introspect module. The new generator reads pre-parsed
API data from introspect's enums, functions, and structs modules
instead of parsing C headers directly.
Changes:
- New: generate_cs_bindings.py in third_party/py/mujoco/codegen/
- Updated: genrule in unity/mujoco/BUILD to use codegen
- Updated: MjBindings.cs regenerated from codegen
- Removed: entire autowrap/ directory (9 files)
- Removed: transitional validate_codegen.py
The validate test continues to verify that the genrule output
matches the checked-in MjBindings.cs.
PiperOrigin-RevId: 885206129
Change-Id: Ib9fb883a2242dd2c039033eadee7a4a6ac91ed55
When freeing a stack frame, only poison the newly-freed memory region
`[old_top, new_top)` instead of the entire region `[limit, top)`. The old
code redundantly re-poisoned already-poisoned memory on every
`mj_freeStack` call.
Benchmarking `engine_forward_test` under ASAN:
- Before: 99.3s
- After: 75.6s (~24% faster)
PiperOrigin-RevId: 885035750
Change-Id: Ib195661ca337d13c5ff6094bcc107c4c0a617b9b
The `grad` parameter in `volumetric_dSdx` and `invariant_dSdx` is not modified, but the `const` qualifier was inconsistent with how the array was being passed, requiring an unnecessary cast. Removing the `const` simplifies the function signatures and calls.
PiperOrigin-RevId: 884598322
Change-Id: Icac8071aa8e838057dd39c979c23a4f47e1dc22d
This change improves trilinear flex elements by using reduced integration for volumetric quantities (strain trace and volume ratio) at the element center, while adding full integration for shear components at 8 Gauss points and removing the second strain invariant from the constraints, which is negligible for small strains. This reduced integration "B-bar" technique is standard in finite element analysis and prevents artificial stiffness that can occur when low-order elements are nearly incompressible. The constraint count per trilinear element changes from 24 to 26 compared to using invariants. For quadratic elements, the full 27 quadrature point are used resulting in 162 constraints.
PiperOrigin-RevId: 884570752
Change-Id: Ib74ece8f4712c2c81fbfd784524fcac52a2c80e5
Use `__SANITIZE_ADDRESS__` (GCC) and `__has_feature(address_sanitizer)` (Clang)
to define ADDRESS_SANITIZER when the toolchain doesn't provide it natively.
Fixes#3160
PiperOrigin-RevId: 884447485
Change-Id: I48ef51bca8f5c5f15f62089e73cd8fa649723636
Reorganize the README to clearly separate the "User Guide" (including npm installation) from the "Build from source" instructions.
Also added npm install instruction.
PiperOrigin-RevId: 883180811
Change-Id: I874b101c941d3a2fbff8995fb7e4d104e6f4fec2
mjrRect is a common type that will be re-used across different
rendering APIs, not just mjr_ APIs.
PiperOrigin-RevId: 882620060
Change-Id: I7f77ac9298c52c454d94c46379ff5270fd833f26
This change introduces new functions to load an `mjModel` from an XML string. Two overloads are provided: one that creates a temporary VFS and one that uses a MjVFS arg.
Also updated other places where `from_xml_string` should be used: demos, readme, etc.
PiperOrigin-RevId: 882581762
Change-Id: I8428196f8f56ae9630fcd4f0bb6763cdc1c43da0
Introduces `from_xml_path` and `from_binary_path` as more idiomatic aliases for `mj_loadXML` and `mj_loadModel` respectively. Refactors the binding of `mj*STRING` constants. Instead of exposing `get_mj*STRING` functions, these constants are now available as properties on the `Module` object. Runtime getters are added via EM_ASM to lazily call the underlying C++ functions.
PiperOrigin-RevId: 882566011
Change-Id: Id3bd5c23704fd122af30a50aed089bd3143fbc96
The pybind for recompile was not releasing the GIL when it called mj_recompile, this can caused deadlocks with the
asset loading threads. For example if a resource provider was trying to call Python.
To resolve this the GIL is release just for the mj_recompile.
Addresses: https://github.com/google-deepmind/mujoco/issues/3118
The next release will include breaking changes, so this bumps the major
version to reflect that.
PiperOrigin-RevId: 881351265
Change-Id: I970c68a0211651c07fcb8109ebd0b138196cf50a
Previously mjx dataclasses would return np.ndarray as bytes for jax tracing to hash since they are not inherently hashable. This meant that any tracing that was cached would hold on to a copy of the numpy arrays in the dataclass. Children such as mjx.Model that store large numpy arrays would end up duplicating that data 3+ times in some cases.
This eliminates O(N * array_size) memory duplication across N cached
pytree traces, saving a lot of memory on models with heavy mesh/texture data.
PiperOrigin-RevId: 880985898
Change-Id: I58d4e91fda4112e4c633818f92907d20138e962a
- handle when body0 or body1 are the default prim/world
- add site-based equalities to the constrainst list so they aren't skipped
- support connect constraints by checking for spherical joints
This can be useful, e.g. writing tests that don't depend on rendering.
PiperOrigin-RevId: 879012859
Change-Id: Ifb8d7d5bb06a2456c1b4543f0bf4945fe8155039
This will allow us to add additional renderers to the `render` folder.
PiperOrigin-RevId: 878913300
Change-Id: I205ae41250cbbcded406ad303d4e801d4cff892e
The relpose in mujoco represents the anchor in body1 space and the relative orientation of body2 in body1 space. Previously we were computing it as the relative position of body2 from body1 space.
Further, we now properly account for the setting of strictly the anchor and not the relpos by setting localPos0 *only*.
PiperOrigin-RevId: 878506356
Change-Id: I83fc7e97cd1a891e17f0bb091f8950b581be0e01
The Renderer should configure the context and flip the image when
in classic mode and not rely on the Window to do so.
PiperOrigin-RevId: 878480986
Change-Id: I1af899107647469659662abd85527cdf66f507f4
The SpecEditor improves spec editing by keeping
track of what's being edited and how it changes
over time.
PiperOrigin-RevId: 878410011
Change-Id: I7c323eeb30178dad31946095a727a21b3955f19a
The frustum_top and frustum_bottom assignments in mjv_updateCamera used
the wrong elements of the zver array, causing the principal point cy
offset to be applied with an inverted sign. This shifted the rendered
image vertically by 2*cy pixels.
Repro instructions (note compiler cache and threading must be enabled):
Assume we have a cube.stl mesh containing face data and the following XML:
<mujoco>
<asset>
<mesh name="cube" file="cube.stl"/>
<mesh name="unused" file="cube.stl"/>
</asset>
<worldbody>
<geom type="mesh" mesh="cube"/>
</worldbody>
</mujoco>
Suppose Thread A processes "cube" and Thread B processes "unused". Thread A will generate the mesh hull and will generate polygon data from faces from qhull. Thread B will NOT generate the mesh hull and will generate polygon data from faces coming from mesh file. Thread A beats Thread B to caching the mesh.
When "unused" is later pulled from the cache it gets the polygon data that was generated from "cube" which is not the same that was generated from "unused".
PiperOrigin-RevId: 878336494
Change-Id: I275b09b44490c54b2a5f09d91d0cc047026090f2
Hiding the dock icon after the viewer window closes triggers an
asynchronous screen/dock reconfiguration via SkyLight. Without
draining the main run loop, the resulting NSScreen invalidation
notification is dispatched to a GCD worker thread, which hits
NSScreen's main-thread assertion and crashes the process.
Drain the main NSRunLoop briefly after setActivationPolicy: so the
reconfiguration is processed on the main thread.
WaitForAtomicNoGil spins until the render loop consumes a pending
set_texts/set_figures/set_images request (atomic == expected). If the
user closes the viewer window after a request is submitted but before
the render loop consumes it, the render loop exits and the atomic is
never updated. The calling thread spins forever, preventing the
process from terminating.
Check exitrequest inside the spin loop so the wait bails out once the
viewer is shutting down.
The flex-SDF algorithm uses the same logic as mesh-SDF. Previous to this change, the flex was instead colliding with the convex hull of the mesh generated automatically with marching cubes from the SDF.
PiperOrigin-RevId: 876420302
Change-Id: I3bf6552b6b8e108ba4c4209bbcf10fe5f2b2fd90
Deleted MAXMESHPNT farthest point sampling instead of sorting by penetration distance is now used to select the best contact points, up to mjMAXCONPAIR. Deleted MAXSDFFACE, the BVH traversal now directly calls a function to process each leaf face against the SDF, instead of collecting face indices and processing them in a separate loop. This reduces memory by removing the need to store all intersecting face indices.
PiperOrigin-RevId: 876296914
Change-Id: I8068d634e2a01ffa9357d0c5381219d097e97abe
The documentation incorrectly claimed the position elements in relpose described body2 relative to body1 when it instead is meant to describe the position of the anchor relative to body1.
PiperOrigin-RevId: 875722437
Change-Id: Ib3b1fd9d14976623b08511068ea9e11746a28b02
This CL rolls back the change from changelist 794576123 since the previous version was more robust and stable. Compared to the original algorithm, this changes handles degenerate and very large triangles as well.
BEGIN_PUBLIC
Restore mesh-SDF collisions.
END_PUBIC
PiperOrigin-RevId: 875716983
Change-Id: If0de41dc7bbd60460779821d2338cf2d661f40d5
The editor panel allows you to add, remove, and modify spec elements
as well as recompiling and loading the spec.
Also includes utilities for handling vertically split panels.
PiperOrigin-RevId: 875658785
Change-Id: I18b10971d587db5eb1e65a033e1dc042faac7f1d
- Simplified constraint tree discovery with a unified iterator.
- Filling in a new `efc_tree` array to avoid calling tree discovery again in the constraint phase.
- Implemented dof skipping in the dense case for efficiency.
PiperOrigin-RevId: 875440387
Change-Id: Id44a5a6fe2a80edaaf30935506a023a307e21303
There are enough differences between how the two are structured that
having separate implementations makes things easier to implement
despite some minor code duplication.
PiperOrigin-RevId: 875287973
Change-Id: Id49e089e5e1944291ce79e79f8cb71d048a942cc
This change updates the Emscripten build to output files named `mujoco.js`, `mujoco.wasm`, and `mujoco.d.ts` instead of `mujoco_wasm.*`. The internal CMake target name remains `mujoco_wasm` to avoid conflicts. The package name in `package.json` is also updated to `mujoco`. New enum tests are added.
PiperOrigin-RevId: 875140314
Change-Id: Ie03e0d1db2d03dd8582d5bfcb260b3d33549c2c9
Rename stubs.cc to mjr_compat.cc. This library acts like a
"compatibility layer" that allows the filament renderer to
be implemented behind the mjr API.
PiperOrigin-RevId: 875114054
Change-Id: I5c47581cacbcadff4c78d2ad15728cc1c3a394ad
The `mjCOctree::ComputeSdfCoeffs` function has been replaced by `mjCOctree::ComputeSdf`. The new implementation removes the dependency on the `triangle_mesh_distance` library. Instead, it uses a provided `mjCBoundingVolumeHierarchy` to perform closest point queries on the mesh. The signed distance is computed by finding the closest triangle face via the BVH and determining the sign based on the dot product of the vector from the closest point on the triangle to the octree vertex and the triangle's normal.
Optional Laplacian smoothing has been added to the SDF coefficients. This helps smooth out potential discontinuities at octree level boundaries.
PiperOrigin-RevId: 875093374
Change-Id: I6fa53243a2dda107ccf255bc6b876ca5a4554d4f
This change introduces methods to cache and load the computed stiffness matrix and nodal masses for flex elements. The cache key is generated based on material properties (Young's modulus, Poisson's ratio), interpolation order, and the bounding box of the flex. This avoids redundant expensive computations when compiling models with identical flex definitions.
PiperOrigin-RevId: 874689771
Change-Id: I6d1e299baf294a984b507e2a2602b2c068610536
Display all other elements under "Elements" or "Assets" group.
Show properties for mjSpec, mjModel, and mjData for selected
elements.
PiperOrigin-RevId: 874614195
Change-Id: I128c2bec844983ac5d35a3a0b1e58b8a5b0109cb
The logic for computing Signed Distance Function (SDF) coefficients using TriangleMeshDistance is moved from `mjCPlugin::Make` in `user_mesh.cc` to a new method `mjCOctree::ComputeSdfCoeffs` in `user_objects.cc`. This encapsulates the SDF computation within the octree class.
PiperOrigin-RevId: 874572414
Change-Id: Ia2365c9c4527a252ff1d1bb43fe2c2593761e471
MujocoTest now loads plugins from MUJOCO_PLUGIN_DIR if set.
PluginTest is removed; all tests use MujocoTest directly.
testspeed binary loads plugins from MUJOCO_PLUGIN_DIR.
This is in preparation for moving common asset format parsing (obj, msh, stl, etc.) where we will always want to load those plugins.
PiperOrigin-RevId: 874194428
Change-Id: Id90805a9ba5de4627911b56d8b9c4ab4e1b29310
- Contact excludes use the UsdPhysicsFilteredPairsAPI schema. Body1 is the body with the schema, body2 is contained in the list of filtered targets within the schema.
The reduced dense factorization for flex interpolation now considers all DOFs in the kinematic chain of the body containing the flex, using mj_bodyChain, instead of only the DOFs directly associated with that body. This is necessary for correctly handling pinned flexes when their parent body is part of a larger kinematic structure.
PiperOrigin-RevId: 872854468
Change-Id: Idbe9fb459084dde9e8eb1076c70dbb685c1b0bdb
Add a simple GUI for it that allows users to enable/disable
the key binding as well as control some parameters.
PiperOrigin-RevId: 872816645
Change-Id: I8abb2803e17b4f6195d447220c436d4701b24db8
This change introduces a filter for flex-related contacts, ensuring that no more than mjMAXCONPAIR contacts are kept for each geom-flex, flex-flex, flex internal, and flex self-collision pair. The contacts are sorted using farthest-point sampling:
- Starts with the deepest penetrating contact
- Iteratively selects the contact farthest from already-selected contacts
- Produces a spatially distributed set of contacts
PiperOrigin-RevId: 872593388
Change-Id: I50b233a0dc66da6a297852c258ba514f131c8f23
- Detect linker type (lld-link vs ld) and use the appropriate stack flag: /STACK:16777216 for lld-link, --stack,16777216 for MinGW ld
- Filter out stack-related flags from Python binding modules to prevent crashes when loading MuJoCo as a DLL in Python
Fixes#3011
Toggling visualization flags via keyboard shortcuts (e.g., C for contact points, F for contact forces) causes the SECT_RENDERING event handler to unconditionally re-evaluate the camera selection, which can reset a tracking camera to free mode. This particularly affects users of mujoco.viewer who set tracking cameras programmatically.
Guard the camera update logic so it only runs when the camera selector itself is changed, not when other items in the rendering section are modified.
PiperOrigin-RevId: 871600340
Change-Id: Ia6ef2a1617c6cdc18c7d10b4b099a8f2c620a824
Root cause: resources and default mount stored pointers tied to the public mjVFS object address. If mjVFS was moved after initialization, resource close/read paths could dereference stale pointers and crash.\n\nThis change stores a stable internal mjVFS handle inside VFS and points resources/default mount to that stable handle. It also tracks the current public owner pointer and rebinds it in Upcast so lifecycle operations (including self-destruct cleanup) target the current mjVFS address after moves.\n\nAdds regression test UserVfsTest.MoveVfsAfterOpenResource, which opens a resource, moves mjVFS, then reads/closes/deletes successfully.
C++ standard says the argument to alignof must be a type. Clang and GCC are permissive but MSVC isn't.
PiperOrigin-RevId: 869823902
Change-Id: I7e113ce62a60cc9be499e8580846a5258deea001
Viscous pause is like pause but the simulation continues with zero gravity, high viscosity and passive springs disabled. It is useful to move things like cabinets with shelves---just move the shelf and the drawers come along as well.
* Updated the simulation control widgets
* Added Ctrl-space shortcut to toggle play/viscous pause
PiperOrigin-RevId: 869810053
Change-Id: Icf649e1f2631c2a64a5d2f25af9537b6a12bdf2c
* Replace various MJOPTION_ macros with a single MJOPTION_FIELDS.
* Use XVEC macro to denote vector members where there is a mixture of
vector and scalar members in a given struct type.
* Split up MJVISUAL_FIELDS into separate macros for each substruct.
* Modify engine_print.c and Python bindings struct.h/cc to use the
new X macros.
PiperOrigin-RevId: 869760513
Change-Id: Idac4fe9aa99f0258e7c79802ca9023a0d4486e2d
Most "classic" objects looked washed out. To "revert" to the old look, you can add the following to your XML files:
```
<custom>
<numeric name="filament.phong.specular_multiplier" data="0.1"/>
<numeric name="filament.fallback.scene_light_intensity" data="100000.0"/>
<numeric name="filament.fallback.environment_light_intensity" data="10000.0"/>
</custom>
```
PiperOrigin-RevId: 869725829
Change-Id: Icab0cedaa27915400497745db886c393709c14b1
--
b1734da56e293b50e7bd0cc8b9a8ee5677aa70ec by MatiasManevi <manevimatias@gmail.com>:
Improve wording for WASM Windows support status
COPYBARA_INTEGRATE_REVIEW=https://github.com/google-deepmind/mujoco/pull/3095 from MatiasManevi:wasm-readme b1734da56e293b50e7bd0cc8b9a8ee5677aa70ec
PiperOrigin-RevId: 869699309
Change-Id: I2780d2406139e33eeb5521f509245d29b69a61ab
This is to properly handle the case where the interpreter wants to exit immediately, e.g. when `mjpython --version` is run.
Currently, we call `PyGILState_Ensure` regardless of the result of `Py_InitializeFromConfig` resulting in a segfault, as in issue #2870.
PiperOrigin-RevId: 869652555
Change-Id: I3a898279eb8aa25afbaece904cfdcc4fdcc92972
--
4cabc9c52dc07ea2d64a3de6dbd58e47a2ad023c by Kevin Zakka <kevinarmandzakka@gmail.com>:
Add system identification tutorial and fix template packaging
- Add sysid tutorial notebook (sysid.ipynb)
- Include HTML templates in package-data to fix TemplateNotFound errors
when pip installing mujoco[sysid]
COPYBARA_INTEGRATE_REVIEW=https://github.com/google-deepmind/mujoco/pull/3092 from kevinzakka:sysid-notebook 4cabc9c52dc07ea2d64a3de6dbd58e47a2ad023c
PiperOrigin-RevId: 868900119
Change-Id: I53c4cc94b5fb6f864c5cee589af9dfad9bfc8744
The derivatives of actuator velocity with respect to generalized velocities were incorrectly computed when the actuator force was limited by `forcerange`. This CL adds a check to zero out these derivatives when the actuator force is at its upper or lower limit, as the force is no longer a function of velocity in this clamped state.
PiperOrigin-RevId: 868818281
Change-Id: I89742a3f04989dd11f9cfada107200015b1472a7
Adds a test which verifies that we can index into the texture buffer at offsets larger than can be represented by a 32-bit signed int.
PiperOrigin-RevId: 868756646
Change-Id: Ibc1a2b269fce41aec370611b0aab77803837e7a8
Replace dynamically-sized edge list with a dense ntree×ntree adjacency matrix for deduplication and a flat CSR representation.
PiperOrigin-RevId: 868728432
Change-Id: Iebe97a0870740e5465549b967bbde0c81e658269
On Windows, _aligned_malloc(0) returns NULL, which MuJoCo interprets as a fatal out-of-memory error. This causes crashes on models with empty arrays.
Ensure a minimum allocation of 64 bytes for any 0-sized request.
Fixes#2992
- Guard #define stat _stat with !defined(__MINGW32__) to avoid conflicts with MinGW's own POSIX-compliant stat implementation
- Replace _MSC_VER check with defined(_WIN32) for localtime_s to allow all Windows compilers including MinGW to use the secure function
Fixes#3038, #3037
The derivative calculation for actuator velocity in implicit integrators now correctly accounts for the `actearly` flag, using the next activation value when `actearly` is true.
PiperOrigin-RevId: 868598722
Change-Id: Ia180afb15b31a718170aeaf9d4ac514bb9e6073b
The implicit integrator was not correctly accounting for the off-diagonal coupling terms between flex and non-flex (parent) degrees of freedom in the mass matrix. This change extracts these coupling terms during the factorization step and applies a correction to the flex forces before solving for the flex accelerations, ensuring that the parent accelerations influence the flex dynamics. A new test verifies that the implicit integrator now matches Euler for small timesteps in a model with flex-parent coupling.
PiperOrigin-RevId: 868098126
Change-Id: Ia8cccd7dd428cd0c0898e1663a7e41017a2311b2
FuseStatic deletes static (joint-less) bodies and reassigns their
children to the parent body. Geoms and sites were reassigned, but
cameras and lights were not, leaving dangling body pointers that
crash in mjCCamera::Compile() / mjCLight::Compile().
Add camera and light reassignment in FuseStatic and FuseReindex.
File resolution only checks local file system. Resource providers may still
be able to load from a path even if it is not resolved.
PiperOrigin-RevId: 867534134
Change-Id: I802566136b965ad839393f56a4d4924dda2e1973
The functions and associated tests related to managing time-stamped data buffers have been renamed from `mju_delay*` to `mju_history*` to better reflect their general purpose beyond just handling delays.
PiperOrigin-RevId: 866978339
Change-Id: I8655e91bce783287ad2adc412d13a1c39aa2c322
Use stat() instead of d_type to check if a file is a regular file
when scanning for plugin libraries. This allows symlinked plugins
to be loaded, which is common in ROS 2 workspaces built with
colcon build --symlink-install.
The stat() approach also handles filesystems that report DT_UNKNOWN
for d_type (e.g., NFS, XFS), making the code more robust.
Fixes#3072
The single array attribute `mjc:polycoef` has been replaced by five individual double attributes: `mjc:coef0`, `mjc:coef1`, `mjc:coef2`, `mjc:coef3`, and `mjc:coef4`.
PiperOrigin-RevId: 865947359
Change-Id: If9d14a77b0a06e5dc712eeadd6e9402411570706
Fix a crash and dimension mismatch issue in user_flexcomp when dealing with interpolated="true" meshes that contain unused vertices. Previously, vertbody would correspond only to used vertices while vert included all vertices, leading to assertions or out-of-bounds access. Also enable node pinning for interpolated meshes.
PiperOrigin-RevId: 865881995
Change-Id: Id150f00f22b5f48896ffbffddf03c57b252de8c0
Otherwise, if you try to open a random file in studio, it will crash.
PiperOrigin-RevId: 865372002
Change-Id: I96d3121b6de792daaff53155ea2436ac3f6668db
Initialize the EGL context in the Renderer when using the classic
rendering engine with no window.
PiperOrigin-RevId: 864884976
Change-Id: Ic6cc4637855a361e41f3bfb4b738c012ec93711f
The BM_CompileManyTextures benchmark temporarily sets the MuJoCo cache capacity to 0. This change ensures that the original cache capacity is restored after the benchmark completes, preventing side effects on other tests.
PiperOrigin-RevId: 864332653
Change-Id: I5f756e30d4922d5e6f9b70d19ba9d0e31cde9259
Resource operations (e.g. mju_openResource, mju_readResource, and
mju_closeResource, etc.) are now all handled by a VFS instance. It
is now up to the VFS to determine which provider to use in order to
handle those operations.
This allows us to dynamically add/remove (aka "mount") providers to
a VFS to handle special requests. mj_addFileVFS and mj_addBufferVFS
have been reimplemented as two such use-cases. Moreover, we expose
the mounting behaviour with two new functions: mj_mountVFS and
mj_unmountVFS.
PiperOrigin-RevId: 863248779
Change-Id: I8bcbd5445814ba1e72c6d7b80ad6a054f5f1df57
The original render_gl3.c code does the following:
```
mjr_setf4(plane, 0.5*scl[0], 0, 0, -0.5);
glTexGenfv(GL_S, GL_OBJECT_PLANE, plane);
mjr_setf4(plane, 0, -0.5*scl[1], 0, -0.5);
glTexGenfv(GL_T, GL_OBJECT_PLANE, plane);
```
The 4th component of the GL_OBJECT_PLANE function effectively
describes a UV-offset for the generates uvs. In our filament
implementation, we had overlooked this 4th component.
PiperOrigin-RevId: 863181644
Change-Id: I60688117ea2019257da683cdda0c7d389dd5af1e
The link to the named access tests in `tests/bindings_test.ts` was incorrectly formatted.
PiperOrigin-RevId: 862786877
Change-Id: Idf10d75638e55b7d3b0312c765a977274d014857
Adds support for mjTRN_TENDON actuators in the USD decoder. Modifies the tendon path parsing to correctly handle side site indices, allowing -1 to signify no side site for a given path element.
PiperOrigin-RevId: 862755621
Change-Id: I18b13b160e3d1c27945d0972a69012d6307131e9
internally) when we want to render the GUI to the same target as the
scene.
PiperOrigin-RevId: 862647358
Change-Id: If3656032b74a168b804dfa34ef3eb97c9817c2c0
* Added color to widgets which have changed from their initial values and the ability to revert to their initial values by clicking with the right mouse button
* Added some reasonable range limits, which are especially useful for drag widgets
PiperOrigin-RevId: 862220411
Change-Id: I1d2c61d8889d5ec29890d81b5f97af576cb5c611
This in preparation for an upcoming change that uses native file dialogs instead
of our very basic ImGui file dialog.
PiperOrigin-RevId: 861671041
Change-Id: I9b00c05efdda5e37ffe15048a2ccf66f6eca89d9
Update SetFrameBuffer to allow users to customize which swap chain
(window or offscreen) to use for rendering both the main mjvScene
as well as the GUI.
PiperOrigin-RevId: 861624061
Change-Id: Ife7bfc447afb007016300438fc5f88a8e4cfa0f6
Resource operations (e.g. mju_openResource, mju_readResource, and
mju_closeResource, etc.) are now all handled by a VFS instance. It
is now up to the VFS to determine which provider to use in order to
handle those operations.
This allows us to dynamically add/remove (aka "mount") providers to
a VFS to handle special requests. mj_addFileVFS and mj_addBufferVFS
have been reimplemented as two such use-cases. Moreover, we expose
the mounting behaviour with two new functions: mj_mountVFS and
mj_unmountVFS.
PiperOrigin-RevId: 861550939
Change-Id: I070eb4bcc2982466c8f368f7918005538baa5185
Removed the GIL lock in set_figures, clear_figures, set_texts, clear_texts, set_images, and clear_images
PiperOrigin-RevId: 861245200
Change-Id: I52f21d82f9813752c7cb357213c24ea6188583db
The dense Jacobian arrays `J0_dense` and `J1_dense` are now zeroed only once before the vertex loop. Inside the loop, only the entries that were actually used are zeroed out after being added to the sparse Jacobian, allowing for efficient reuse of the dense arrays across all vertices.
PiperOrigin-RevId: 860799056
Change-Id: Ia61daae5eeb2f4dbc0c5d8c0064622a881e92b7a
Use unsigned size_t instead of signed mjtSize for size multiplications to avoid Clang's overflow-checking intrinsic. This is semantically correct as size calculations are inherently unsigned.
PiperOrigin-RevId: 860213177
Change-Id: I837aa6556335478969d4977492d0f231419f020a
Use unsigned size_t instead of signed mjtSize for size multiplications to avoid Clang's overflow-checking intrinsic. This is semantically correct as size calculations are inherently unsigned.
PiperOrigin-RevId: 860172221
Change-Id: I3b6cb720db8771b8f266f1927e2980ac7514538b
This change updates all size-related members within the `mjModel` struct from `int` to `mjtSize`. This allows MuJoCo to handle models with a larger number of elements. Corresponding changes were made to macros, function signatures, and I/O routines to accommodate the new `mjtSize` type.
PiperOrigin-RevId: 860144595
Change-Id: I701c6d607715d240766b6210a9773cd9e4258c59
This change adds an Emscripten binding for loading binary MuJoCo models (`.mjb`) from the virtual filesystem. The new binding, `mj_loadBinary`, takes a filename and an `MjVFS` object, enabling the loading of models that reference assets within the VFS.
PiperOrigin-RevId: 859740455
Change-Id: I9f9d8bbba0b57422e2356867e4282a1b04566475
There are three ways to load a model: from a file, from a buffer, or an
"empty" model. Instead of overloading a single function to do all three,
provide three separate functions.
Also disable model loading functions that will not work for emscripten.
PiperOrigin-RevId: 859051341
Change-Id: I71557d31d0e7c9c6882895c36116d300f19e255d
The ImGui table API cell padding variables can be used to adjust the positioning of the UI in the box.
PiperOrigin-RevId: 858137824
Change-Id: I1ce1519c0abd67bc5fafc30f9a18dfcf18c2a313
This change introduces two new USD API schema:
* MjcEqualityAPI - base API for representing MuJoCo equality constraints in USD, this will typically be applied to joints such as UsdPhysicsFixedJoint.
* MjcEqualityWeldAPI - extends MjcEqualityAPI for MuJoCo's weld equality constraints with an attribute for torqueScale.
The usd_decoder is updated to parse UsdPhysicsFixedJoints and convert the new schema attributes into the appropriate mjsEquality data fields.
PiperOrigin-RevId: 856723634
Change-Id: I0982fd3168b643f8e91d87bb5ae5933e526b63a1
Adds a new window that allows the user to display one or more renders from
the different cameras in the scene.
PiperOrigin-RevId: 856607089
Change-Id: I7268ffd3ef62b9b4d62ce8d004fdbbec92b42af4
Since relationships in USD can only contain a single instance of a path, it was previously impossible to have a tendon path that visits the same wrap target more than once. This is a fairly common occurence when dealing with tendons that have pulleys.
With this change, if mjc:path:indices is not defined then the behaviour is as it was and the mjc:path is considered to be ordered. If it is authored then the parser will use the indices into mjc:path as the order. This mirrors other similar concepts in USD such as face vertex indices.
PiperOrigin-RevId: 856339887
Change-Id: I6b9503973de377acdb0689be168c16e4aa19b70b
Most of it is done leveraging existing X Macros (indexers.h, indexer_xmacro.h) used for python bindings already.
PiperOrigin-RevId: 856205245
Change-Id: Ic72443999065040af3042bbf3f9f68c5b70d309d
Resource operations (e.g. mju_openResource, mju_readResource, and
mju_closeResource, etc.) are now all handled by a VFS instance. It
is now up to the VFS to determine which provider to use in order to
handle those operations.
This allows us to dynamically add/remove (aka "mount") providers to
a VFS to handle special requests. mj_addFileVFS and mj_addBufferVFS
have been reimplemented as two such use-cases. Moreover, we expose
the mounting behaviour with two new functions: mj_mountVFS and
mj_unmountVFS.
PiperOrigin-RevId: 856166919
Change-Id: Id723d612ffc0bff020705cf19ef95fbf24676840
Regarding mj_compile VFS argument:
I was encountering a memory error when using `std::optional<MjVFS>` with `mj_compile` (because vfs should be an optional argument of the function). This is likely because `MjVFS` doesn't have copy/move constructors, which are required for types used with `std::optional`, causing issues with memory management when std::optional copies the MjVFS object.
To solve this and to make vfs an optional argument to `mj_compile`, I replaced `mj_compile_wrapper` with two overloaded functions. This avoids using `std::optional<MjVFS>` and resolves the memory issue, while still allowing mj_compile to be called with or without the vfs argument from JavaScript.
But what if we instead add those copy/move constructors so it works with `std::optional`?:
While making `MjVFS` copyable or movable would theoretically allow it to work with std::optional, it's not a feasible approach in this case.
The MjVFS struct manages file data in memory, allocating buffers when files are added and freeing them when `mj_deleteVFS` is called in its destructor. A copy would require a deep copy of the entire virtual filesystem, but MuJoCo does not provide a public API function (like a "mj_copyVFS") to do this. Implementing a deep copy manually would be complex and fragile. A shallow copy would result in multiple MjVFS objects pointing to the same memory, leading to double-free errors when their destructors run.
Given these constraints, MjVFS cannot safely be made copyable. The approach of providing two overloaded C++ functions is better.
PiperOrigin-RevId: 855740541
Change-Id: Ia08b6db8868ad245f07145db3fb0322cb9f737cb
All known implementations were effectively the same as the default fallback. It was just adding unneeded complexity. Removing this now will help with upcoming improvements to resource providers.
PiperOrigin-RevId: 855163273
Change-Id: I529fc18d0d03a8dc676c909ec9e4b1da1454d414
This allows calling `mujoco.mj_copyData(dest, model, src)` to copy data between existing `mjData` instances.
PiperOrigin-RevId: 855150139
Change-Id: If122cb7acf590846e25ee15f9770c3c087147169
Updates function comments to consistently use a semicolon (`;`) before describing the return value and to use the imperative form "return" instead of "returns".
Also fix error in docstring of `mjp_registerResourceProvider`
PiperOrigin-RevId: 854888532
Change-Id: I311239a2770ded5febece9958ae4e94c1e522600
Add usd_decoder to mujoco/plugin.
- Previously was src/experimental/usd/usd_to_mjspec.cc, now that same spec is returned by the plugin.
PiperOrigin-RevId: 854350962
Change-Id: Ia980190a557c50ce8197980922a2594b613859b4
Explicitly free allocated memory for local resources. (Upcoming
changes to `mju_closeResource` will not work for local resources.)
PiperOrigin-RevId: 854254013
Change-Id: I5cbb8264b590327767d5500f0c2a32ebe036bc4f
When compiling with threading, we will block the main thread anyways waiting for all threads to complete.
PiperOrigin-RevId: 854230560
Change-Id: Ief689d381afaa3aacc5d712a8df0cb4b6762251c
This allows us to remove the special "LoadModelFromString" resource provider.
PiperOrigin-RevId: 854207845
Change-Id: I6d00f2ab99b4351866e1d39dbeed96f29aaaf915
This removes the need for a custom mjResourceProvider, but does require
reimplementing part of mj_loadXML in the fixture.
PiperOrigin-RevId: 854170820
Change-Id: Ib455cc5cdb5138213eb7e996dc32ac156f22a859
This attribute allows specifying the intended output types (e.g., RGB, depth, normal) for each camera in the XML. The output types are stored as bit flags in `mjModel`.
PiperOrigin-RevId: 853316261
Change-Id: I1ad2e94102593cf402756f8f4c80509371ca86d2
(We may consider splitting this class up into specialized subclasses at a later date.)
PiperOrigin-RevId: 851290789
Change-Id: Iee00b8e906eeb911de5799f784475ac6916ab55b
This will fetch and call the build_usd.py build helper for OpenUSD and build within the MuJoCo _deps folder. Simplifying the build process for MuJoCo with USD. Users can still provide their own USD build, but must now do so via pxr_DIR.
PiperOrigin-RevId: 846735578
Change-Id: I0da7eb2da6465e2d518084340e762bf370adb6d5
17% overall speedup for `100_humanoids.xml` as measured by `testspeed`
PiperOrigin-RevId: 846723342
Change-Id: Ibc41487bfc576c992f14853640d0b6000f5b47b2
The new symbolic function is a generalization of the function it replaces. In this CL it takes two unused temp arrays. The actual change in behavior happens in the followup.
New benchmark test output below ("L" is 2 humanoids and 100 free objects, "XL" is 100 humanoids). Note that `symbolic` is only ever called once per Newton iteration, while `numeric` is sometimes called multiple times (when the rank-1 update fails), hence timing them separately is valuable.
```
Benchmark Time(ns) CPU(ns) Iterations
--------------------------------------------------------------
BM_old_L_mean 84382 84703 19547 11.807k items/s
BM_symbolic_L_mean 16345 16381 88414 61.055k items/s
BM_numeric_L_mean 10986 10994 120000 90.999k items/s
BM_old_XL_mean 1241208 1244212 1200 803.924 items/s
BM_symbolic_XL_mean 130917 131042 12720 7.631k items/s
BM_numeric_XL_mean 77004 76767 21116 13.029k items/s
```
PiperOrigin-RevId: 846704054
Change-Id: Ib0c365724d63bf2b81606ca5353756a6496c3a26
A future CL will allow users to specify search paths in their settings.
PiperOrigin-RevId: 846240293
Change-Id: I1a1a4027d0fc85004a12fe01a406f50fd929f3e4
Displays the list of bodies and joints from the mjSpec and displays
values for the selected element.
Functionality is very limited and a bit non-intuitive. However, we want
to get this into our users hands to start getting feedback.
PiperOrigin-RevId: 842228895
Change-Id: I2491cd5e0acaf622110e0f6b8406919024d3607a
Initialize playback speed based on the model's global.realtime setting.
Adjust layout and tweak colours of the status and tool bars.
PiperOrigin-RevId: 842214796
Change-Id: Iff9cda74178df28a0787693242fee81e011014fc
Image lights are not normal lights, so use nullptr as a placeholder.
Add checks for nullness when iterating over the lights.
PiperOrigin-RevId: 840695579
Change-Id: I092515ae814523e85f4f5ce87b2bac2241f4ea35
In this case, we'll use the mujoco material color which is then multiplied with a white fallback texture.
PiperOrigin-RevId: 840244521
Change-Id: I2134f45dcbaed7db268e5278ca8ac5429488943d
Inlines the platform::LoadMujocoModel into the App class which simplifies
the logic and allows us to correctly display loading errors.
Also updates shortcuts:
Load Model (Ctrl+L) -> Open File (Ctrl+O)
Reload Model (Ctrl+R) -> Reload Model (Ctrl+L)
PiperOrigin-RevId: 840232553
Change-Id: I957d29046ae681d2aeb69310c3a2eec64d042d49
Keep track of all textures and recreate them as needed. This makes imgui
textures robust to render context reinitialization.
PiperOrigin-RevId: 840228061
Change-Id: Ia4ac35ff93a41ac74020f334adc438df4b030f7c
Previously we were computing at material update time a color for the geom based of it's
segid. This made segids unrecoverable from the resulting buffer. With this change
we allow SceneView creators to specify if they want the segmentation buffer to be purely
for visualization with distinct colors.
PiperOrigin-RevId: 840016870
Change-Id: I5920f248ace0901023e6545c7d8dd2b23f9aa397
This also moves the read call into the frame, per the recommendation in the filament documentation. We also don't need to flush and wait for the engine twice, just defer to the end of readPixels.
PiperOrigin-RevId: 839953612
Change-Id: I52205147794440322ca976c52fb4905207c21473
`tuple` is better than `list` for constants if we don't expect they get modified by other parts of the code
PiperOrigin-RevId: 838748519
Change-Id: Ic950a78be7ad7518361c046d7e4542607070d3a2
Add a light box-shadow to docutils tables (excluding mjcf-attributes) when in dark mode or auto mode with dark preference, so that the table boundaries are visible against the dark background.
PiperOrigin-RevId: 838741947
Change-Id: Ic788f9669ea65d290f927927b389fcb51227a55a
This change introduces a `wrapper_struct_name` function in `structs.py` to consistently generate the name of the C++ wrapper struct from a C struct name. All call sites in `functions.py` and `structs.py` that previously used `common.capitalize` for this purpose now call `wrapper_struct_name`.
PiperOrigin-RevId: 837544242
Change-Id: Ibe5fea8294283dae63bb8d064fd8beb8cfd3f2fe
* Move all bindings into a single EMSCRIPTEN_BINDINGS block
* Move all auto generated bindings line to the start of the block
* Alphabetically sort the constants binding lines
PiperOrigin-RevId: 837142009
Change-Id: I218a37dbc0ca6c6f16a455718889c08fe1b41d56
The Physics class is no longer needed. This makes Studio similar to
other toolbox-based apps (like web demo and python viewer) which
manage their own mjModel and mjData instances.
PiperOrigin-RevId: 836588076
Change-Id: I3f695b49bf6a7bba1a2b639d3d75d0c996582f06
Also moves perturbation handling up to the App.
Combined, this makes Physics::Update only about advancing the StepControl and resonding to its Status.
PiperOrigin-RevId: 836569506
Change-Id: I148c787f0e1c18baac3e3038ee6ad0e337eb92a8
- Add Toolbar and StatusBar.
- Reconfigure sections into Settings and Inspector groupings.
- Use docking for Settings/Inspector panels.
- Rename "Free" camera to "Tumble"; add WASD-based free camera.
- More dynamic layout of table-based elements.
- Remove "non-classic" UX mode.
- Switch to light mode by default.
PiperOrigin-RevId: 835174573
Change-Id: I1855caa79f00002e44ed2516631675727bdcb9f6
This change makes `mjtSize` a signed, rather than unsigned 64-bit integer. While sizes are non-negative, the type promotion rules for unsigned integers can lead to unituitive downstream bugs, and 8 billion terabytes are enough bytes.
PiperOrigin-RevId: 834292964
Change-Id: Iea9c47c2a5d80fde63851a543d59ed0549db0f01
For each contact point, we used to first compute the vertex weights on a triangle and then add a contact point per vertex using the flex interpolation (trilinear or quadratic), obtaining the total weight by multiplying the vertex weight and the basis function value at that vertex. After this change, each contact point is added directly by evaluating the basis function directly a the point.
PiperOrigin-RevId: 834218909
Change-Id: Ic0fdb03fc0ef5478798c293df99204fd33116fd1
This fixes a bug where the wrong instance was being used in some cases.
PiperOrigin-RevId: 833818151
Change-Id: If8b0cb90017ee0b89cde98a5ae64c36704c7338c
* Removed the caution callout since some internal CI has been implemented.
* Added to clarify the state of bindings build process on Windows.
* Fixed the formatting of a note callout in the Testing section.
PiperOrigin-RevId: 831899135
Change-Id: I9f105b91e924368c8e84da7114e1b1d3e48c185a
This reduces the amount to yaml we need to know/write and makes the steps reusable in a clearer way than yaml anchors. Also Made sure that bash commands are executed with -xe set to log the command before executing and to fail the script on the first failing command.
PiperOrigin-RevId: 831823786
Change-Id: I7410c13decb914ef079ac4dd19a49481c452f3ec
In `structs.py`, a `RuntimeError` is now raised when an anonymous struct is encountered but is not present in `STRUCTS_TO_BIND`.
PiperOrigin-RevId: 830978376
Change-Id: Id64720a12c3cce313bd513a40a74ddf57718a7d1
* All tests moved into wasm/codegen/tests folder
* Merged wasm/codegen/helpers/ into wasm/codegen/generators/
PiperOrigin-RevId: 829471173
Change-Id: I2dbc5d9351771817ec260c7ddf87c31e66a9eabe
This change exposes the `mjENBL_SLEEP` flag from MuJoCo's `mjtEnableBit` in MJX's `EnableBit` type.
PiperOrigin-RevId: 829446801
Change-Id: Ia95b31a3488ecba0431646c889e10a5ae5fb60e8
This enables decoders to leverage their own file resolution systems. For example: USD can compose a stage (scene) from memory, via a file on disk, or via custom asset resolver.
Passing it through to the decoder reduces the need for custom resource providers that wrap these other resolution systems.
This will also enable a fun, but likely niche usecase where the decoder does procedural generation and does not have to be backed by a resource. See the tests for an example of this.
PiperOrigin-RevId: 828939899
Change-Id: Ic319a685332d91198a4ae926867c834bf7f7f724
Interactions (like moving the camera or mouse picking) no longer depend
on needing an mjvScene. Instead, everything is done relative to the
camera directly.
This duplicates some code in engine_vis_visualize which we will try to
resolve and recombine at a future time.
PiperOrigin-RevId: 828461259
Change-Id: If26329c1a7c37516f0213b18056c3e31760f60ae
Added `sphinx.ext.extlinks` to the Sphinx configuration and defined `extlinks` for `:issue:` and `:pr:` roles, pointing to the MuJoCo GitHub repository. Updated `changelog.rst` to use these new roles, replacing `:github:issue:` and `:github:pull:` which are currently failing.
Also fix a formatting bug in the 3.3.7 changelog
PiperOrigin-RevId: 828403002
Change-Id: I7f0134e4dd555fc59a3fee090338de56aababe1c
This change modifies the code generation for structs in `bindings.cc`. Instead of placing each struct's constructor and member functions under individual markers, all autogenerated struct source code is now grouped together under a single `// {{ AUTOGENNED_STRUCTS_SOURCE }}` marker. This improves the organization of the generated file and simplifies the template.
Future work would move the rest of the structs into this pattern
PiperOrigin-RevId: 828390272
Change-Id: Iee9d0e8766db86b2c1d4296a37ac7a8e6e05428b
The `sort_structs_by_dependency` function now takes a dictionary of `WrappedStructData` and uses the pre-computed `typename` within `WrappedFieldData` for dependency analysis, instead of re-introspecting the AST. This change also includes populating the `typename` in various `WrappedFieldData` generation methods.
PiperOrigin-RevId: 828389481
Change-Id: Ie97c1a66e5e69bd148a928fda26afdaa09f56687
Updated the wasm/README.md to describe how to manually run the benchmark tests.
PiperOrigin-RevId: 827881670
Change-Id: I1d524851d9f3f8182ecbfcc649bb9a5a61d716ae
* Add newline function to code_builder
* Remove type aliases which made jump to definition less ergonomic
* Add types to constants
PiperOrigin-RevId: 827863199
Change-Id: Ib4390d398926466ecce491a3d0ebe308ed5e0cbe
This enables two workflows:
1) Users that parsed some other format into MjSpec, or built it programmatically can export animated USD easily with as minimal as possible interaction with USD.
2) Creating a spec from USD, then modifying the spec, should not cause a duplication of data when writing to USD.
PiperOrigin-RevId: 827627520
Change-Id: I02c8c14a18569547710e54f3704d52ac0bf70ce6
- When `mjData.nefc` was 0 (solver not run at all), we were plotting the stale diagnostics from the last run; now fixed.
- In the case where islands were used, the semantic of the plotted diagnostic `sqrt_nnz` (square root of Hessian nonzeros) is changed. It used to be the sum of square roots of solver nonzeros per island, it is now the square root of the sum of all nonzeros in all islands. The semantic `sqrt(sum(nnz_i))` was found to be more consistent than `sum(sqrt(nnz_i))`, in the sense that switching islanding on/off leads to smaller changes and is more in line with the interpretation of islanding as [block-diagonalization](https://mujoco.readthedocs.io/en/3.3.7/computation/#constraint-islands).
PiperOrigin-RevId: 827624908
Change-Id: I5fc86364ead585a4752a6d44823fb75cf6c7c318
Since we don't do any on demand data loading for USD and always convert everything it should be safe to use the SdfLayer API instead of the SdfAbstractData API. This enables other codepaths such as the USD writer class to reuse the same logic to generate USD specification from an mjSpec.
PiperOrigin-RevId: 827431722
Change-Id: I60a581e0c9577164a4a66229ea9dcb8912afcf74
- plugin system similar to mjpResourceProvider, but instead of loading a resource it converts an existing mjResource into an mjSpec.
- The returned spec is then composed into the referencing spec.
- This enables different file types to generate arbitrary specs, and allows us to separate format parsing from compilation code.
Follow up CLs will move some of the logic in src/engine for PNG, USD, KTX, OBJ loading into decoders.
The mj_parse function MjSpec from a given file, it's a more generic version of mj_parseXML.
In it's implementation, mj_parse as opposed to mj_parseXML will look for any registered decoder and
not assume we are striclty dealing with MJCF.
PiperOrigin-RevId: 826149497
Change-Id: I0ece26904280cb94bd5ded6dd5a565c539d60254
This allows setting attributes with bind using a list of mjSpec objects as arguments.
PiperOrigin-RevId: 825456920
Change-Id: Ie6af956feab0a805175d7aaecf26e071401fbf05
The user can recover the old behavior by passing prefix="".
This enables to attach children with default and save a valid result to XML.
PiperOrigin-RevId: 825011185
Change-Id: Id20c2589da928bf92b77bdb01cfba73dfc1d2f52
`xfrc_applied` mostly contains user perturbations which are rare. It is very often identically zero and for large arrays `mju_isZeroByte` is significantly faster than `mju_isZero`.
PiperOrigin-RevId: 824975356
Change-Id: Iadb1d300d68cf12de00c14a0665bd89924a2d7e0
This includes the filament, toolbox, and studio projects.
Adds a MUJOCO_BUILD_STUDIO option to enable building of the `studio` app (disabled by default).
Adds a MUJOCO_USE_FILAMENT to allow the studio app to use the filament rendering backend. A separate MUJOCO_USE_FILAMENT_VULKAN flag can be used to enable vulkan rendering.
PiperOrigin-RevId: 824602367
Change-Id: I26d46c16211ae2118f96c163c4194fea5b5a15a9
Adds targets for dear_imgui, implot, filament, sdl2, and webp. These
targets are not currently used.
PiperOrigin-RevId: 824554405
Change-Id: Ibebdd50752d251852a945b6abc230e2c6e65fae9
This ensures that at e.g. the barycenter of the triangle each vertex has weight 1/3, as one would expect with barycentric coordinates, rather than 1/sqrt(3). This makes it consistent to the finite element interpolation used in the passive elastic forces.
PiperOrigin-RevId: 823458736
Change-Id: Ia5c02cba186a80612de38402f791695c33e991ab
The smaller size is a warning/error on some targets:
```
error: ‘ bytes’ directive output may be truncated writing 6 bytes into a region of size between 0 and 15
```
PiperOrigin-RevId: 823047552
Change-Id: Id66b5828cf84a512dffc452753f1881deb685584
FetchPackage calls FindOrFetch, but sets USE_SYSTEM_PACKAGE to OFF
(i.e. do not find, just fetch). It also sets EXCLUDE_FROM_ALL.
PiperOrigin-RevId: 822565180
Change-Id: I70476f57b8d3371cefd02e840add279423913f3f
This function allows the caller to extract a subset of components of a state previously obtained via `mj_getState` without having to first write it back into `mjData`.
PiperOrigin-RevId: 822165077
Change-Id: I6433261f4f5ec2e8d024bb7dee8f7dbf1e62666c
This is a more general API in preparation of a higher interpolation order
PiperOrigin-RevId: 820174741
Change-Id: I81bd52ab44e0485d72579e21d1c8a48a1b35ec3f
This is strictly an out array and should not be read before it is written to. This change improves MSAN coverage of engine code.
PiperOrigin-RevId: 819767673
Change-Id: I57500c8147f4774d326cf87ea3bac5420e4dd54d
*** Reason for rollback ***
BEGIN_PUBLIC
Holding off on a minor version bump until the next release.
*** Original change description ***
#mujoco update the version to 3.4.0 ahead of the 3.4.0 release.
Bump the version to 3.4.0 ahead of the next release.
***
PiperOrigin-RevId: 818748143
Change-Id: I722e9beb80c61a48bd997da6a1840777a81d5036
The truth is that all these solver-related values should be moved out of `mjContact` altogether, but that can be done in a future followup.
PiperOrigin-RevId: 818624976
Change-Id: I5b9e63927098cdf26b9f8acfdd9d86e75d6ce331
An earlier refactor incorrectly assumed that only selected bodies needed
labels.
PiperOrigin-RevId: 818568645
Change-Id: I7aea07c5342673dd589e1891d0db1f2b0c489fe4
This is intended as a drop-in replacement for mjr_render to enable high
quality, physically-based rendering (PBR) using the filament render engine.
This is a work-in-progress and, as such, some features may be missing. This
is also a code-only drop; build files (including instructions on how to
generate the filament materials) will be provided at a later date.
This library is intended to be run with the experimental studio app.
PiperOrigin-RevId: 817593684
Change-Id: Ib9cd14c1881e4897c1111275bd749aa38ebb5317
Also, unify the meaning of fitting a geom to an AABB: it now means to find the smallest geom such that its AABB contains the mesh AABB.
Fixes#2881.
PiperOrigin-RevId: 817097544
Change-Id: I883c686feffa803bd16ba461db24a474dfec7712
Previously this was just used for the USDA file format token, which we can confidently just construct ourselves.
Since [this PR in OpenUSD](https://github.com/PixarAnimationStudios/OpenUSD/commit/5bb9ad1fb2a034e1f9b48c7db936f296b5b78e25) the file lives in a different place now and public usage will be deprecated anyways.
PiperOrigin-RevId: 816801204
Change-Id: I42e92d2af52b0f9ff0a679ecb96f3d2dbf623531
This is a no-op "prefactor" of `mj_crb` to reduce the number of lines changed in the upcoming sleeping CL. The main change here is that `mj_crb` now avoids accessing the model and data pointer repeatedly, but instead has the input and output pointers explicitly declared as local variables. A benchmark test found a healthy **14% perf bump** due to two changes:
- Adding `restrict` to `mju_mulInertVec`
- The function-local pointers.
Adding `restrict` to the local pointers had no effect. Note that `mj_crb` is not a particularly expensive function so these speed bumps are not significant per se, but rather indicative of possible future gains with these techniques.
```
Benchmark Time(ns) CPU(ns) Iterations
---------------------------------------------------------------
ORGINAL BASELINE
BM_CRB_BASELINE_mean 4325 4348 993200 230.052k items/s
BASELINE + RESTRICT
BM_CRB_BASELINE_mean 4057 4090 1186150 244.573k items/s
LOCAL POINTERS + RESTRICT
BM_CRB_mean 3772 3800 1001750 263.209k items/s
```
PiperOrigin-RevId: 815798225
Change-Id: Iffdf57b544e8e10562807c617f73ca4ccd1c614f
This will allow assets to cache compiled results with different parameters. For example, we could cache both an RGB version of a texture and a Mono version.
PiperOrigin-RevId: 811341377
Change-Id: Ifd6a4ff88661a2b38be47c02d6a666de2c202885
*** Reason for rollback ***
mjv_makeScene does not call mjv_defaultScene directly. Instead, it calls mjv_freeScene which calls mjv_defaultScene. However, mjv_freeScene attempts to free pointers if they are not NULL and if you don't call mjv_defaultScene then you'll have garbage data in those pointers.
*** Original change description ***
Remove redundant mjv_defaultScene call since its called by mjv_makeScene
***
PiperOrigin-RevId: 810442645
Change-Id: Ica50493d6769a0afb086f9ead99d731cdf0d75d9
For backwards compatibility in the Python bindings, both `spec.compiler.meshdir` and `spec.meshdir` are now allowed.
Fixes#2834.
PiperOrigin-RevId: 809060113
Change-Id: Ie23f1c5dd57de43568312a8e062906f4013bb474
This module has been deprecated for many months and its replacement is jax.ffi.
PiperOrigin-RevId: 808567797
Change-Id: I5b4f4eee5e65ccd86e597c5761e68c36292b6209
Also:
- update the namespace to `toolbox` (instead of `filament`)
- Add copyright notices to all files
PiperOrigin-RevId: 808474353
Change-Id: Id1fe86c5d183c8e91bec8509b6c0830b5fe84c1c
This is done by detecting the hanging nodes and compute the function at those location by interpolating the corresponding coarse vertices.
PiperOrigin-RevId: 807700228
Change-Id: I27dcb85361ca445c2099dd07b280cae5c92d3131
This means that two adjacent nodes can only have at most one level of refinement difference.
Note: This is a small breaking change for mjWarp since the order of the children was flipped.
PiperOrigin-RevId: 806299445
Change-Id: Ia326a31c7a8162ae02d70c868d87779198e805be
The octree construction is now performed using a breadth-first search with a `std::deque` to manage tasks. A new `OctreeTask` struct encapsulates the state for each node to be processed, and a helper function `Subdivide` is introduced for subdividing the Octree nodes.
Also reduce the number of (center, size) to (min, max) conversion for the bounding box representation in order to avoid duplicated vertices in the Octree due to floating point errors.
PiperOrigin-RevId: 806214441
Change-Id: Iff9015ebe4705522db743c478cef5acf1a7312b7
Previously, it was assumed that attaching was the last operation performed on the mjSpec, so keyframes resulted in the incorrect size. In order to prevent information loss, we now only allow the resize function to expand the keyframe array, since attach should never remove a degree of freedom.
PiperOrigin-RevId: 804917828
Change-Id: Icfacd207ced1c6aac600d514f8d9065ceff2d347
This ensures that Python bindings build also uses GLFW 3.4, similar to C/C++
MuJoCo.
The hashes are from https://pypi.org/project/glfw/2.9.0/#files.
PiperOrigin-RevId: 802536702
Change-Id: Ie9cfc17a5f9146fe6731681115f7aaa98fcb323e
The previous instructions use a pre-built binary from MuJoCo and do not cover
the use-case of building C/C++ and Python bindings from the same codebase.
PiperOrigin-RevId: 802060401
Change-Id: I6d0b9c7c2269ff596ac706b716ff6c95b42c5d99
This makes it possible to build open-source MuJoCo with Wayland support out of
the box.
Currently, it is necessary to run cmake with -DGLFW_USE_WAYLAND=ON and ensure
cmake can find the "ECM" package somehow (a dependency of the 3.3.6 version of
GLFW), for which there is no automated fetching setup. As this is no longer a
dependency of GLFW it seems to make more sense to update GLFW to make out of the
box builds on Wayland.
PiperOrigin-RevId: 800456607
Change-Id: Iffdf1d65319bfb134e580faceb63ac3bed7b9c84
This is the correct location, this enum is only used in `mjData`, not `mjModel`.
PiperOrigin-RevId: 798860951
Change-Id: I48b9a2afc831bd9a6966cc9586429fd03605bdd2
- Updated docs to clarify that only the lower triangle is touched
- The function was unnecessarily adding the upper triangle in the sparse case
- The test used an unnecessarily large model and stepping it leading to timeouts under ASAN
PiperOrigin-RevId: 798528736
Change-Id: I592cc17dfb62379bb0cd6b332a8eb7e8b0ef6355
This extends both the spec and the XML definition to allow specification of a material name on a mesh. This material acts as a fallback in the case that the referencing geom element does not specify a material of it's own.
PiperOrigin-RevId: 798232378
Change-Id: Iaf300c727732744ea1b613e64334ee505ac6e209
This change introduces an `nullable` flag to `ArrayType`, `PointerType`, and `FunctionParameterDecl`. The code generation process now parses function comments from `mujoco.h` to identify parameters marked as "Nullable" and sets this flag accordingly.
PiperOrigin-RevId: 797870883
Change-Id: Ic7cac5a7a9c14177fbf97b8655c5c4809d4ef683
This allows the MJCF SdfFileFormat plugin to load MJCF files that specify assetdir, meshdir, or texturedir attributes. This is specifically important for resolver implementations that fetch assets into a local cache.
PiperOrigin-RevId: 796509754
Change-Id: Ib2b0c9cf9d6a3351ceea49d90c882edf94d0b880
- Make island visualization off by default
- Give it the keyboard shortcut 'N'
- Use HSV island coloring
PiperOrigin-RevId: 796375514
Change-Id: I3cc8d6f8142412c771b2b8e57e82e70000727770
The path has already been stripped while parsing. This will enable prefixes that contain a `/` while attaching.
Also use `spec.meshdir` for asset paths in `spec.to_zip()`.
PiperOrigin-RevId: 794573523
Change-Id: Ic36bb641c3d72848399006cf718afd8542e91ed4
This check is never called due to the fallback to gjkIntersection, however it's needed for debugging when disabling the fallback.
PiperOrigin-RevId: 792623394
Change-Id: I7178d9afae697bd22984688e89fd1865d3c6a37f
#MIGRATION_3P_PY_WARP__DEFAULT
- 23f1a48c1acbc1aa1f353423ec5f9182560c565d Upgrade to libmathdx 0.2.2 (GH-809) by Zach Corse <zcorse@nvidia.com>
- a5b978abc2995c875498111d3cd4d307e621fe1f Fix GH-822 adj_tile_sum with shared tiles by Gilles Daviet <gdaviet@nvidia.com>
- 4cd0fda5978c550665b54235b8f19cf87b844989 Disable parallel test execution for MJWarp by Eric Shi <ershi@nvidia.com>
- 7408f297d03e7ed605f6d31fcfdaa288a9058ece Fix the OpenGL Renderer Box Colors (GH-810) by Christopher Crouzet <ccrouzet@nvidia.com>
- 1f3f589ba6732a3272f9e1fe8cc2a292864df4cb Fix rendering of meshes with different scales (GH-828) by Eric Heiden <eheiden@nvidia.com>
- a317a3d064f3518429e48858c5a99c7270934b5d Add a config file by Eric Shi <ershi@nvidia.com>
- 61848a5f12b1b1b1275a7a57ae734318e1cbb7d6 Resolve GH-832 "Fix bsr_from_triplets prune_numerical_zer... by Gilles Daviet <gdaviet@nvidia.com>
- f9fc3a1b9b3a69beee57766554ea10036ebe64b7 Extend the OpenGL example to show how to use ImGui (GH-833) by Tobias Widmer <twidmer@nvidia.com>
- bd2ca117a003736d95ec9938764a93eea10086fb Add flag to enable support for mac os - it avoids OpenGL ... by Tobias Widmer <twidmer@nvidia.com>
- 3c6388890e7a18c0164504b68b53ccb60859cbc0 Fix hashing of static expressions ([GH-830], partially re... by Eric Heiden <eheiden@nvidia.com>
- 74cac74e57f4b9d90f77cbe0b2b01f1f5ac84c67 fix box-box collision by Zhenggehan <gehan.zheng@vanderbilt.edu>
- 5d93b757c1febd64ff3e273e6c8225202391b5cc Remove a redundant assignment for query_b in box collision by Zhenggehan <gehan.zheng@vanderbilt.edu>
- 486422dc20d5665d9622115eb34fc5a7b9ef831d Add missing changelog entries for GH-822 and GH-809 by Zach Corse <zcorse@nvidia.com>
- 52be82e7bded3a496fbba04fb90e31b0c5512950 Add a missing changelog entry for GH-839 by Eric Shi <ershi@nvidia.com>
- b266b6a1497dd910cb23cbc4f0c03035005da8a1 GitLab jobs now use the R570 runners by Eric Shi <ershi@nvidia.com>
- 7368bf7d630c58ca9999f5284076cd5c0e9f2dc3 Fix potential issues in bitonic tile_sort ([GH-836]) by Kenny Vilella <kvilella@nvidia.com>
- 31621ff99b90927e608f56c5165d8b6332ec5b2f Fix for wp.tile_min() when tile thread block includes emp... by Zach Corse <zcorse@nvidia.com>
- 569b5a2b3672e0501958e6a3fbc6901df8800c49 Add more ImGui helper functions GH-844 by Tobias Widmer <twidmer@nvidia.com>
- a5a746a14254ae8ef89197c6d1988e3d33013683 Arbitrary size blocks and tile-based computations in warp... by Gilles Daviet <gdaviet@nvidia.com>
- 6ef9436700acb9f80cf7f3a6a34618a5e2da0a3d Fix `adj_div(scalar, vec/mat/quat)` by Christopher Crouzet <christopher@crouzet.pm>
- 0044654bb97a9de8c75629e52fa04a04fa632c21 Fix miscellaneous issues with adjoints by Christopher Crouzet <christopher@crouzet.pm>
- 42e374713557e3a1a85f23286ff1b02334eb15ea Fix the Possible Dead Loop in wp_balance_coloring (GH-816) by Anka Chen <ankac@nvidia.com>
- b39954ece68e67c124e1ff856fd189cc366debb8 Graph-capturable linear solvers (GH-843) by Gilles Daviet <gdaviet@nvidia.com>
- b2a9133d0125c2b973c8f0dbafaa31830e2af0ef Expose `array.ptr` in kernels (GH-819) by Gilles Daviet <gdaviet@nvidia.com>
- 3fa6c9b19c9f4774bd3f61f102a0867136563804 Fix wrong version passed to cuDeviceGetUuid by Eric Shi <ershi@nvidia.com>
- 195fd4e0ccb83ed7cfd74b716a6d33bfc9a35217 Add new publication: GeoWarp framework for geomechanics by Eric Shi <ershi@nvidia.com>
- 514e8b5a8f6a80a5a6aa230d9d0f23e3f2e9aa9a Add edit page link on right sidebar by Eric Shi <ershi@nvidia.com>
- 178e8430911b77b44bf1b0cd543f0304423c2ef2 Fix positioning of changelog entry of MR !1438 by Gilles Daviet <gdaviet@nvidia.com>
- 907cbd4b572a937b8b1c9a5fbd4bc21976304596 Use latest clang for builds in CI/CD by Eric Shi <ershi@nvidia.com>
- 649d206616735ec923d7a6bc1631bb03f4abcc6a Handle CUDA 12.8 + Thor combination by Eric Shi <ershi@nvidia.com>
- 8775c618ec9b1a8efd91f18b48ef6acd15caad92 Allow arr = wp.array(dtype=MyStruct...) in kernels GH-853 by Tobias Widmer <twidmer@nvidia.com>
- d3d0bdc67854c74045499253fa556369337925b8 Fix default PTX architecture selection to include only su... by Eric Shi <ershi@nvidia.com>
- 0e2b1f9cd28db7fe366647b39a09e2f43ebc236b Fixed the Bug of Missing Cloth-body Contact in VBD Integr... by Anka Chen <ankac@nvidia.com>
- 70479a95722e50ab6a32c477a238b801b0db5d4b warp.fem: leverage tiles to sum over quadrature points (G... by Gilles Daviet <gdaviet@nvidia.com>
- 2446e4c06a1d6d50ab825f6991d402f7959745c2 Add Warp stuctured array NumPy interop examples to docs (... by Zach Corse <zcorse@nvidia.com>
- bac82151b4cc46659f5278df9749cfd1d994ca61 Refactor some tests to reduce recompilation cost by Eric Shi <ershi@nvidia.com>
- c0cc239b5fe457c8aedca636e7d2e3f32f060a62 Fix debug mode compilation (GH-856) by Alain Denzler <adenzler@nvidia.com>
- 906495b742f583b5c5a524a23ffc7112b542286a Fix typo in wp.fem nodal field DG gradient by Gilles Daviet <gdaviet@nvidia.com>
- 476765315edf7268274f8862af540a7ddb68ce4f Reenable parallel execution of mjwarp GitLab job by Eric Shi <ershi@nvidia.com>
- 8f2bcfc503e82ad492dabc6cdbd9103495f0ff17 Disable Blackwell job by Eric Shi <ershi@nvidia.com>
- 531e822b1939be95edb11c56db310c0ac4701e17 Support initializing fixed-size arrays in kernels by Christopher Crouzet <christopher@crouzet.pm>
- 52f7f53f247302c666e73490e33228d0172e08b6 Support fixed-size arrays with structs as `dtype` by Christopher Crouzet <christopher@crouzet.pm>
- af038bddb408acd76fe009fb0b548ec0da68b74b Fix keyword arguments not being reported by Christopher Crouzet <christopher@crouzet.pm>
- 1bd4fac0637cd1eed3abc9af14699b5c9e05b35c JAX FFI graph capture using Warp (GH-848) by Lukasz Wawrzyniak <lwawrzyniak@nvidia.com>
- ff63d5073ae453d04aa8f78dcf9ed90bf7d70e5b Split `assign_copy` tests by Christopher Crouzet <christopher@crouzet.pm>
- 62daadda34f794bcb8c8ece4fe40c95224005b26 Add `wp.matrix_from_rows/cols()` to Python's API by Christopher Crouzet <christopher@crouzet.pm>
- a19818854f716629028186a24815629cb5513145 Add support for negative indexing by Christopher Crouzet <christopher@crouzet.pm>
- f440c5b15766943623870b8e887efe78bb9f9d62 Implement a slice object by Christopher Crouzet <christopher@crouzet.pm>
- e26f23207acf09449deeeea7db2168d2123804cf Add support for slicing vec/quat/transform by Christopher Crouzet <christopher@crouzet.pm>
- 28907cdfcae397d0e32b6f34d302d178677308e0 Add `wp.matrix_get/set_col()` to Python's API by Christopher Crouzet <christopher@crouzet.pm>
- 303c0ac8b680f788700e3974aba161042fef449b Add support for slicing matrices by Christopher Crouzet <christopher@crouzet.pm>
- bbc79c3dbcc9b37b00b9d61094c920e93515a2b1 Implement adjoints for slice indexing by Christopher Crouzet <christopher@crouzet.pm>
- c1e872f74f886592490771fe37e410f7b3905701 Update the hash with the config for `assign_copy` by Christopher Crouzet <christopher@crouzet.pm>
- b978cf94a87f66e90e418dda3c05d7c864b52849 Symmetrize operators by Christopher Crouzet <christopher@crouzet.pm>
- fd71d280d7a9d390bd7b322519ade06be62ac875 Fix a documented return type by Christopher Crouzet <christopher@crouzet.pm>
- 57fd611636f804cdaec3c8b69a0271f7717b770d Add a doc section for indexing/slicing by Christopher Crouzet <christopher@crouzet.pm>
- 6aa03089a96ff18792fbc2a3cbf50e205cea7783 Reduce the code size by Christopher Crouzet <christopher@crouzet.pm>
- 6c6c6e738972b25e69d171f6801b717ca921664b Fix wrong macros being used by Christopher Crouzet <christopher@crouzet.pm>
- 43be725152909f6434f9bf6aa0cdcf5e77bcd8c8 Add post-loop checks by Christopher Crouzet <christopher@crouzet.pm>
- 16a6a575ce6bee368b056a70c9d5bec8c6f1a409 Work around GH-637 in wp.fem integrands by Gilles Daviet <gdaviet@nvidia.com>
- 637bafffb90d495b222bf1c79d7173f60aa1871c Resolve function return types for wp.map() and wp.tile_ma... by Zach Corse <zcorse@nvidia.com>
- 18849b08e0809ccb357d22a6601139b9c3277cd2 Publish macos dev wheel to artifactory by Eric Shi <ershi@nvidia.com>
- de7481a377d0380e13208a7261996daba69fd9ba Tentative fix for bsr_mm asv regression from c5fdbc20 by Gilles Daviet <gdaviet@nvidia.com>
- eba4be3cf12ac3accdd0d48a265d0f8766ed8c99 Reenable Blackwell GitLab job by Eric Shi <ershi@nvidia.com>
- ee012fe62c8cb47b498ac430652c234368d41723 GH-870 Detect and warn about long file paths in Windows by Gilles Daviet <gdaviet@nvidia.com>
- fe5785431d4423a1faef64f2c810fa5ac18265d1 Reduce error messages when CUDA driver is not found by Eric Shi <ershi@nvidia.com>
- e5904c3d78e9e77174ab84527575a06c3c9d9265 Clarify Python vs. Warp scope execution of @wp.func funct... by Eric Shi <ershi@nvidia.com>
- b4ca2187d15f8b2c4220dc89b953670ab1b99913 Compile time improvements by Eric Shi <ershi@nvidia.com>
- 3a07ca72d155ff8666fc68a7c51a8690d8fef19e Add a documentation section about indexed arrays by Christopher Crouzet <christopher@crouzet.pm>
- 248fd07b67395323098231e64169e3d1c8216d89 Namespace the remaining warp-clang symbols by Christopher Crouzet <christopher@crouzet.pm>
- c6af3501853d30bd059f3ac1c9c9a9057f72247b Fix adding superfluous inactive nodes to tet function spa... by Gilles Daviet <gdaviet@nvidia.com>
- 62ac48861731a1800ad46548dc254d94362bdd18 Use usd-core==25.5.1 for Windows jobs to avoid failures by Eric Shi <ershi@nvidia.com>
- 5d1c2ba11cb6a11c4e89b4f47980f3063e3e63fc Add support for `IntEnum`, `IntFlag` inside Warp kernels ... by Eric Heiden <eheiden@nvidia.com>
- a4aba20a00e3d267d178a49b2ee145b82966f166 Update Warp version to 1.8.1 by Eric Shi <ershi@nvidia.com>
PiperOrigin-RevId: 792191632
Change-Id: I227d605677c925ca5e7fa64948ef884ef25fa5ad
According to `man dyld`, the default value for DYLD_FALLBACK_LIBRARY_PATH changed in late 2023. In newer binaries, if DYLD_FALLBACK_LIBRARY_PATH is not set, dyld will use /usr/local/lib and /usr/lib as fallback. If it is set, these locations will not be used as lookup paths unless explicitly added.
Fixes#2781
PiperOrigin-RevId: 791897707
Change-Id: I00d7e80bfbd5e5d7dbf2f601eaad4d9b0e1030f3
According to the deprecation warning, support for the old way of declaring the license will be removed from setuptools on 2026-Feb-18.
PiperOrigin-RevId: 791716539
Change-Id: Iaf9ec55f9425380b017bd7ea370cd481ed01aa8f
Also, when a mesh has both an octree and a bvh, render only the octree.
PiperOrigin-RevId: 790680831
Change-Id: Iaf3896933f6728af4db1eaa83ff5b06558ab0d19
This prevents the taxels from being occluded by the convex hull for meshes that do not provide face connectivity.
PiperOrigin-RevId: 790420616
Change-Id: I543fd7b52e4625d921b6b5b5b77b4720020df42a
Nullable arguments will be added to the `introspect` datastructures in a future change.
PiperOrigin-RevId: 789350522
Change-Id: I0bfd12fab5121f94b937264570f907593b63cf64
The SDF value of the closest point on the bounding box is added to the distance from the bounding box when the query point is outside of it.
PiperOrigin-RevId: 788377943
Change-Id: Id8e489a1d112918c484f5615223d557f2d14b822
"comment":"Build matrix for build.yml. 'tier' controls when an entry runs: 'core' runs on every pull_request and push; 'extended' runs only on push to main (full compiler sweep). See generate_matrix() in build_steps.sh.",
a module for procedural manipulation of MuJoCo models.
- [JavaScript bindings and WebAssembly support](/wasm/README.md) (inspired [stillonearth](https://github.com/stillonearth) and [zalo](https://github.com/zalo)'s community projects; [mjswan](https://github.com/ttktjmt/mjswan) extends these with real-time policy control, interactive force
application, and more).
- [C# bindings and Unity plug-in](https://mujoco.readthedocs.io/en/stable/unity.html)
#### Third-party bindings:
- **WebAssembly**: [mujoco_wasm](https://github.com/zalo/mujoco_wasm) by [@zalo](https://github.com/zalo) with contributions by
[@kevinzakka](https://github.com/kevinzakka), based on the [emscripten build](https://github.com/stillonearth/MuJoCo-WASM) by
[@stillonearth](https://github.com/stillonearth).
:arrow_right: [Click here](https://zalo.github.io/mujoco_wasm/) for a live demo of MuJoCo running in your browser.
- **MATLAB Simulink**: [Simulink Blockset for MuJoCo Simulator](https://github.com/mathworks-robotics/mujoco-simulink-blockset)
by [Manoj Velmurugan](https://github.com/vmanoj1996).
- Spaces are required around comparison operators.
- Spaces are required around comparison operators.
- Spaces are not allowed around operators in array subscripts `[]` or in
variable initialisation in `for` loops. For example, inspect the
`mju_transpose` implementation above.
- Spaces are not allowed around operators in array subscripts `[]` or in
variable initialisation in `for` loops. For example, inspect the
`mju_transpose` implementation above.
- Three blank lines are required between function implementations in source files.
- Two blank lines are required between function implementations in source
files.
#### Variable declarations
@@ -161,4 +162,7 @@ helping us to complete the migration are very welcome.
### [Python code](#python-code)
For Python code, run `pyink foo.py` to adhere to Google's [Python style guide](https://google.github.io/styleguide/pyguide.html). For sorting and cleaning imports, run `isort foo.py`. Both `pyink` and `isort` can be pip installed via `pip install pyink isort`.
For Python code, run `pyink foo.py` to adhere to Google's
[Python style guide](https://google.github.io/styleguide/pyguide.html). For
sorting and cleaning imports, run `isort foo.py`. Both `pyink` and `isort` can
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.