Mujoco - 在Python中运行时更改MjModel实例

0 投票
2 回答
62 浏览
提问于 2025-04-14 18:18

我有一个XML文件,是我自己做的一个机器人用的。我想在运行时修改机器人的链接大小。我希望在每次模拟循环之前,随机改变机器人的某些部分。

我在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>
...

我在Python代码中关注的部分:

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

我想要改变的是<geom>标签中的fromtosize参数的值,这些参数会被编译到MjModel对象里。我尝试过修改与geom标签相关的大小和位置属性,但似乎没有达到预期效果。还有其他需要修改的属性吗?如果有任何线索,我会很感激。谢谢。

2 个回答

0

我想要改变的是在MjModel对象中,from、to和size这几个参数的值,它们是从标签中提取出来的。

所以在你把XML传给MjModel之前,先做下面的操作。

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)

输出结果

<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>
0

我找到一个简单的答案,发现我还需要修改一下<body>属性的值。我之前不知道这是必须的——但是Mujoco的XML文件中的body标签里存储了一些编译好的反向姿态。把下面这行代码加到我的代码里就解决了这个问题。

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

撰写回答