Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice
  2. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  3. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Featherstone's solver for articulations

Discussion in 'Physics Previews' started by yant, Dec 11, 2019.

  1. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    595
    This has just been fixed and is on the way to be delivered to 2020.2 first. A back-port is a must in this case, of course.
     
  2. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    595
    @sohojoe can you send me a project that illustrates the perf issues please? I'm not aware of any at the moment, would greatly help. Appreciated. Anthony.
     
  3. newlife

    newlife

    Joined:
    Jan 20, 2010
    Posts:
    1,064
    Hello @yant any news about this?
     
  4. airnamics

    airnamics

    Joined:
    Feb 5, 2020
    Posts:
    28
    Hey, I still get weird bug, where physics just doesn't stay still (articulation body doesn't sleep). Is there any chance you devs can check it?

    Even changing sleep treshold doesn't help, through physics settings or manually with script.
     
    Last edited: Jun 1, 2020
  5. airnamics

    airnamics

    Joined:
    Feb 5, 2020
    Posts:
    28
    Ok it seems I fixed it, I had one prismatic articulation on top which seems to be causing 'vibrations' of some sort, now whole body does get to sleep.
     
  6. sohojoe

    sohojoe

    Joined:
    Feb 13, 2015
    Posts:
    21
    I will need to think about how best to do this. But one question, assuming no new forces have been added, then should ArticulatedBody have additional performance overhead per physics step vs ConfigurableJoint
     
  7. sohojoe

    sohojoe

    Joined:
    Feb 13, 2015
    Posts:
    21
    We are implementing a PD Controller for the ArticulatedBody character to learn to mimic a Target/MechAnim character. The target/MechAnim character uses RidgedBody. We have a couple of questions:

    Question #1: What is the correct way to get the current angle and velocity of each degree of freedom per joint and what format does it give it in? (deg, rad, 0f-1f)

    Question #2: What would be the correct way to estimate the current angle of each degree of freedom per joint on the ridgedBody charicter - I'm assuming we can apply the anchorPosition/Rotation and parentAnchorPosition/Rotation in the target/ridgedbody's space, but I'm not sure how to combine the anchor and parentAnchor
     
  8. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    595
    They scale differently if we think about it.

    ConfigurableJoint creates a constraint per lock/limit -- so it scales with the total number of locked DoFs.

    ArticulationBody simulates in the reduced space -- so it scales with the amount of free DoFs. Featherstone's forward dynamics is linear in the number of unlocked DoFs.
     
    sohojoe likes this.
  9. sohojoe

    sohojoe

    Joined:
    Feb 13, 2015
    Posts:
    21
    @yant - I tested this today on 2020.1 beta 11 and when rotating x below -90 it will become unstable. or setting the rotation to 0, 90, 90 will give an odd result

    I updated the repro a little to show the difference between setting the joint.target and using joint.jointVelocity - https://github.com/Sohojoe/PD-controller/tree/5197bfa54b9f75da02c8d6ace06becf930798b3d
     
    Last edited: Jun 6, 2020
    yant likes this.
  10. airnamics

    airnamics

    Joined:
    Feb 5, 2020
    Posts:
    28
    Hello, just want to warn you, Articulations itself already work as a PD system. So you are now dealing with PD on a PD system.

    For answer #1, you can access DoF of each Articulation and read the current position, velocity, force in reduced coordinate space.
     
  11. niccarey

    niccarey

    Joined:
    Mar 25, 2020
    Posts:
    5
    @flawless_code I find the jointForce variable at any joint is always zero - I have been assuming up till now that force sensing is not yet enabled on the joints, since articulation bodies are still in beta. Have you had success in getting output from this variable?
    Context: I would love to implement some proper force-feedback control in my current simulation but without an explicit force/torque sensor it's difficult to develop a stable controller.
     
  12. sohojoe

    sohojoe

    Joined:
    Feb 13, 2015
    Posts:
    21
    My goal is to learn to mimic a mechanim/mocap character - so the input for the controller is the rotation of the mechanim/mocap character body in the ragDoll/ArticulatedBody joint rotation space. I.E. I want to re-calculate the equivalent of the AtriculatedBody.jointPosition using the mocap character.
     
  13. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    595
    This is a new component and we don't yet have stats on it, unfortunately. Theoretically, there will be an overhead reading poses back from PhysX to Unity transforms, and maybe a little overhead here and there in the simulation. The read back code hasn't been changed since some early builds shared in this thread, so it's not that much clever really.

    Could you at least give me some pointers at constructing a slow scene? How many articulation bodies? What's your simulation frequency? Things like that.

    Thank you for your contributions. Anthony.
     
  14. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    595
    Hi,

    Just a quick heads up that in 20.2a15 we have this new functionality.

    1) API for setting/getting velocities/max velocities for root body of articulation hierarchy.
    2) API for physically based inverse kinematics: computing jacobian matrix, various getters/setters for articulation cache and etc.
    3) Fixed ray casts to work correctly with colliders having attached ArticulationBody components (see Collider.attachedArticulationBody and RaycastHit.articulationBody)
    4) Fixed crash while acccessing Collider.attachedRigidbody property if collider has only ArticulationBody attached.
    5) Make it possible to use regular joints to link rigidbody and articulation hierarchies (see Joint.connectedArticulationBody)

    Anthony

    Er4tcXJ.gif
     
    ZiadJ, rz_0lento, mvaandrager and 3 others like this.
  15. airnamics

    airnamics

    Joined:
    Feb 5, 2020
    Posts:
    28
    Awesome news :D! So multi-bodies are now possible!
     
  16. niccarey

    niccarey

    Joined:
    Mar 25, 2020
    Posts:
    5
    great news @yant . As a followup to my previous questions, does that mean internal joint forces/torques will be exposed? I know PhysX has this capability but have not yet managed to get anything meaningful out of the AB joints.
     
  17. codebiscuits

    codebiscuits

    Joined:
    Jun 16, 2020
    Posts:
    84
    Is there a way to set the starting position of a prismatic joint?
    Like, I'm creating a suspension spring in code as a prismatic joint in Y that goes from 0 to -0.666, with a target of -0.666 and a stiffness that will cause it to level out at -0.333 when at rest.
    Currently it creates the spring with jointPosition[ 0 ] == 0 and then rapidly pushes it to -0.333.
    I'd like it to create the spring at jointPosition[ 0 ] = -0.333.
    I can't decide if I'm doing something wrong in code (like, with the anchors), or if this just isn't possible right now?
    I'm not convinced that it is paying attention to my parentAnchor values, I can set lots of values in code when I create the joint, but they don't appear in the editor (it always has "ComputeParentAnchor" checked, and if I uncheck it, it's not the values I'm asking for, and if I then make changes in the editor, I think I can get the behaviour I want).

    Edit: I'm using 2020.1.0b12
     
    Last edited: Jun 23, 2020
  18. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    467
    I might have a similar issue @codebiscuits. In my case it's a revolute joint, but the symptoms are the same. In my application, I need to inverse the hierarchy of a joint, so I need to copy the parent/child anchors from the former child to the former parent, but it seems like setting parentAnchorRotation and parentAnchorPosition is ignored unless I manually uncheck "Compute Parent Anchor".

    @yant could you either expose the "Compute Parent Anchor" property or just omit computing (and thus overriding) the parent anchor in case it's set by a script?
     
  19. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    467
    hey @yant, could you elaborate a bit more on:
    I'm trying to change the hierarchy of an articulation and as far as I understand, I need to reset all the joints anchors, parentAnchors, joint positions and velocities to make this change unnoticeable to the user. I tried the new API like this

    Code (CSharp):
    1. public void DebugInfo()
    2. {
    3.     List<float> positions = new List<float>();
    4.     List<float> velocities = new List<float>();
    5.    
    6.     ab.GetJointPositions(positions);
    7.     ab.GetJointVelocities(velocities);
    8.  
    9.     foreach (float p in positions)
    10.     {
    11.         Debug.Log($"position {p}");
    12.     }
    13.  
    14.     foreach (float v in velocities)
    15.     {
    16.         Debug.Log($"velocity {v}");
    17.     }
    18. }
    19.  
    which results in reasonable values for velocity and position. As soon as I change the hierarchy, the two lists are filled with 6 zeros and 1 reasonable value. Is that intended? Am I doing something wrong?

    Also: I guess that it doesn't matter on which body of the articulation hierarchy I execute GetJointPositions/Velocities, which makes sense to me since it should reflect the whole state of the articulation. But since I'll have to re-order the hierarchy, I need more information about the order of the values. How is the articulation tree traversed to collect the velocity/position values?

    I created a test project on github:
    https://github.com/fi4sk0/UnityArticulationsTests
     
  20. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    467
    One question answered: the 6 leading zeros were because the root body of swapped hierarchy wasn't immovable. The error message helped:
    Articulation cache size(total degrees of freedom of all joints + 6 if root body is not immovable) does not match supplied list size!
     
  21. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    467
    @yant some things I noticed in 2020.2.0a15
    1. calling articulationBody.jointPosition on a disabled ArticulationBody results in a crash
    2. switching on/off "immovable" during runtime doesn't add/remove the 6 degrees of freedom (changing it before switching to play mode works)

    And a question:
    Can I effectively replace TeleportRoot by using GetJointPositions(), manipulating the values and SetJointPositions() on a moveable Articulation?

    And in case this is not said often enough: big thanks to you yant for pushing this further!
     
  22. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    467
    Continuing my lone conversation.
    After reading https://gameworksdocs.nvidia.com/PhysX/4.0/documentation/PhysXGuide/Manual/Articulations.html confirms my assumption of being able to teleport the root:
    Unfortunately I get all zeros for both `GetJointPositions` and `GetJointVelocities` for a single ArticulationBody that accelerates using gravity for some seconds. Setting articulationBody.velocity and articulationBody.angularVelocity works, however. Is this intended? Am I doing something wrong?
     
  23. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    467

    Alrighty, I just realised angularVelocity and velocity can now be set (as of 2020.2.0a15 I guess). This solves my problem but doesn't answer my questions :)
     
  24. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    595
  25. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    595
    The current approach is to consider that the position in the prismatic joint is just an offset from the parent anchor really. With that in mind, move the parent anchor to where you think zero should be located. Hope that helps.
     
    codebiscuits likes this.
  26. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    595
    Oh dear, I think this has missed attention somehow. Indeed, one needs that property exposed and reset in order to set the parent pose. Not sure how to work this around really. Make a prefab with an ArticulationBody component where you set it manually from the editor? Make an extension to Unity's built-in inspector that would read the serialised property? (here is how the editor does that:
    https://github.com/Unity-Technologi.../Mono/Inspector/ArticulationBodyEditor.cs#L69)

    Will try to fix this, of course. Thanks for the report.
     
    tjmaul and codebiscuits like this.
  27. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    595
    Thanks @tjmaul for the report, I updated our tracking doc with this. Will get fixed.
     
  28. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    595

    Another workaround could be to set the anchorPose to where you want the parent pose to be, first. This will position the parent pose too, but then you can move the child hierarchy in the reduced coordinates I guess.
     
  29. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    467
    This is exactly what I did: I parented my objects to a dummy articulation body, unchecked the compute parent anchor box and created a prefab. Like this, I can set both the anchors and parent anchors and if the object is a root, it doesn't seem to have any adverse effects.
     
  30. AlTheSlacker

    AlTheSlacker

    Joined:
    Jun 12, 2017
    Posts:
    326
    Just wanted to say thanks for the support for this, I've been using it for a few days and really enjoyed it. I found I had to move to the alpha to be able to manually set the inertia tensors.

    I don't understand why the inertia tensors seem to have such a commanding effect on the articulation characteristics, even in relatively quasi-static loading; for now I have resorted to setting them to 1,1,1 and then tuning the stiffness and damping characteristics to get the visual behaviour I want. If anyone would like to try and explain this I would be happy to read...

    I'm assuming rotational stiffness is rad/Nm?
     
    airnamics likes this.
  31. r3hman

    r3hman

    Joined:
    Feb 25, 2020
    Posts:
    5
    Hello @yant,
    Great place to get a lot of information. I am really happy with ArticulationBody, this is game changing for Robotics simulation within Unity. I am almost done simulating my robot. I just need little help regarding getting Joint Torques for the Revolute joint and Joint Force for Prismatic joint. I am trying to use ArticulationBody.jointForce but result is always zero. I am carrying a payload and wanted to see how much in my joint torque and in case if I am pushing my Prismatic to ground, i would like see how much force is being applied. For both joints I am using x Drive and setting Target position.
    Is anyone tried this, my ultimate goal is to simulate a hydraulic actuated robot. I need this infromation to simulate hydraulics dynamics, I have my own dynamical model that depends joint Torque and Force, I know Roy Featherstones Algo provide all this information but I dont know how to get this information.
    Thanks in advance and one more time great job guys.
    Bilal
     
  32. zalo10

    zalo10

    Joined:
    Dec 5, 2012
    Posts:
    21
    Nice! With the ability to set the global linear and angular velocity, I'm able to suppress explosions entirely...

    I have one last feature request:
    When you set the linear velocity, it applies that linear velocity to all of the children. This is fine because AddForce doesn't (so I can zero the linear velocity and AddForce in the appropriate amount).
    However both setting the AngularVelocity AND AddTorque affect the children. Would it be possible to make AddTorque only affect the body it's called on? (In my case, this is also the root body)

    Additionally, considering the differences, would it be possible to have a VelocityMode on the AddForce/AddTorque functions? This would greatly simplify the math in my scripts.

    Thank you for the continued improvements!
     
  33. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    467
    AddForce and AddTorque do only affect the ArticulationBody that they're called on, but its effects are propagated through the joints.

    I'd also like that. But until it's there, you can just use an extension as follows:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public static class ArticulationBodyExtensions
    4. {
    5.     public static void AddForce(this ArticulationBody ab, Vector3 force, ForceMode mode)
    6.     {
    7.         switch (mode)
    8.         {
    9.             case ForceMode.Force:
    10.                 ab.AddForce(force);
    11.                 break;
    12.             case ForceMode.Impulse:
    13.                 ab.AddForce(force / Time.fixedDeltaTime);
    14.                 break;
    15.             case ForceMode.Acceleration:
    16.                 ab.AddForce(force * ab.mass);
    17.                 break;
    18.             case ForceMode.VelocityChange:
    19.                 ab.AddForce(force * ab.mass / Time.fixedDeltaTime);
    20.                 break;
    21.         }
    22.     }
    23. }
    24.  
     
    Last edited: Jun 29, 2020
    rz_0lento likes this.
  34. GabsKapellmann

    GabsKapellmann

    Joined:
    Jun 13, 2018
    Posts:
    10
    Is there no way to connect multiple articulations? Lets say, for the ABB robot arms, the IRB6660 model, for example, it has a link arm that manipulates one of the joints. But then, at some point there is the need of connecting two joints in a same body in different places.
     
  35. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    467
    The articulation can not contain loops. You can connect articulation bodies with regular joints in the latest alpha (2020.2.0a15 as of writing).

    For the robot you mentioned it seems like this extra link is not necessary for its physics model. You could use inverse kinematics to deduct the position of the extra link arm .. but I could only guess from the video that I found on their homepage
     
    GabsKapellmann and yant like this.
  36. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    467
    hey @yant, anything new for 2020.2.0a16? I didn't see anything in the release notes concerning articulations. Is there another place to follow the development?
     
  37. airnamics

    airnamics

    Joined:
    Feb 5, 2020
    Posts:
    28
    He always posts updates in this thread, I believe, it could just be other updates not related to articulations, I believe.
     
  38. r3hman

    r3hman

    Joined:
    Feb 25, 2020
    Posts:
    5
    Hello all,
    I am trying to use articulationbody function to get GetJointForces, but they are always zero, in the documentation it says that "Every joint force DOF is represented by one float value, however depending on the type of the articulation joint there might be zero, one or 3 DOFs per joint." But it doesnt specified which type of joint will result in zero force. I am using both Revolute joint and Prismatic joints for testing and both result in same value "0".
    Any hint or advice is welcome
    BR
    Bilal
     
  39. applicattura

    applicattura

    Joined:
    Mar 28, 2017
    Posts:
    16
    Hello, I am really interested in checking this new articulation body feature. Could You please let me know are there any github examples of it?
     
  40. airnamics

    airnamics

    Joined:
    Feb 5, 2020
    Posts:
    28
    applicattura likes this.
  41. Vilmantas

    Vilmantas

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    29
    Hey,

    Few points:
    a) i fail to reproduce crash when calling articulationBody.jointPosition on a disabled ArticulationBody. Can you elaborate what is your setup ? What stack trace you are seeing ? Best would be to report a bug.
    b) Will take a look at "immovable" issue.

    Regarding TeleportRoot, it is not the same as GetJointPositions which deals with joints, but not the root node. In the future versions it might, however for now those 6 dof zeroes are reserved when root is movable. For now TeleportRoot is used to place root body to specific position/orientation.

    Kind regards,
    Vilmantas
     
  42. Vilmantas

    Vilmantas

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    29
    To get the index of particular articulation body one can use ArticulationBody.index property and when substitute that as indexer value in List<float> for GetJointPositions/Velocities.

    Kind regards,
    Vilmantas
     
    yant likes this.
  43. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    467
    Thanks @Vilmantas!
    Most interestingly, it doesn't crash any more in my test project either. I'm scratching my head about this now.

    Also thanks for clarifying the GetJointPositions/Velocities!
     
  44. r3hman

    r3hman

    Joined:
    Feb 25, 2020
    Posts:
    5
    Hi,
    Could you please also suggest how to get joint forces, I know there is GetJointForces, which takes a List of float, and provides forces, these force can be either 0 or a 3 DOFs per joint. I am using this, but force that I get is always zero. Is there a away to get force that are being applied while moving the joint or simply keeping its position static. is there any way to get access to inverse dynamics, where given joint position, velocity and acceleration, one get get torques/forces?
    Kind regards
    bilal
     
  45. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    595
    Inverse dynamics is not yet available. Joints forces are non zero only when using inverse dynamics I'm afraid. Hope this clarification is still helpful. Anthony.
     
  46. hjgujtf

    hjgujtf

    Joined:
    Jul 13, 2019
    Posts:
    1
    Hello,when I'm tying to do snake robot simulation using Articulation,I find that a snake robot using more than 10 revolute joints will lead to AABB error and 'fly' away (I use xdrive for driving them).Could You please tell me a way to avoid this? The snake I used showing in the picture.
     

    Attached Files:

  47. r3hman

    r3hman

    Joined:
    Feb 25, 2020
    Posts:
    5
    Thank you @yant for reply. I am happy that I know the problem now. I was going nuts over this. Now I have few options to look into,
    Option 1: I put a feature request for Inverse Dynamics (put not sure how to do it)
    Option 2: Get access to inertia matrix also known as Mass matrix, H in the equation below, and C which is generalized bias forces which also contain gravity forces. Since you already have provided joint position q, velocity qdot and acceleration qddot. I can calculate joint torques. Now this option is vaild only if you give access to this information or I implement by my self, which I am afraid might slow things down for me.
    upload_2020-7-8_19-50-4.png
    Option 3: Use external library to calculate torques, but than I will external dependency which I want to avoid too.
    Option 4: sit tight and wait for Option 1 to be completed.

    I thoughts what should I do?
    Bilal
     
  48. Vilmantas

    Vilmantas

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    29
    Hey,

    i fixed the issue for immovable property setting not having any effect during runtime, fix will be shipped in later alphas and back ported to 2020.1.
    However, there is a easy workaround: after setting "immovable" property, call WakeUp() method on root articulation body and immovable state changes will be reflected in simulation, also +6 dof returned in joint accessors.

    Kind regards,
    Vilmantas
     
    airnamics likes this.
  49. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    467
    Hey there,

    Unity crashes sometimes when I set jointPositions and jointVelocities that I saved earlier to reset the pose of an articulation. It might have something to do with it being called from a click event. I hope this excerpt from the Editor.log helps. If not, I'll investigate more. It's still very obscure for me

    Code (CSharp):
    1. Obtained 5 stack frames.
    2. #0  0x000001084a48b8 in physx::NpArticulationReducedCoordinate::createCache() const
    3. #1  0x0000010504fb26 in ReadJointDofs(physx::PxArticulationCache::Enum, physx::PxArticulationReducedCoordinate*, physx::PxArticulationLink*)
    4. #2  0x0000010504fad6 in Unity::ArticulationBody::GetJointPosition()
    5. #3  0x000001057a6fd6 in ArticulationBody_CUSTOM_get_jointPosition_Injected(ScriptingBackendNativeObjectPtrOpaque*, Unity::ArticulationReducedSpace&)
    6. #4  0x0000013c45d81f in  (wrapper managed-to-native) UnityEngine.ArticulationBody:get_jointPosition_Injected (UnityEngine.ArticulationBody,UnityEngine.ArticulationReducedSpace&) {0x7fc09f742ba8} + 0xdf (0x13c45d740 0x13c45d8c9) [0x1318e1960 - Unity Child Domain]
    7. Launching bug reporter
    8. [Unity Package Manager (Upm)]
    9. Parent process [2875] was terminated
    10. QObject: Cannot create children for a parent that is in a different thread.
    11. (Parent is QObject(0x7fa5b2fd89e0), parent's thread is QThread(0x7fa5add04660), current thread is Thread(0x7fa5b3044e00)
    12.  
    This happens with 2020.2.0a15. I'm gonna test with the latest alpha now
     
  50. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    467
    Same problem with 2020.2.0a18, same stack strace