-1

On line 26 here we have this line:

self.sim = mujoco_py.MjSim(model, nsubsteps=n_substeps)

The mujoco_py MjSim file is here: https://github.com/openai/mujoco-py/blob/master/mujoco_py/mjsim.pyx

I don't understand how this cython is working. I read the cython tutorial but it wasnt making sense: https://cython.readthedocs.io/en/latest/src/quickstart/build.html

Specifically, in python we would have to do: mujoco_py.mjsim.MjSim() to instantiate the MjSim object. How exactly is cython loading things such that the MjSim object is callable immediately after mujoco_py?

Also, in line 155 here: https://github.com/openai/mujoco-py/blob/master/mujoco_py/mjrendercontext.pyx

There is a call mjv_updateScene(...). Where is this function defined?

user3180
  • 1,369
  • 1
  • 21
  • 38
  • Please read [ask] you are supposed to provide a [mcve] as the question must be understandable without the need to follow links. – ead Jul 29 '19 at 07:29
  • I don't understand how the cython code works so it is not possible for me to produce a minimal example – user3180 Jul 29 '19 at 07:43
  • 2
    "Specifically, in python we would have to do: mujoco_py.mjsim.MjSim() to instantiate the MjSim object" - you missed the `__init__.py` where it has `MjSim = cymj.MjSim ` –  Jul 29 '19 at 07:55
  • Possible duplicate of [What is \_\_init\_\_.py for?](https://stackoverflow.com/questions/448271/what-is-init-py-for) – DavidW Jul 29 '19 at 08:00
  • Specifically [this answer](https://stackoverflow.com/a/18979314/4657412) answers your question (which is what @JustinEzequiel has told you) – DavidW Jul 29 '19 at 08:01

1 Answers1

1

The answer to second bit of the question about mjv_updateScene that you edited in is: "they have the most awful build system I've seen that makes no sense whatsoever".

I believe (although it's difficult to trace all the way back) that cymj.pyx is the only .pyx file that's actually built. This file manually (textually) includes all the other .pyx files. This disobeys two conventions: first things should be cimported rather than textually included (the textual include is only really kept around as an artefact of an earlier way of doing things), and second that included files should be named ".pxi" to indicate that they're being included (then at least you know it isn't self-contained). Instead included files are named a mixture of .pxi, .pyx or .pxd with no regards to their role.

mjv_updateScene itself is defined in pxd/mujoco.pxd which is included indirectly from generated/wrappers.pxi.

I don't know anything about this library but the fact they thought this arrangement was a good idea gives me severe doubts about the quality of everything else. (However, there may be good reasons for it - we've all made dubious-looking bodge-jobs on occasion...)


The initial question about MjSim is answered in @JustinEzequiel's comment about __init__.py.

DavidW
  • 29,336
  • 6
  • 55
  • 86
  • Yep found update scene. So is the PXD file just 'exposing' the functions in mujoco.h C header file for python? – user3180 Jul 29 '19 at 11:41
  • Could you explain the general build flow. I'm just lost as to how I can add more functionality to this python wrapper mujoco_py – user3180 Jul 29 '19 at 11:43
  • I believe I can add my own python functions to any of the .pyx files. For example, "mjv_makeConnector" in mujoco.pxd is not used in any of the pyx files, so I believe I can add a new python function using it to mjrendercontext.pyx. And then the next time I import mujoco_py, I can use my new function? Or do i need to build it? – user3180 Jul 29 '19 at 11:45
  • Yes - that's what pxd files are (mainly) for - to "expose" C functions. In well-written code they're either statically imported with `cimport`, or if they have the same name as a pyx file they're then it's kind of the same as `from name cimport *` automatically. – DavidW Jul 29 '19 at 11:45
  • 1
    I honestly could not clearly explain the general build flow. It's a mess and I gave up trying to understand it all. However: if you edit "mjrendercontext.pyx" you will need to rebuild it to use your new function (this is definitely true!); to rebuild it you'd normally do something similar to "python setup.py build_ext", but with this code it's hard to be certain... – DavidW Jul 29 '19 at 11:49