Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failed to load model after setting user actuator callback #1014

Open
yushijinhun opened this issue Aug 9, 2023 · 4 comments
Open

Failed to load model after setting user actuator callback #1014

yushijinhun opened this issue Aug 9, 2023 · 4 comments
Labels
bug Something isn't working enhancement New feature or request

Comments

@yushijinhun
Copy link

Description

Loading a model with user actuators (using mujoco.MjModel.from_xml_path) would fail if a user actuator callback is set (using mujoco.set_mjcb_act_dyn, set_mjcb_act_gain, or set_mjcb_act_bias).

To reproduce the problem:

import mujoco

def my_act_dyn(model, data, id):
	return 0.0

mujoco.set_mjcb_act_dyn(my_act_dyn)

model = mujoco.MjModel.from_xml_path("user_act.xml")

user_act.xml:

<mujoco>
	<worldbody>
		<body>
			<inertial pos="0 0 0" mass="1.0" diaginertia="1.0 1.0 1.0" />
			<joint name="my_joint" />
		</body>
	</worldbody>
	<actuator>
		<general dyntype="user" joint="my_joint" />
	</actuator>
</mujoco>

Output:

Traceback (most recent call last):
  File "/home/yushijinhun/robodev/mujoco_act_bug/user_act.py", line 8, in <module>
    model = mujoco.MjModel.from_xml_path("user_act.xml")
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: Error: engine error: Python exception raised

I tried to debug this problem using GDB and here is the backtrace:

#0  mujoco::python::(anonymous namespace)::EscapeWithPythonException () at /tmp/pip-req-build-gqttshg5/mujoco/callbacks.cc:36
#1  0x00007ffff6fa0210 in mujoco::python::(anonymous namespace)::MjWrapperLookup<mjData_> (ptr=0x12d2e00) at /tmp/pip-req-build-gqttshg5/mujoco/callbacks.cc:117
#2  0x00007ffff6fa1195 in mujoco::python::(anonymous namespace)::MjWrapperLookup<mjData_> (ptr=0x12d2e00) at /tmp/pip-req-build-gqttshg5/mujoco/callbacks.cc:122
#3  0x00007ffff6f99ae3 in mujoco::python::(anonymous namespace)::PyMjcbActDyn (m=0x12c95c0, d=0x12d2e00, id=0) at /tmp/pip-req-build-gqttshg5/mujoco/callbacks.cc:208
#4  0x00007ffff6b14e64 in mj_fwdActuation (m=0x12c95c0, d=0x12d2e00) at /home/yushijinhun/repos/mujoco/src/engine/engine_forward.c:257
#5  0x00007ffff6b17569 in mj_forwardSkip (m=0x12c95c0, d=0x12d2e00, skipstage=0, skipsensor=0) at /home/yushijinhun/repos/mujoco/src/engine/engine_forward.c:851
#6  0x00007ffff6b1763f in mj_forward (m=0x12c95c0, d=0x12d2e00) at /home/yushijinhun/repos/mujoco/src/engine/engine_forward.c:865
#7  0x00007ffff6b176cb in mj_step (m=0x12c95c0, d=0x12d2e00) at /home/yushijinhun/repos/mujoco/src/engine/engine_forward.c:877
#8  0x00007ffff6d557f5 in mjCModel::TryCompile (this=0x12c4110, m=@0x7fffffffb128: 0x12c95c0, d=@0x7fffffffb130: 0x12d2e00, vfs_provider=0) at /home/yushijinhun/repos/mujoco/src/user/user_model.cc:2854
#9  0x00007ffff6d51dad in mjCModel::Compile (this=0x12c4110, vfs_provider=0) at /home/yushijinhun/repos/mujoco/src/user/user_model.cc:2442
#10 0x00007ffff6d9cd86 in _loadXML (filename=0x7fffffffd1a0 "user_act.xml", vfs_provider=0, error=0x7fffffffba30 "", error_sz=1024) at /home/yushijinhun/repos/mujoco/src/xml/xml_api.cc:86
#11 0x00007ffff6d9cf2a in mj_loadXML (filename=0x7fffffffd1a0 "user_act.xml", vfs=0x0, error=0x7fffffffba30 "", error_sz=1024) at /home/yushijinhun/repos/mujoco/src/xml/xml_api.cc:116

It seems that MuJoCo creates a temporary mjData struct and does simulation during model compilation. The simulation calls mjcb_act_dyn to calculate activation dynamics. Because the callback function is in Python, the mjData has to be wrapped before passing to Python code. However, that temporary mjData struct has never been passed to MjWrapper's constructor to create such wrapper. Therefore, the lookup of the corresponding wrapper object of the mjData struct would fail.

Environment

  • Operating system: Ubuntu 23.10 (devel) / Linux 6.3.0
  • MuJoCo version: 2.3.8 (built from source, commit: 93012bf)
  • Python binding: mujoco (Python 3.11.4)
@yushijinhun yushijinhun added the bug Something isn't working label Aug 9, 2023
@yuvaltassa
Copy link
Collaborator

The callbacks are tested in bindings_test.py. Can you please inspect how they are used in the tests and see if that resolves your problem?

@yushijinhun
Copy link
Author

@yuvaltassa Thanks for highlighting this. I've noticed that it's essential to unset all callbacks before invoking mujoco.MjModel.from_xml_string or from_xml_path, as demonstrated in bindings_test.py.

Is this the intended behavior? Some documentation on this aspect might be beneficial for clarity.

@saran-t
Copy link
Member

saran-t commented Aug 25, 2023

Your analysis is correct. @yuvaltassa maybe we should just disable all callbacks during TryCompile?

@yuvaltassa
Copy link
Collaborator

Yup sounds sensible. It's hard to imagine a callback that would be required for TryCompile (with the exception of truly obscene things that shouldn't be done anyway)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants