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. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    467
    I investigated a bit more and created a repro project you can find as an attachment.

    Instructions:
    1. Import package
    2. Open Scenes/JointBug scene
    Bildschirmfoto 2020-07-17 um 09.19.42.png
    All ArticulationBodies have a "JointState" component that can save the ArticulationBody.jointPosition/jointVelocity. The buttons all act on the "Fixed"-GameObject.

    Oddities:
    1. Run the scene, first click Save, then Restore. Observe that the joint states are reset.
    2. Click "Unparent" to unparent the "Fixed" game from "Revolute 1"
    3. The "Top"-Articulation stops working.
    4. Clicking "Save" now crashes the editor

    1. Run the scene
    2. Click "Unparent"
    3. Select "Revolute 1" in the editor
    4. disable/enable the Articulation component
    5. "Save" and "Restore" works now. (there is a "Unparent Fixed & reset"-Button that will disable/enable all ArticulationBodies, but this doesn't work. Both articulations stop working)
     

    Attached Files:

    sohojoe and GabsKapellmann like this.
  2. GabsKapellmann

    GabsKapellmann

    Joined:
    Jun 13, 2018
    Posts:
    10
    This might be a silly question, but I have not found any answer to this.

    Can rigidbodies be placed in the same tree, or child, or parent of a set of articulation bodies without repercussions?

    I see that joints work with rigidbodies as well as articulated ones, but between them, do they interfere? Or can a rigidbody be at the parent gameobject who has a set of childs with articulated bodies and have no problems?
     
    Last edited: Jul 22, 2020
  3. Vilmantas

    Vilmantas

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    29
    Thanks for repro project ! I will take a look.
     
  4. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    467
    I also posted this as a bug: 1264800
    @Vilmantas thanks for dealing with this.
     
  5. sohojoe

    sohojoe

    Joined:
    Feb 13, 2015
    Posts:
    21
  6. Vilmantas

    Vilmantas

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    29
    @sohojoe, this looks really good ! Did you experience any issues ?
     
  7. rz_0lento

    rz_0lento

    Joined:
    Oct 8, 2013
    Posts:
    2,361
    This is a long thread so I don't know if this has been requested/reported already but:

    Any chance we could translate the articulation root in scene view via tranform gizmo while the game is running? With regular physics, this works fine but for articulation, it always snaps the articulation body back where the sim happened. I get that this kind of behavior can't easily happen with articulation child bodies but would be handy if it was allowed on the root as that you should be able to translate via code gracefully.
     
  8. lazyrobotboy

    lazyrobotboy

    Joined:
    Jul 1, 2020
    Posts:
    16
    Is it intentional that transform.position does not change its world coordinates when a joint moves (see attached image)? It seems like the object only refers to the position relative to the parent due to the fact that it is so close to zero. Observed this behaviour in the "articulations-robot-demo" (https://github.com/Unity-Technologies/articulations-robot-demo).
     

    Attached Files:

  9. GabsKapellmann

    GabsKapellmann

    Joined:
    Jun 13, 2018
    Posts:
    10
    Similar to the last two posts, yes, translation would be very useful.

    So for design reasons I have a GO with two childs, each child has a different Articulation Body root and then a set of 3 to 6 joints.

    I am using also the XR Toolkit to attempt to grab the parent, but it requires for it to have a Rigidbody. It is then a bit confusing and not clear (At least to me) how this three components can work together.

    Attempting to move the parent wont move the childs, and the gravity of the rigidbody seems to have conflict with the "use gravity" of the childs if "immovable" is deactivated.
     
  10. rz_0lento

    rz_0lento

    Joined:
    Oct 8, 2013
    Posts:
    2,361
    Have you tried moving it via ArticulationBody.TeleportRoot? (this is what I referred to earlier that it is possible to translate these via code)
     
  11. GabsKapellmann

    GabsKapellmann

    Joined:
    Jun 13, 2018
    Posts:
    10
    Interesting point! I will have a look at it.

    However, in this case because I have two Articulated bodys (Roots of different systems) as childs of the parent that is being grabbed by a VR user with the XR toolkit, it would be way better to have the childs follow the parent.

    Nevertheless, lets try to make it work with what we have so far.
     
  12. rz_0lento

    rz_0lento

    Joined:
    Oct 8, 2013
    Posts:
    2,361
    Actually I didn't initially quite grasp initially how you wanted to use this. You can attach regular joints to any ArticulationBody (even non-root) since 2020.2.0a15 so if you can make your grab handle thing to use this mechanism, it should work for all parts. I don't know how your toolkit handles it but it could be pretty trivial additional check + hook to ArticulationBody instead of Rigidbody.
     
  13. GabsKapellmann

    GabsKapellmann

    Joined:
    Jun 13, 2018
    Posts:
    10
    Yes I get your point here, problem is that the toolkit being used is the new XR Toolkit from Unity. With their toolkit they have a script XR Grabbable, which forcefully adds a Rigidbody.
     
  14. applicattura

    applicattura

    Joined:
    Mar 28, 2017
    Posts:
    16
    I am still confused with the articulation body. Is the ragdoll based on these new bodies more stable than a regular one made with normal bodies?
     
  15. niccarey

    niccarey

    Joined:
    Mar 25, 2020
    Posts:
    5
    I've been trying out attaching rigid bodies to articulation bodies via regular joints, but the behavior seems odd - eg. at steady state things look ok-ish but as soon as I add even a small force to the rigid body, the joints break instantly. Tried fixed and configurable so far, locking various axes changes nothing.
     
  16. mlongest

    mlongest

    Joined:
    Mar 1, 2017
    Posts:
    1
    Really love this feature!
    One feature that would help on ArticulationBody is RigidBody's
    SetDensity
    .
    I've run into situations with complicated articulations where I drastically underestimated the mass on the root relative to the children and got really shaky results.
     
    felbj694 likes this.
  17. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,065
    Correct me if I'm wrong but is ArticulationBody suffering the same problem as previous joints.
    When you disable and enable the initial position/rotation is changed from what was created, and set to this new settings.
    And let me guess there is no way to set the initial position.

    If so than I'm hugely disappointed.
     
    GabsKapellmann likes this.
  18. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    467
    Dark thoughts. But fear not! The link state can be read and written. See one of my previous post for how to do that, but it’s simple: store jointPosition and jointVelocity somewhere. At any time, you can set this property from the values that you saved.

    Be aware that, depending on the degrees of freedom of the particular ArticulationBody, these values are actually arrays.

    I hope I could smash your disappointment although I’m somewhat worried that you assumed the worst. One last note: if you change the articulation hierarchy, be careful with setting and getting those values, it’s still buggy. I filed a bug report and it’s been reproduced yesterday. You can also look at how it’s done in my post from July 17.
     
    GabsKapellmann likes this.
  19. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,065
    I do not know if we are talking about the same thing. But take a look at the picture below.
    3 sets of two bodies (same settings) in different state.
    Left - Initial setup (before play).
    Middle - After play mode when body stabilized.
    Right - After disabling and enabling child ArticulatedBody.

    As you can see limits are changed.

    I beg you Unity don't go this road. Previous joints were broken like this, why repeat the mistake.

     
  20. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    467
    I guess upon reenabling, the child ArticulationBody re-computed the parent anchor and it's obviously in a different position now, hence the difference in position. The child articulation body completely defines the relationship with its parent by the following properties:
    • jointType
    • parentAnchorPosition
    • parentAnchorRotation
    • anchorPosition
    • anchorRotation
    • jointVelocity
    • jointPosition
    If you save all those values before disabling and restore them after re-enabling the ArticulatedBody, everything should be back in place. There is a problem though: Compute Parent Anchor will work against you. Uncheck that box of the child ArticulationBody.

    No need for begging. See nvidias documentation on physx and Articulations. If you consider working with it, it's well worth a read.
     
  21. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,065
    You are right, I don't know how this happened but "Compute Parent Anchor" somehow slipped my attention.
    Probably because I'm used to my own wrapper around ConfigurableJoint that don't have auto configuration.

    Still as you noticed Enabling Disabling pose some troubles, and I think this should be addressed.
     
  22. Vilmantas

    Vilmantas

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    29
    Hey,
    there is no need to beg. We are working to address the issues mentioned in this forum thread and others. This thread was made precisely to gather feedback, learn about issues and have a communication channel about articulations.

    Kind regards,
    Vilmantas
     
  23. rz_0lento

    rz_0lento

    Joined:
    Oct 8, 2013
    Posts:
    2,361
    I'd have one additional request for articulation joints:
    - When using revolute joint, let us pick the axis like on other joint options. Right now to swap the joint axis we need to manually rotate both anchor rotations until we get the right axis which kinda does the job but not as elegantly.
     
    Julien_at_work likes this.
  24. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    467
    Will velocity and angularVelocity be writable for root objects in the 2020.1 release cycle? I've only seen this work in the 2020.2 alpha versions up to now.
     
  25. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,065
    I have played a little with articulations and articulations based ragdoll.
    The biggest problem I see is actually stability when intersecting (overlapping) with static collider. (tested with static cube)
    Ragdoll starts to madly throw it's body parts around (with immense force) and even after removing this static collider it takes a while before becoming stable.
    This is when I set it's root to immovable.
    When it is movable body just launch itself with a great velocity.

    Also setting immovable to false during runtime does nothing. (until you deactivate and activate kinematic chain hierarchy)
     
  26. pbechard

    pbechard

    Joined:
    Nov 22, 2015
    Posts:
    6
    two quick questions:
    1) Is there currently any way to get the force+torque acting on an articulation body (like a force torque sensor)?
    2) Is there currently any way to get the motor torque applied by an articulation drive?
     
    mvaandrager likes this.
  27. Vilmantas

    Vilmantas

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    29
    Hey,

    unfortunately currently it is not possible, however I ll look at ways to have such ability due to a popular demand.

    Kind regards,
    Vilmantas
     
    mvaandrager and pbechard like this.
  28. Vilmantas

    Vilmantas

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    29
    Hey,

    i didn't observe such behaviour so far. Do you have any simple scene to share ? Report a bug ? Did you try to limit joint drives max force ? Current default value of maximum float value is way too strong, what happens if you set it to say 1000 ?

    Kind regards,
    Vilmantas
     
  29. Vilmantas

    Vilmantas

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    29
    Hey,

    so far I didn't make a backport to 2020.1, however i can consider making it if it is badly needed.

    Kind regards,
    Vilmantas
     
  30. Vilmantas

    Vilmantas

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    29
    Koirat, as for immovable setting during runtime not working properly - did you check 2020.1.1 ? This should have a fix for that ? Or are you using 2020.2 ?

    Kind regards,
    Vilmantas
     
  31. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    467
    No worries, I can wait for 2020.2 :)
     
  32. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,065
    Unity3d 2020.1.1f1
    For immovable set from true to false. I have to disable and enable the ArticulationBody component. For body to fall to the ground with gravity.
     
  33. niccarey

    niccarey

    Joined:
    Mar 25, 2020
    Posts:
    5
    I'm finding adding forces with SetJointForces pretty unintuitive. E.g. Running GetDofStartIndices returns 10DoF for 12 bodies (which is correct, there are some fixed joints in the articulation), but the returned list gives double indexing on several bodies (i.e.. {0, 0, 1, ..., 7, 8, 8, 9} ...).
    From inspection, I guess what's happening is that the index count doesn't increase for a fixed joint?
     
    Last edited: Aug 11, 2020
  34. Vilmantas

    Vilmantas

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    29
    Yes, fixed joint has 0 dof, so joint dof start index does not increase.
     
  35. Vilmantas

    Vilmantas

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    29
    Will take a look at this.
     
  36. airnamics

    airnamics

    Joined:
    Feb 5, 2020
    Posts:
    28
    Hey, question about .TeleportRoot(pos, rot).

    I have this code:

    Code (CSharp):
    1.  
    2. public class TeleportArticulation : MonoBehaviour {
    3.  
    4.     ArticulationBody body;
    5.  
    6.  
    7.     void Start() {
    8.      
    9.         body = GetComponent<ArticulationBody>();
    10.     }
    11.  
    12.     void Update() {
    13.  
    14.      
    15.  
    16.         body.TeleportRoot(transform.position, transform.rotation);
    17.     }
    18.  
    19.     void FixedUpdate() {
    20.  
    21.         body.TeleportRoot(transform.position, transform.rotation);
    22.     }
    23. }
    And, when I move the transform inside Scene Editor, where this script and root articulation is, it moves correctly, albeit very laggy.

    But when I move parent transform of this articulation transform, it is as if sometimes deltas of transform doesn't get registered. Does ArticulationBody root itself modify transform?

    Preview image, what I mean by moving private transform: ur10e is parent (with no articulationbody ofc).
    upload_2020-8-11_18-6-1.png
     
  37. pbechard

    pbechard

    Joined:
    Nov 22, 2015
    Posts:
    6
    That would be great! A bit of extra detail for 1), a FT sensor would show the forces + torques applied from a child link to a joint. Not the true net force + torque on a link, which could be derived from delta Vs + interial tensors, and would be zero for systems in equilibrium. ie An arm's gripper finger tips pressing against a wall (at stationary equilibrium), should show the relevant, non zero forces + torques applied to a parent wrist joint from the child (and gravity).
     
  38. airnamics

    airnamics

    Joined:
    Feb 5, 2020
    Posts:
    28
    Fixed it, now I have script on parent transform, which remembers relative transformation to child transform and he teleports articulation instead.
     
  39. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,065
    Please take a look at the video I recorded the situation, Articulation root is set to immovable.
     
  40. TimHogklint

    TimHogklint

    Joined:
    Nov 24, 2017
    Posts:
    40
    Unsure where to post this but I really appreciate the new articulation body - you rock unity devs !
     
  41. r3hman

    r3hman

    Joined:
    Feb 25, 2020
    Posts:
    5
    Hello everyone,
    I had sometime to play around with he new articulation body. I created a quadruped robot called HyQ2Max in unity (Real robot video
    ).
    I am also sharing a video showing the robot in unity. I am running Unity connected to ROS and Simulink.
    Unity is my simulator for all the physics that needed and Simulink is running IK and some motion planning algorithm, whereas ROS is playing a bridge role to communicate between Simulink and Unity. Enough with setup details

    About video, you will see a static foot position but changing the robot trunk orientation and position as user input command, and in second part trotting with the robot. Trotting doesn't look good for sure, there is a good reason for that, I have no closed loop controller running and just sending out each leg joint position. Normally, I would use inverse dynamics to control the robot to get joint torque reference given the foot trajectory.

    I have one and only one request "Please expose or enable the Inverse Dynamics so we can have joint Torque/Forces".


    Video Link
     
  42. Luke-Houlihan

    Luke-Houlihan

    Joined:
    Jun 26, 2007
    Posts:
    303
    What is the most effective way of zeroing out all existing velocity/momentum on a hierarchy of Articulation Bodies?

    I need to reset each articulation body in a robot simulation after each episode for reinforcement learning but I haven't been able to successfully lose the existing momentum. TeleportRoot() moves the root body but the robot is often immediately tipped over by inertia from whatever maneuver caused reset (e.g. falling off the platform). I've tried setting the velocity and angular velocity directly on all articulation bodies but they are read only.

    I'm currently trying to zero each body out by applying a counter force to negate the existing values but running into issues with my limited understanding of the physics. Is this the only way?
     
    Last edited: Aug 18, 2020
    mvaandrager likes this.
  43. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,065
    When it comes to physics:

    F = Mass * (0 - V) / dTime
    F is a counter force for a body to stop. V is it's current velocity. dTime = fixedDeltaTime

    Analogically Torque

    T = I * (0 - A) / dTime
    T is counter Torque for a body to stop. A is angular speed (in radians) " I " moment of Inertia dTime = fixedDeltaTime

    As you can see there are "0" in the equation. But Zero might be replaced by any number it is a target velocity/angularVelocity.

    But if it is machine learning you might reconsider recreating the whole object instead.
     
  44. Vilmantas

    Vilmantas

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    29
    You can set velocity and angular velocity after teleport on root articulation body. Also, you can do a complete reset to initial pose and zero velocites by using properties jointPosition and jointVelocity. Alternative approach would be to have your ArticulationBody hierarchy in a prefab, and destroy/instantiate upon reset of episode.
     
  45. Luke-Houlihan

    Luke-Houlihan

    Joined:
    Jun 26, 2007
    Posts:
    303
    @koirat Thank you for the formula and explanations they have helped my understanding tremendously. As you noted at the end of your post this approach hasn't worked well for me either because it takes a physics step to apply, meaning the ML algorithm will always get at least 1 frame of garbage input.

    @Vilmantas Thank you for the reply, how do I correctly set the velocity and angular velocity on the root body? Here's what I attempted (condensed)
    Code (CSharp):
    1. public ArticulationBody body;
    2. public void ResetAgentRootBody()
    3.     {
    4.         body.TeleportRoot(StartPosition.position, StartPosition.rotation);
    5.         body.velocity = Vector3.zero;
    6.         body.angularVelocity = Vector3.zero;
    7.     }
    This gives me 2 read-only property errors.

    My hunch is this is because I am using unity 2020.1, the documentation for 2020.2 is different

    I'll try your second suggestion and come back, thank you again for the responses.
     
  46. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,065
    He suggested to use:
    jointPosition and jointVelocity
    exact names.
     
  47. Luke-Houlihan

    Luke-Houlihan

    Joined:
    Jun 26, 2007
    Posts:
    303
    Tried the second approach with no success.
    Here's the code I used -
    Code (CSharp):
    1. public Transform StartPosition;
    2. public ArticulationBody body;
    3. public ArticulationBody[] servos;
    4. public void ResetAgentAllArticulations()
    5.     {
    6.         body.TeleportRoot(StartPosition.position, StartPosition.rotation);
    7.         ArticulationReducedSpace ARS = new ArticulationReducedSpace(0.0f);
    8.         for (int i = 0; i < servos.Length; i++)
    9.         {
    10.             servos[i].jointPosition = ARS;
    11.             servos[i].jointVelocity = ARS;
    12.             servos[i].xDrive = new ArticulationDrive
    13.             {
    14.                 damping = servos[i].xDrive.damping,
    15.                 forceLimit = servos[i].xDrive.forceLimit,
    16.                 stiffness = servos[i].xDrive.stiffness,
    17.                 lowerLimit = servos[i].xDrive.lowerLimit,
    18.                 upperLimit = servos[i].xDrive.upperLimit,
    19.                 targetVelocity = servos[i].xDrive.targetVelocity,
    20.                 target = 0
    21.             };
    22.         }
    23.     }
    And the result

    You can see in both resets that occur the inertia from the end of the last episode is still affecting the Articulation after the reset, enough to knock it over.
     
  48. Vilmantas

    Vilmantas

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    29
    Yes, seems the root body has velocity from inertia and setting joint velocities doesn't reset existing root articulation body velocity.
    Thing is, in 2020.1 ArticulationBody.velocity and .angularVelocity are read only. Can you try using 2020.2 ? That one has .velocity and .angularVelocity as read/write for root articulation body, so it should solve your problem.

    Also, as an alternative approach, if 2020.2 usage is out of question, just make your robot be a prefab game object, Destroy prefab and Instantiate in the reset. This will remove and deallocate robot from physics scene and instantiates a new copy in a initial pose without any velocities/forces. Ideal for resetting at the beginning of training episode.
     
  49. Luke-Houlihan

    Luke-Houlihan

    Joined:
    Jun 26, 2007
    Posts:
    303
    Ok, thanks @Vilmantas I'll try 2020.2, I was initially scared away from that version because of its 'Alpha' status but I suppose if I'm using cutting edge features like Articulation Bodies I need to push ahead of the regular releases :).

    I did manage to get instantiation/destroying to work, however the performance implications of constant garbage collection becomes exponential because I train with 5-10 environments per build, times 4-6 builds (depending on processor cores), times 2-4 machines running simultaneously. Once I move the training to a cloud provider it gets expensive. So I wanted to rule out all other options first.

    Again thank you for taking the time to help me out, I really appreciate the help and the overall focus Unity has put on providing tools for robotics and machine learning.
     
  50. Luke-Houlihan

    Luke-Houlihan

    Joined:
    Jun 26, 2007
    Posts:
    303
    Just a quick follow up - 2020.2 has worked well so far. Here's the reset code I'm using -
    Code (CSharp):
    1. public Transform StartPosition;
    2. public ArticulationBody body;
    3. public void ResetAgentRootBody()
    4.     {
    5.         body.TeleportRoot(StartPosition.position, StartPosition.rotation);
    6.         body.velocity = Vector3.zero;
    7.         body.angularVelocity = Vector3.zero;
    8.     }
    Works like a charm!