Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

ArticulationBody.SetJointPosition doesn't update transform immediately. Workaround?

Discussion in 'Physics' started by i-make-robots, Aug 11, 2022.

  1. i-make-robots

    i-make-robots

    Joined:
    Aug 27, 2017
    Posts:
    17
    upload_2022-8-11_11-19-45.png
    upload_2022-8-11_11-19-8.png
    upload_2022-8-11_11-20-45.png
    Code (CSharp):
    1.  
    2.    public override void OnEpisodeBegin() {
    3.       SetRandomReachableTarget();
    4.       SetInitialPose();
    5.    }
    6.  
    7.     private void SetRandomReachableTarget() {
    8.         SetRandomPose();
    9.         SetTargetToPose();
    10.     }
    11.  
    12.     private void SetRandomPose() {
    13.         for (int i = 0; i < targets.Count; ++i) {
    14.             // TODO check angle limits?
    15.             targets[i] = Random.Range(-1f, 1f) * 180.0f;
    16.         }
    17.         Debug.Log("targets=" + string.Join(",", targets));
    18.         bodyRoot.SetJointPositions(targets);  // must be in degrees, unlike SetDriveTargets, not mentioned in any version of the documentation. >.<
    19.     }
    20.  
    21.     private void SetTargetToPose() {
    22.         Transform eet = endEffector.transform;
    23.         target.transform.SetPositionAndRotation(eet.position,eet.rotation);
    24.         Debug.Log("p="+eet.position + "\tr="+eet.rotation);
    25.     }
    I expected that after I `SetJointPositions` the kinematic chain would move and the endEffector transform would be somewhere new. Instead the endEffector stays right where it is - at the initial position - and I get "hit" events that shouldn't happen.
    upload_2022-8-11_11-21-28.png

    Is there a way to force an update on the kinematic chain?
     
  2. Augustinas-Simkus

    Augustinas-Simkus

    Unity Technologies

    Joined:
    Mar 9, 2020
    Posts:
    84
    Not really, changes like these are flushed to the Transform components only on physics simulation steps. E.g. setting the position property on a Rigidbody will have the same problem, it will not write to the Transform before a simulation step.
    I'm about to introduce a method to flush these changes manually without any hacks but that will be only for the latest alpha releases :/
     
  3. i-make-robots

    i-make-robots

    Joined:
    Aug 27, 2017
    Posts:
    17
    Are you the maintainer? Awesome! Can you please update the docs to mention which ArticulationBody convenience methods are in radians and which are in degrees? That makes me crazy.
     
  4. i-make-robots

    i-make-robots

    Joined:
    Aug 27, 2017
    Posts:
    17
    I'm going to be in the Seattle Robotic's Society "Robothon Exhibition" August 27, 2022. I'd like to present my work in ML with robots. Is there any chance you can help me get this to work before then?
     
  5. Augustinas-Simkus

    Augustinas-Simkus

    Unity Technologies

    Joined:
    Mar 9, 2020
    Posts:
    84
    Yep, will do. I thought we added those everywhere. But turns out we forgot the setters that take in a list. For now you can take a look at the properties for single joint, those have units of measurement listed. E.g. ArticulationBody.jointPosition.

    I can mostly help with physics, not really an expert in robotics :D But feel free to ask if you encounter any technical problems.

    Regarding this specific issue, the most obvious solution would be to perform a time-step :/ You could extract the position of links by using the worldCenterOfMass property, but not rotation.
     
  6. i-make-robots

    i-make-robots

    Joined:
    Aug 27, 2017
    Posts:
    17
    Getters for lists also do not mention units of measurement. I submitted "improve this page" requests on the docs. Do they fall in a hole forever?

    How do i perform a one frame time step without screwing up the rest of the simulation or the ML stuff?
     
  7. Augustinas-Simkus

    Augustinas-Simkus

    Unity Technologies

    Joined:
    Mar 9, 2020
    Posts:
    84
    No, but it will definitely be faster if I just do it myself next week.


    I'm not a fan of the fake step either. If you don't care about the actual response of the Articulation tree to the world (which you're obviously not getting without simulating either way), you could probably just calculate the poses. Given the root pose, all the anchors, and joint positions in reduced space.

    I made a sample script out of curiosity and it seems to check out. Keep in mind that writing to Transforms yourself, will not propagate to Articulations, it only "works" with Rigidbodies. Articulations ignore Transform changes and overwrite them on each simulation step.
     

    Attached Files:

  8. i-make-robots

    i-make-robots

    Joined:
    Aug 27, 2017
    Posts:
    17
    Fantastic! If that works I'm one step closer to calculating approximate jacobians, too.
     
  9. i-make-robots

    i-make-robots

    Joined:
    Aug 27, 2017
    Posts:
    17
    In related question...

    Code (CSharp):
    1.         bodyRoot.GetDriveTargets(targets);
    2.         bodyRoot.SetJointPositions(targets);
    > Articulation cache size(total degrees of freedom of all joints + 6 if root body is not immovable) does not match supplied list size!

    This seems odd. as it happens my bodyRoot is immovable so not sure why I get this message. I assumed the two lists are always the same length. The mobility of the root shouldn't be relevant, right? confused.

    Looking further down my log I see

    Code (CSharp):
    1.        bodyRoot.SetDriveTargets(targets);
    > Total degrees of freedom of articulation hierarchy joints do not match supplied list size!

    Well now that's just silly, it's the same list I got from GetDriveTargets.

    edit: a hint like "total degrees of freedom (8) does not match supplied list (6)!" would be great.
     
    Last edited: Aug 14, 2022
  10. Augustinas-Simkus

    Augustinas-Simkus

    Unity Technologies

    Joined:
    Mar 9, 2020
    Posts:
    84
    Regarding the first error message that you're getting, the method checks the list element count, throws this error, and aborts the call if they are not equal (I think the message should indicate that). If your List.Count matches the total dof count, please report a bug, I wasn't able to reproduce the issue in my quick test project.

    Regarding the second error message, I opened the code and I see a potential bug... List capacity is being checked instead of count when supplying the drive targets (or velocities). It does not cause the method to abort though (also potentially dangerous), so if you're supplying the correct amount of elements, you can ignore it until I fix it. (Will post the Issue Tracker link once it's up).

    That's a good idea. I'll add that while I'm at it.

    P.S. Which Unity version are you using?
     
  11. i-make-robots

    i-make-robots

    Joined:
    Aug 27, 2017
    Posts:
    17
    Sorry for the late reply, I go down a focussed rabbit hole of trying to fix things and not remember I have messages waiting.

    I'm using Unity 2021.3.7f1.