Mujoco - Change MjModel instance during runtime in Python

65 Views Asked by At

I have an XML file for a custom robot I made. I am trying to modify the size of links of the robot during runtime. I want to make randomized variations of certain parts of the robot just before each simulation loop.

Area of interest in the XML File:

...
<body name="arm" pos="0 0 .01">
    <joint axis="0 0 1" limited="false" name="joint0" pos="0 0 0" type="hinge"/>
    <geom fromto="0 0 0 0.5 0 0" name="link0" rgba="0.0 0.9 0 1" size=".01" mass="4.0" type="cylinder"/>
</body>
...

Area of interest in my Python code:

m = mujoco.MjModel.from_xml_path('assets.xml')

m.geom('link0').size[1] = act_size / 2.0
m.geom('link0').pos[0] = act_size / 2.0

What I want to change is the values fromto and size params in the <geom> that tag are compiled into in the MjModel object. I've tried changing the size and pos attributes linked to the geom tag However it doesn't seem to work as intended. Are there any other attributes that require changes? Would appreciate any leads. Thanks.

2

There are 2 best solutions below

0
SKrish On BEST ANSWER

A simple answer I found that I would need to also modify the values of the <body> attribute. I did not know this was required - but Mujoco XML body tags have some compiled inverse poses stored. Adding the below line to my code fixed the answer.

m = mujoco.MjModel.from_xml_path('assets.xml')

m.geom('link0').size[1] = act_size / 2.0
m.geom('link0').pos[0] = act_size / 2.0
m.body('arm').ipos[0] = act_size / 2.0

0
balderman On

What I want to change is the values fromto and size params in the that tag are compiled into in the MjModel object

So before you pass the XML to MjModel, do the manipulation below

import random
import xml.etree.ElementTree as ET

xml = '''<body name="arm" pos="0 0 .01">
    <joint axis="0 0 1" limited="false" name="joint0" pos="0 0 0" type="hinge"/>
    <geom fromto="0 0 0 0.5 0 0" name="link0" rgba="0.0 0.9 0 1" size=".01" mass="4.0" type="cylinder"/>
</body>
'''


def get_random_value():
    # modify this code based on your needs
    return str(random.randrange(1, 145))


root = ET.fromstring(xml)
geo = root.find('.//geom')
for prop in ['fromto', 'size']:
    geo.attrib[prop] = get_random_value()
ET.dump(root)

output

<body name="arm" pos="0 0 .01">
    <joint axis="0 0 1" limited="false" name="joint0" pos="0 0 0" type="hinge" />
    <geom fromto="95" name="link0" rgba="0.0 0.9 0 1" size="70" mass="4.0" type="cylinder" />
</body>