Contact locations on object

Discussion in 'Simulation' started by Alexander, Jul 4, 2017.

  1. Hi,

    I'm currently using a hand model (Modular Prosthetic Limb) that is interacting with a single object. I'm aware that the position of the contact point between the 2 objects can be obtained using d->contact and the position of the particular part of the hand that touched the object can be found with d->xpos, however is it possible to get the location of where the object touched the hand, in terms of a specific location on the hand itself. As I would like to note all the locations on the hand (skin) where the object came into contact with the hand.

    I'm thinking that given the xpos value of the particular part in question, and the contact point, you could find the difference between the two values (d->contact - d->xpos). Then when mapping all the points, given the location of that part in global coordinates (in initial position), you could say that the contact point is the initial position of the part + the difference calculated. However would this work, as each part of the hand is not symmetrical?

    Or can you suggest a better method?

    Also is there a function available to plot 3d points in the simulation?
    Last edited: Jul 4, 2017
  2. Emo Todorov

    Emo Todorov Administrator Staff Member

    The procedure you described is the correct way to compute the contact point coordinates in the local frame of each body. In addition to subtraction mjData.xpos, you should also apply the frame rotation (given by mjData.xmat) to obtain local coordinates. The different parts of the hand are indeed not symmetric, but that does not affect the global-to-local transformation.

    As for adding elements to the 3D plot, you have to add abstract geoms at the end of the geom list in mjvScene, before rendering. See mjvive.cpp for an example.
    Kyokushin likes this.
  3. Thanks for the swift reply.

    In terms of performing the global to local transformation using mjData.xmat, is this how it would work?

    Say a body of the hand with id "i" is in contact with the object. Then for the local coordinates in the x-axis:

    double x_local = 0;
    for(int j = 0; j < 3; j++) {
    x_local+= (d->contact.pos[j] - d->xpos[i*3 + j]) * d->xmat[i*9+j]

    Edit: After some testing and plotting the data, it appears to work.
    Last edited: Jul 4, 2017
  4. Emo Todorov

    Emo Todorov Administrator Staff Member

    I am not quite sure about your indices... Anyway, I would do it using the built-in BLAS-like functions. Note that xmat is a 3x3 matrix which rotates from local to global coordinates. So you need the transpose to go the other way.

    int bodyid, contactid;
    mjtNum localpos[3], temp[3];

    // set bodyid and contactid to what you need

    mju_sub3(temp, d->contact[contactid].pos, d->xpos+3*bodyid);
    mju_rotVecMatT(localpos, temp, d->xmat+9*bodyid);
    Aykut Onol and Kyokushin like this.
  5. Is it possible for MuJoCo to detect multiple (e.g. 2) contact points at the same body in a single frame. For example, if some type of object shaped like a 'V', touched a part of the hand such that the 2 ends hit a specific body of the hand at the same frame, would this be registered such that d->contact[0] and d->contact[1] would correspond to each part of the V-shaped object touching that particular body, such that both contact positions can be read?
  6. Emo Todorov

    Emo Todorov Administrator Staff Member

    Yes, you can have multiple contacts for the same pair of geoms. Note that contacts are made with geoms, while bodies are just abstract frames to which geoms are attached (so one body can have many geoms attached to it).

    MuJoCo does collisions with convex shapes. So the "V" shape would have to be decomposed by the user into a union of convex shapes, all attached to the same body.

    With meshes and some other geom pair types, MuJoCo uses the MPR algorithm as implemented in libccd, which returns at most one contact point per geom pair. But in other cases it uses native collision functions which can return multiple contacts; box-box in particular can return up to 8.
  7. Hello,
    I would like to achieve the same thing : " note all the locations on the hand (skin) where the object came into contact with the hand."
    Is it possible to mark contact locations on the skin of the composite object at runtime?
    Thank you in advance!