Synchronized joint positions with a condition (equality?)

Discussion in 'Priority support' started by Dongmin Kim, Jan 27, 2020.

  1. Hello!

    I'm trying to convert OpenSim model to MuJoCo model.

    In OpenSim, a joint position (or angle) could be decided from another one.
    We also could associate an individual axis, to specific axis of joint which has multiple DoFs.
    These associations could be defined by constant value, polynomial equation, or spline.

    For example, I would like to set an angle of knee_angle_R_beta with some value,
    that calculated with a spline from knee_angle_R's angle.

    <body name="femur_R">
    <body name="tibia_R">
      <joint name="knee_angle_R" type="hinge"/>
    <body name="patella_R">
      <joint name="knee_angle_R_beta" type="hinge"/>
    Question 3 in another unanswered post describes this problem too.

    What I've tried
    I defined the following joints in the MuJoCo model.
    main_joint = knee_angle_R, hinge, axis 1 0 0
    dependent_joint_1 = knee_angle_R, hinge, axis 0 1 0
    dependent_joint_2 = knee_angle_R, hinge, axis 0 0 1
    dependent_joint_3 = knee_angle_R, slide, axis 1 0 0
    dependent_joint_4 = knee_angle_R, slide, axis 0 1 0
    dependent_joint_5 = knee_angle_R, slide, axis 0 0 1
    dependent_joint_6 = knee_angle_R_beta, hinge, axis 1 0 0
    dependent_joint_7 = knee_angle_R_beta, slide, axis 1 0 0
    First, I got the position value (d-> qpos) of main_joint,
    then I calculate a function(like spline) forr each joint.
    Finally I put it back to pos (d-> qpos) of dependent_joint_1 ~ dependent_joint_7.

    I chose this approach because implementing spline with a polycoef in joint equality constraint was difficult.

    After that, I redefined the forward and step as follows.
    custom_step (m, d) {
      change_position (m, d);
      mj forward (m, d);
      mj_step (m, d);
      // Just double check
      change_position (m, d);
      mj forward (m, d);


    1) Is this approach proper? Could I implement it with MuJoCo's native callback and constraint solver?

    2) How could I set the proper value of qvel and qacc for each joints?
    If I force it every joints to 0, of course it won't move.
    For now I just set the qvel and qacc to 0, only for dependent joints.

    3) Is it good to do like following tricks?
    * Set m->jnt_limited to true for dependent joints,
    * Set m->jnt_range to dependent_joint +- 0.001 for every step,
    * Set solimp with width = 0.0001, midpoint = 0.0001, and power = 6 for dependent_joints.

    4) An example musculoskeletal model in MuJoCo website's promotion video using a patella bone with attached muscle. How could I design my model like that? (red circles in attached screenshot)

    5) Not much related to this question, but in future, I want to put this model
    in the soft sphere, like uterus. Is it possible to implement it by using 'cloth' composite type?


    Attached Files:

  2. I tried to implement using joint equality, but it didn't work well. (without modifying joint value)

    I'm updating every polycoef as "[desired value] 0 0 0 0" before execute mj_step.
    (0:00~ with actuation, 0:09~ without actuation)

    If everything is good, patella should be located on the air for every step,
    but it swallowed into the femur&tibia.

    I think the reason was that currently our model has a poorly calculated muscle parameters,
    therefore all of constraints could not be satisfied in the same time.

    (Opensim joint has a range of -99999~99999 for dependent joints, so
    we couldn't use a MuJoCo's muscle length auto compiler)
    (0:00~ stable case, 0:13~ unstable case)

    Red sylinder is a muscle wrap object for 'recfem_R' muscle.
    This muscle was attached to patella(body).

    Since the position of patella was instable, recfem_R muscle tend to pass through the wrap object.

    I tried to using combination of Integrator(Euler, RK4), Collision(Dynamic, All), Cone(Elliptic, Pyramidal), Jacobian(Auto, Dense, Sparse), Solver(PGS, CG, Newton) or changing sol ref to (0.1 1), (9999 9999), etc.

    In this reason, I hope to find how to make soft constraint more harder, or make a joint value callback.

  3. I solved the problem by setting solimp on <equality> node with changing polycoef for every step.

    Overriding solimp by <option> node or simulator UI didn't applied to the other constraints, I didn't know about that.
  4. Emo Todorov

    Emo Todorov Administrator Staff Member

    Sorry about the delay. Yes, equality constraints are the way to do this. The solimp overrite in Option is for contacts only.

    Changing joint angles and velocities to impose constraints at each step is not a good idea in general, because the equations of motion assume that only the simulator can make such changes.

    Looking at your video, if you want one object to slide over another object, you may be able to achieve the desired effect by creating a planar joint between the objects (instead of defining free objects and relying on contacts). Of course this only works for simple sliding motions that can be captured by joints.
  5. Thank you for your advice!