Closed johnny-wang16 closed 3 days ago
I think we've a faucet in robocasa. However, I'm not too sure how that was created; @Abhiram824 would you know if we've examples for faucets?
Re:
DoorObject as it seems to also contain a revolute joint. but it sets it to None which makes the object immovable for some reason (is this intended!?).
Right - if you remove the joint, then it becomes a fixed joint.
I think we've a faucet in robocasa. However, I'm not too sure how that was created; @Abhiram824 would you know if we've examples for faucets?
Re:
DoorObject as it seems to also contain a revolute joint. but it sets it to None which makes the object immovable for some reason (is this intended!?).
Right - if you remove the joint, then it becomes a fixed joint.
Yep! We do have faucets. Perhaps the xml file and the corresponding code will be of help.
Hi all, thanks for your help! I figured out my problem actually.
The reason why it's detaching like that is because i set the scale of meshes to be 0.1 but did not change the position of the joint. When examining the scaled xml in mujoco, i saw that the joint is actually in mid air. After scaling the joint position, the top part stays attached to the bottom part. Ideally, I would like to set the scale of the object programmatically but seems like the only way now is to modify the xml files?
Regrading the correct way of initializing custom xml objects, i think this is the correct way:
class FaucetObject(MujocoXMLObject):
"""
Bread loaf object (used in PickPlace)
"""
def __init__(self, name):
super().__init__(
xml_path_completion("objects/faucet.xml"),
name=name,
joints=[dict(type="free", damping="0.0005")],
obj_type="all",
duplicate_collision_geoms=True,
)
After trial and errors, my understanding of this joint
parameter is that, it is not referring to any joints that the object already contains (the ones already specified in the xml). Rather, it is determining what the object as a whole should behave. Setting this parameter seemed to add a new joint to the top level of the object tree and based on the joint type, the object would behave differently. In my case, I'd like it to be freely movable in 3D space so setting it to "free" seemed to work for me. Is my understanding correct?
Another question, I was trying the demo_device_control.py
with my faucet xml but somehow the gripper stops before it actually touches it. I was suspecting its a mesh problem but the problem persist after I cleaned my mesh with open3D. The following is a short clip illustrating this problem. Any ideas how to solve it ?
Short clip
Great to see you've fixed it!
Yes, right now it's modifying the xml files, though you can modify xml files programmatically. The current class definition assumes the FaucetObject has only a fixed scale specified by the xml file --- did you want to scale it in a one-off way, or did you want to pass in a scale parameter?
Joint parameter: I think one way to check this is to print out the xml see what happens:
print(env.sim.model.get_xml())
.
Re: weird physics: maybe visualize the collision mesh? Perhaps the collision mesh differs from the visual mesh?
Great to see you've fixed it!
Yes, right now it's modifying the xml files, though you can modify xml files programmatically. The current class definition assumes the FaucetObject has only a fixed scale specified by the xml file --- did you want to scale it in a one-off way, or did you want to pass in a scale parameter?
Joint parameter: I think one way to check this is to print out the xml see what happens:
print(env.sim.model.get_xml())
.Re: weird physics: maybe visualize the collision mesh? Perhaps the collision mesh differs from the visual mesh?
You can visualize the collision mesh and visual meshes as needed by with the following script in the Robocasa codebase: https://github.com/robocasa/robocasa/blob/main/robocasa/scripts/browse_mjcf_model.py.
Thanks @kevin-thankyou-lin and @Abhiram824 ! Scaling: I'd like to pass in a scale parameter. Is there a way to programmatically do that? The reason is because i'd like to do it on all the shapenet mobility objects and won't be able to adjust each by hand.
Joint parameter:
I printedprint(env.sim.model.get_xml()
and found the that my guess is correct. Here's the resulting xml of the faucet part:
<body name="faucet_main">
<inertial pos="0 0 0" mass="1" diaginertia="1 1 1"/>
<joint name="faucet_joint0" type="free" limited="false" actuatorfrclimited="false" damping="0.0005"/>
<geom name="faucet_link_1_collision" type="mesh" rgba="0.5 0 0 1" mesh="faucet_link_1"/>
<geom name="faucet_link_1_collision_visual" type="mesh" contype="0" conaffinity="0" group="1" mass="0" mesh="faucet_link_1"/>
<site name="faucet_default_site" pos="0 0 0" size="0.002" rgba="1 0 0 0"/>
<body name="faucet_link_0">
<inertial pos="0 0 0" mass="1" diaginertia="1 1 1"/>
<joint name="faucet_joint_hinge" pos="0.0300886 -0.00055465 0" axis="0 0 -1" range="-1.5708 1.5708" actuatorfrcrange="-100 100"/>
<geom name="faucet_link_0_collision" type="mesh" rgba="0.5 0 0 1" mesh="faucet_link_0"/>
<geom name="faucet_link_0_collision_visual" type="mesh" contype="0" conaffinity="0" group="1" mass="0" mesh="faucet_link_0"/>
</body>
</body>
So it actually adds a new free "joint" to the top level of the faucet to make the object move freely in 3D. In my opinion, this way of initializing the class for custom objects is confusing.
Weird physics: I also visualize the collision mesh by running that script but not sure how to visualize the visual mesh. When i didn't enable the flag for visualizing collision, I didn't see anything (maybe because my xml doesnt contain a visual mesh!?). But the visualization for collision seems fine to me. Video of visualization here.
Scaling: we don't have that yet; I'd do it by adding that as an attribute to the relevant object class, the super class + other logic in the base class. You'll need add some xml parsing logic:
class FaucetObject(MujocoXMLObject):
"""
Bread loaf object (used in PickPlace)
"""
def __init__(self, name: str, scale: Optional[float] = None): # new arg
super().__init__(
xml_path_completion("objects/faucet.xml"),
name=name,
scale=scale, # new arg
joints=[dict(type="free", damping="0.0005")],
obj_type="all",
duplicate_collision_geoms=True,
)
feel free to give it a shot and make a PR!
Joint parameter: gotcha, what would you suggest for making it less confusing?
Physics: Looks like the vis and collision meshes are the same --- the other thing to try is to convex decompose the meshes. The physics engine doesn't work too well if the meshes aren't convex. Kevin Zakka has a nice tool for this: https://github.com/kevinzakka/obj2mjcf
Also, did you mean the PartNet-Mobility objects?
Scaling: Got it. It's not too urgent for me so ill try it when i need to .
Joint parameter: Maybe it's because im not familiar with MuJoCo so its confusing to me. But i feel like in the object part of documentation, maybe add more description after: "The optional joints argument can also specify a custom set of joints to apply to the given object (defaults to “default”, which is a single free joint)." Saying something along the lines of: "This joint argument determines the DOF of the object as a whole and does not interfere with the joints already in the object" would be nice.
Physics: got it. thanks for the info. I tried with other objects in partnet mobility and seems like this problem is specific to this type of faucet. I'll ignore it for now.
Thanks for answering all my questions and the wonderful project you guys have built!
Yes. I mean PartNet-Mobility Dataset.
Gotcha, you're very welcome! Thanks for your kind words; I'll pass along to the dev team :) Feel free to ask if you've more questions. I'll update the docs - thanks!
Faucet XML file:
I'd like to load a custom xml file (a faucet). I tested it in mujoco's interactive viewer (activated by the command
python -m mujoco.viewer
) to make sure the joint is revolute. I followed the tutorial and load it to one of the demo scenes here (code below). To achieve that, I mainly modified the xml and added a python class in thexml_objects.py
file:However, I am not sure how to set the joints argument correctly and couldn't find documentations or related issues. I looked at the DoorObject as it seems to also contain a revolute joint. but it sets it to None which makes the object immovable for some reason (is this intended!?). The joint of the faucet should be a revolute joint as indicated in the xml file. Could you let me know the correct way of setting the joints parameter such that it behaves like a revolute joint in robosuite? A weird behavior is observed by executing my current code where, after the gripper grab the faucet a couple times, the top part is detached from the bottom part (image below). In addition, it seems like the faucet would suspended in midair or stuck in table if i don't set joint type to "free" and set the position too high or too low. How to resolve that? I provided my testing code and the meshes of my object below:
Testing code:
meshes of the object to be added in to
objects/meshes
folder: link_0 link_1 .Weird behavior: