openai / mujoco-py

MuJoCo is a physics engine for detailed, efficient rigid body simulations with contacts. mujoco-py allows using MuJoCo from Python 3.
Other
2.81k stars 810 forks source link

How to get contact point position #725

Open Ddeconelee opened 2 years ago

Ddeconelee commented 2 years ago

I saw position in mjContact, but I don't know how to get it by mujocopy. I tried sim.data. active contacts_ efc_pos function, but there are many values. Can someone help me solve this problem?Thanks!

print(sim.data.active_contacts_efc_pos)# I got these values from this code. [-0.00131081 0.00099923 0.00099923 0.00099923 0.00099923 0.00099923 0.00099923 0.00099923 0.00099923 0.00099923 0.00099923 0.00099923 0.00099923 0.00099923 0.00099923 0.00099923 0.00099923 0.00099923 0.00099923 0.00099923 0.00099923 0.00099923 0.00099923 0.00099923 0.00099923 0.00056471 0.00056471 0.00056471 0.00056471 0.00056471 0.00056471 0.00099861 0.00099861 0.00099861 0.00099861 0.00099861 0.00099861 0.00099861 0.00099861 0.00099861 0.00099861 0.00099861 0.00099861 0.00099861 0.00099861 0.00099861 0.00099861 0.00099861 0.00099861 0.00099861 0.00099861 0.00099861 0.00099861 0.00099861 0.00099861 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099902 0.00099383 0.00099383 0.00099383 0.00099383 0.00099383 0.00099383 0.00099518 0.00099518 0.00099518 0.00099518 0.00099518 0.00099518 0.0009989 0.0009989 0.0009989 0.0009989 0.0009989 0.0009989 ]

Manchewable commented 2 years ago

You can get the number of active contacts with sim.data.ncon and an array of active contacts with sim.data.contact.

Each element in sim.data.contact is an mjContact object, which you can get the contact point position.

For example, if you want to know the contact position of geom1 and geom2, then you can do this by iterating sim.data.contact:

for i in range(sim.data.ncon):
    con = sim.data.contact[i]
    if (con.geom1 == geom1_id and con.geom2 == geom2_id) or (con.geom2 == geom1_id and con.geom1 == geom2_id):
        contact_pos = con.pos
        break

print(contact_pos)

You can read more about mjContact here.

tomoya-yamanokuchi commented 2 years ago

@Manchewable

Thanks for your great idea.

Based on your idea, I tried the above code.

However, I have the problem that the two ids of the con.geom1 and geom1_id are not consistent, while these ids of course should be the same.

So, could you tell me how these ids (id comes from sim.data.contact, and id comes from geom1_id which can be obtained from the sim.model.geom_name2id("xxx")) are internally determined in mujoco?

Manchewable commented 2 years ago

However, I have the problem that the two ids of the con.geom1 and geom1_id are not consistent, while these ids of course should be the same.

A simple get around for this is to also check for whether con.geom1 matches geom2_id and con.geom2 matches geom1_id, so you can change the if statement to this if (con.geom1 == geom1_id and con.geom2 == geom2_id) or (con.geom2 == geom1_id and con.geom1 == geom2_id):

So, could you tell me how these ids (id comes from sim.data.contact, and id comes from geom1_id which can be obtained from the sim.model.geom_name2id("xxx")) are internally determined in mujoco?

Sorry, I'm not exactly sure how the order of geom1 and geom2 in sim.data.contact are determined, it's best to check for both as mentioned above.

As for how the ids are assigned for each geom, I assume when it reads in your MJCF file, it'll assign the ids to the geom in a top down fashion. But it's best to get the id of your geom via sim.model.geom_name2id("xxx").

I've updated my post above for getting around this issue.

tomoya-yamanokuchi commented 2 years ago

@Manchewable

I greatly appreciate your reply.

Based on your advice, I confirmed the two ids of con.geom1 and con.geom2, and compared them with the ids comes from sim.model.geom_name2id().

Then the results are follows:

con.geom1 -> 27 con.geom2 -> 108

sim.model.geom_name2id("xxx") -> 28 sim.model.geom_name2id("yyy") -> 108

Therefor, I can find that the id 108 is consistent between con.geom2 and sim.model.geom_name2id("yyy"), while the con.geom1 and sim.model.geom_name2id("xxx") are inconsistent.

So, I'm still confusing this inconsistent of id 27 and id 28.

Best regards.

tomoya-yamanokuchi commented 2 years ago

@Manchewable

I apologize for my mistake. I just make a mistake with my wrong reference for the geometry. (I created my geometry with a wrong name)

So, I was able to solve my problem with the aid of your advice.

Thank you so much for your help!