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
    Depending on what kind of joint this articulation body has with its parent, it has varying degrees of freedom. Depending on this, you can read values like this:
    Code (CSharp):
    1. force[0]
    2. force[1]
    3. ...
     
    InTooVR likes this.
  2. InTooVR

    InTooVR

    Joined:
    Jan 30, 2021
    Posts:
    2
    Thanks for the reply.
    This joint only has 1 DoF, so reading force or force[0] gave the same result:always zero. force[1] or beyond is out of bounds of the array.
    In this demo model https://github.com/Unity-Technologies/articulations-robot-demo I expect that the joint force of any of the two Articulation Bodies of the gripper are non zero when the gripper closes. I have attached the C# script to one of the gripper fingers.
    Any other suggestion?
     
    EdwinBabaians likes this.
  3. biu_biubiu

    biu_biubiu

    Joined:
    Dec 24, 2017
    Posts:
    5
    The articulationbody have bug and are easy to vibrate, but AI has learned to make the joints as stable as possible.
     
    sohojoe, TimHogklint and koirat like this.
  4. mirko_gft

    mirko_gft

    Joined:
    Aug 5, 2020
    Posts:
    2
    Could you please help on the topic of self-collision. I have two cubes that are stacked on top of each other with some distance in between them.
    Lower cube:

    • Mesh Renderer
    • Mesh Collider
    • Articulated Body (root)
    • Use Gravity and Immovable
    Upper cube:

    • Mesh Renderer
    • Mesh Collider
    • Articulated Body (child of lower cube)
    • Use Gravity
    • Anchor position = lower right edge of cube


    When turning on play mode, the upper cube spins correctly around the anchor position, however it spins into the lower cube (self-collision). Which setting is wrong, that prevents the upper cube from spinning into the lower one?
     
  5. lazyrobotboy

    lazyrobotboy

    Joined:
    Jul 1, 2020
    Posts:
    16
    Hey Anthony, any update on the inverse dynamics so that methods like GetJointForces or properties like jointForce finally become available? Thanks in advance.
     
    EdwinBabaians likes this.
  6. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    594
    Yes, we're working on it, hoping to make it available in builds over summer if the API shapes in well; that's a relatively low-level set of functions in PhysX. Unfortunately, I can't be more precise than that at this moment in time.
     
    drmgmt, EdwinBabaians and Nyanpas like this.
  7. monolythic

    monolythic

    Joined:
    Oct 12, 2013
    Posts:
    1
    hey Guys,

    I have been experimenting with ArticulationBodies for a basic robot simulation, and I am facing some issues with revolute joints.

    Let me present the situation: I have a vacuum cleaner robot (see attached figure), composed of a base, with two actuated wheels (revolute joints), one unactuated castor wheel (2 revolute joints), and a LIDAR head (1 vertical prismatic joint and 1 revolute joint).

    upload_2021-3-19_16-54-2.png
    upload_2021-3-19_16-54-24.png

    All the joints work as expected except for the revolute joints of the castor wheel (small support wheel).

    Basically, in the configuration that you see on the screen, the two revolute joints of the castor are not moving at all, and not trying to reach the target position of the xDrive, no matter how large the stiffness is. Even applying a torque from a script does not produce any motion of the joint, no matter how large the applied torque. They are also not rotating when hit by external rigibodies. However, setting the joint angle from a script does work.

    What I have realized, is that the mass of these links is apparently too small (50 grams), and setting the mass to a higher value (e.g. it starts reacting to forces at m=0.8kg). I have tried to change every possible physics parameter (e.g. fixed time step, iteration number etc...) but this does produce any effect on my problem. The problem seem to come from some sort of minimal mass/inertia threshold ? Is there such a physics parameter, is it even exposed ? Let me know if there is another way to solve the issue, as I do not want to be forced to have absurd masses for the different parts of my robot, and I don't think 50g is particularly small and should be handled correctly by the physics engine (50g rigidbodies work quite well...).

    I also have some overall remarks on points that could be improved for this component. I have not done a thorough research to check if these remarks were addressed in this thread or somewhere else, so maybe they will be a bit redundant.
    1. There seems to be no way to disable the gizmos for the articulation body, this component is not listed in the toggles of the dropdown Gizmos menu in the editor. Additionally, it would be nice to be able to scale the size of the joint visualization, as they tend to be way too large, for instance with the slider that controls the size of the Gizmos.
    2. The "Immovable" toggle does not work in Play mode (Unity 2020.3.0f) although I have seen in the release notes of an earlier version that this was corrected. Toggling "Immovable" from a script does work in play mode though.
    3. Why is there no option to change the center of mass and inertia matrix like for the rigidbody component. Both can be changed in scripts, but it would be much better to also be able to change them in the inspector. In fact, it is quite limiting to have the inertia automatically computed from the colliders.
    4. It is quite frustrating to not be able to move the base articulationBody in play mode. I know that the position of the base link should be changed with TeleportRoot(), but I believe it would still be desirable to just be able to move the base link by moving the transform Gizmos. This would not be so difficult to implement, especially in the case of Immovable bases.
    5. It would be nice to explain in the documentation how self-collision are handled in an articulation body tree ? From what I have understood, there are no collision between two adjacent bodies, but otherwise all joints can self-collide. I assume further self-collision can be disabled with Physics.IgnoreCollisions() or with the collision matrix and layers. Anyways it would be nice to have the documentation be more explicit about it.
    6. Another bug that I have caught is some erratic behavior with the Undo/Redo system with that component. In particular, the field "Anchor position" when values are set manually (e.g. not with the small anchor Gizmo), they cannot be undone/redone. This is quite frustrating, especially since Unity's undo/redo system usually works very well. The field "Anchor rotation" when set manually also sometimes exhibits weird behavior, like not being undone to the previous value.
    7. Multi-object editing does not work well with this component. I have had cases, where some joints properties are changed when they should not. For instance, selecting two joints and changing their anchor position, also causes the anchor rotation to be modified and set to the rotation of one of the other articulationBodies.

    Thanks a lot, sorry for the long post.
     
    yant likes this.
  8. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    594

    Thanks for the great feedback! We'll be replying soon.
     
  9. Gustorvo

    Gustorvo

    Joined:
    Oct 26, 2017
    Posts:
    32
    Please lead me to the right direction. I'm trying to understand how ArticulationBody.SetDriveTargets does work, so far whatever length of the list<float> I'm trying to supply, I get error - "Total degrees of freedom of articulation hierarchy joints do not match supplied list size!". I expect to get the correct length via
    GetDofStartIndices() and extracting the last item in that list (which should be the total num of dofs in the artBody hierarchy) but even though I get the above mentioned error.
     
  10. ratdox

    ratdox

    Joined:
    Dec 17, 2020
    Posts:
    12
    Hey, how can we go about doing inverse kinematics with articulation bodies? I figure we're supposed to use ArticulationJacobian but how? there's no documentation or examples and i'm completely lost :(

    thanks!
     
  11. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    594
    Inverse dynamics isn't yet exposed, unfortunately. This will come at a later moment. We only have the kinematic jacobian exposed that is mostly useful for IK of some sort.
     
  12. ratdox

    ratdox

    Joined:
    Dec 17, 2020
    Posts:
    12
    Oh, so we need inverse dynamics for inverse kinematics?
     
  13. Vilmantas

    Vilmantas

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    29
    Hey,
    https://docs.unity3d.com/2021.1/Doc...ence/ArticulationBody.GetDofStartIndices.html returns the total DoF for entire articulation body hierarchy.
    SetDriveTargets as well as GetDriveTargets use one buffer for entire articulation body hierarchy, each joint target represented by DoF count float values. ArticulationBody.index property should be used on a list populated by GetDofStartIndices to get the starting offset for joint target values.

    Kind regards,
    Vilmantas
     
  14. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    594
    Pardon, my bad. I read it too quick and assumed you were after inverse dynamics. :)

    For IK, there are a couple methods that you could implement based on the kinematic jacobian -- we had a simple jacobian transpose method implemented during the testing of this feature. It's not part of the API, was just a quick test.
     
  15. Gustorvo

    Gustorvo

    Joined:
    Oct 26, 2017
    Posts:
    32
    Trying all steps you mentioned and still no success...here is my results:
    I have a list of 17 bodies. Manipulating two drives of the same two-dof body, which has ArticulationBody.index = 1, results in changes of the first 2 elements in the GetDriveTargets list (at indexes 0 and 1 respectively). This is correct so far.
    Now, manipulating next two-dof body with ArticulationBody.index = 2 should change elements at indexes 2 and 3 respectively in the GetDriveTargets list but instead, elements at indexes 12 and 13 are changed. I'm totally confused!
    EDIT:
    Seems like I found a bug that was causing this odd behavior.
    I setup my articulation bodies at runtime, and some values won't update, so in order to re-initialize its values I just toggle art body component on and off like this:
    Code (CSharp):
    1. body.enabled = false;
    2. body.enabled = true;
    but this seems to break the order of elements in GetDriveTargets list afterwards. Is it a bug, or is it a normal behavior when disabling and enabling articulation body component?
     
    Last edited: Apr 8, 2021
  16. Gustorvo

    Gustorvo

    Joined:
    Oct 26, 2017
    Posts:
    32
    I'm stuck trying to figure out how to set drive values in a batch. How do we suppose to use SetDriveTargets function?
    Doing this:
    Code (CSharp):
    1. rootBody.GetDriveTargets(fetchedDriveTargetValues);                
    2. if (fetchedDriveTargetValues.Count == driveTargetValuesToSet.Count)
    3.     rootBody.SetDriveTargets(driveTargetValuesToSet);
    will throw this error "Total degrees of freedom of articulation hierarchy joints do not match supplied list size!"

    however, this works as expected:

    Code (CSharp):
    1. rootBody.GetDriveTargets(fetchedDriveTargetValues);
    2. List<float> newList = new List<float>(driveTargetValuesToSet);
    3. if (newList.Count == fetchedDriveTargetValues.Count)
    4.     rootBody.SetDriveTargets(newList);
    GetDriveTargets just for showing that list length in both code snippets are identical, but in case with the first one unity will complain that it isn't.
     
  17. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    594
  18. qw246

    qw246

    Joined:
    Sep 3, 2018
    Posts:
    1
    Hi @yant, I tried to use this method in a virtual mechanical claw. The claw or pincher part used one root and two revolute articulation joints to close/open pincher, which worked well when the root is fixed. However, when the claw is moved with the rest part of model using TeleportRoot method, the claw can no longer stably grab an object. Since it's a hand-held tool, it's meant to be moved with hands/controllers.
    I made a workaround by creating a root articulation at world origin and three prismatic joints representing world position of the claw. By manipulating these joints, I make it move while keep the gripper control working. I'm wondering if there's a better solution.

    Edit: creating a rigidbody with a fixed joint connected to the articulation root solves the problem.
     
    Last edited: Jul 23, 2021
  19. bjornsyse

    bjornsyse

    Joined:
    Mar 28, 2017
    Posts:
    102
    Hi!
    Love the new articulationbody system!

    I've tried it with great success setting up controllers for robotic arms like this one, but recently also created a joint chain bound to a bunch of hoses via a skinned meshed renderer. Worked great when fiddling with it moving transforms of the robotic arm. Hose joints are connected to the robotic arm hierarchy with Fixed Joints (which have a slot for hooking up articulation bodies).

    However, as soon as I set up the main embracing rig of the robotic arm (also with articulation bodies) things started breaking. Now it seems the pack of hoses are no longer individual rigs with their own respective root objects anymore but are instead being included in the larger robotic arm rig somehow. I'm trying to get my head around this, but have not succeeded yet.

    I also suspect it can be related to order of execution since there are moments where the hose will connect and move, but then falls out of the calculation and stands still in mid-air the next time I play. I've tried doing my input polling for controlling the drive's of the larger robotic arm joints using both FixedUpdate(), Update(), and LateUpdate()

    Can this setup work?

    M20 Experience - Frame 2.jpg
    1. Before with only hose rigs setup, moving the arm manually with transform in editor. This was very stable and never weirded out on me

    2021-04-16_11-18-18 a0_2.gif

    2. After setting up the arm aswell, I can't get hoses to move coherently.

    2021-04-19_07-03-15_1 A.gif

    3. Sometimes it works, only to bug out when I start the screen recording for no reason. Then starts to work when I try a setting (let's say turning on "use gravity" on the articulationbodies. Only to bug out the next play session.

    Any clues to push me in the right direction?
     

    Attached Files:

    Last edited: Apr 19, 2021
  20. Gustorvo

    Gustorvo

    Joined:
    Oct 26, 2017
    Posts:
    32
    Would like to report about 2 bugs:
    The 2nd one is very critical for me. Unitypackage file is attached.
    1. Setting drive target from editor (in Play mode) breaks the drive anchor and causes the drive to rotate infinitely around its axis. Setting drive target from script work fine.
    Drive target rotates with its anchor.gif
    2. Too small collider (by radius or length) will not move/affect articulation drive target (even though its value got updated) when the articulation body is the last one in the hierarchy. Changing collider radius (or length) to some bigger value makes articulation body to function as expected.

    too small radi.gif
    Drive target rotates with its anchor.gif too small radi.gif
     

    Attached Files:

    Last edited: Apr 21, 2021
  21. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    594
  22. Gustorvo

    Gustorvo

    Joined:
    Oct 26, 2017
    Posts:
    32
    I'm using 2020.3.4f1 (LTS). Haven't tried v 2021.2.X though. This bug came starting with unity version 2020.3.1.
    I assume that issues being fixed, related to articulation bodied, are also fixed for both 2020 LTS and 2021 versions, since articulation body is a new feature. Or am I wrong? I am going to work with articulation bodies a lot, what unity version you recommend to stay with (2020 or 2021) when it comes to "more stable Art bodies" ? I am planning to ship final product by the end of the year.
     
  23. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    594
    We're investigating this issue, seems we have't back-ported the fix to 21.1 and 20.3. PRs are en route as we speak, I'll be sharing dates/version as soon as I have them. Sorry for the caused inconvenience. <3 Anthony
     
  24. djarcas

    djarcas

    Joined:
    Nov 15, 2012
    Posts:
    245
    I have tried to make a simple vehicle with a trailer. However, pasting in another copy of that trailer causes this quite low level crash:

    Received signal SIGSEGV
    Stack trace:
    0x00007ff7082f8d82 (Unity) internalABP::doCompleteBoxPruning_Leaf
    0x00007ff7082f8bf8 (Unity) internalABP::doCompleteBoxPruning_
    0x00007ff7082f8ef3 (Unity) internalABP::findAllOverlaps
    0x00007ff7082f7d19 (Unity) internalABP::ABP::Region_findOverlaps
    0x00007ff7082fa908 (Unity) physx::Bp::BroadPhaseABP::update
    0x00007ff70828dd29 (Unity) physx::Bp::AABBManager::finalizeUpdate
    0x00007ff7082922d1 (Unity) physx::Bp::FinalizeUpdateTask::runInternal
    0x00007ff7081e7f92 (Unity) physx::Cm::BaseTask::run
    0x00007ff705253982 (Unity) PhysxJobFunc
    0x00007ff704b6911b (Unity) JobQueue::Exec
    0x00007ff704b69a0a (Unity) JobQueue::ExecuteJobFromHighPriorityStack
    0x00007ff704b69bcd (Unity) JobQueue::ExecuteOneJob
    0x00007ff7052247b5 (Unity) CompletionTask::processAllPhysicsTasks
    0x00007ff7052585e7 (Unity) PhysicsManager::Simulate
    0x00007ff70524f915 (Unity) `PhysicsManager::InitializeClass'::`2'::FixedUpdatePhysicsFixedUpdateRegistrator::Forward
    0x00007ff704c74f0c (Unity) ExecutePlayerLoop
    0x00007ff704c74fe3 (Unity) ExecutePlayerLoop
    0x00007ff704c7bfd9 (Unity) PlayerLoop
    0x00007ff70608ea71 (Unity) PlayerLoopController::UpdateScene
    0x00007ff70608c757 (Unity) Application::TickTimer
    0x00007ff7069eee21 (Unity) MainMessageLoop
    0x00007ff7069f2eb1 (Unity) WinMain
    0x00007ff708838fc6 (Unity) __scrt_common_main_seh
    0x00007fff9fda7034 (KERNEL32) BaseThreadInitThunk
    0x00007fffa06c2651 (ntdll) RtlUserThreadStart
     
  25. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    594
    @djarcas -- from the looks of it, appears to be a problem with the automatic box pruning. Could you try changing the broadphase algorithm in the physics settings to sweep and prune? Additionally, would be nice to have a repro & if you have it please submit through the bug reporter (built-in in the Unity Editor). Finally, does this relate to articulations in any way? Anthony.
     
  26. djarcas

    djarcas

    Joined:
    Nov 15, 2012
    Posts:
    245
    It is currently in Broadphase Sweep And Prune. Seems to be a 100% repro, tho, as ever, submitting my project would involve submitting some 20 gigabytes! I put it here as my entire scene is Articulated Bodies or static colliders, and the crash action is 'copying' the tractor-and-trailer object at the connecting joint and pasting it (effectively turning it into tractor-and-trailer-and-trailer - like Astroneer if you're familiar with it)

    Doing it again gives this:

    Code (CSharp):
    1. [C:\build\output\unity\physx\physx/source/physx/src/NpArticulationLink.cpp line 154]
    2.  
    3. [Physics.PhysX] PxArticulationLink::release(): Only leaf articulation links can be released. Release call failed
    4. UnityEngine.StackTraceUtility:ExtractStackTrace ()
    5. UnityEditor.Unsupported:PasteGameObjectsFromPasteboard ()
    6. UnityEditor.CutCopyPasteUtility:PasteGO (UnityEngine.Transform)
    and also

    Code (csharp):
    1.  
    2. Received signal SIGSEGV
    3. Stack trace:
    4. 0x00007ff705221d28 (Unity) Collider::FinalizeCreate
    5. 0x00007ff705234a03 (Unity) BoxCollider::Create
    6. 0x00007ff70521e1b2 (Unity) Collider::AwakeFromLoad
    7. 0x00007ff705493197 (Unity) AwakeFromLoadQueue::InvokeAwakeFromLoad
    8. 0x00007ff70548c04d (Unity) AwakeFromLoadQueue::AwakeFromLoad
    9. 0x00007ff70452acba (Unity) GameObject::ActivateAwakeRecursively
    10. 0x00007ff70452ac17 (Unity) GameObject::Activate
    11. 0x00007ff70667a259 (Unity) RepairTransformHierarchiesAfterPrefabMerging
    12. 0x00007ff706621031 (Unity) MergePrefabInstances
    13. 0x00007ff705e40add (Unity) PasteGameObjectPasteboardData
    14. 0x00007ff705e40e1c (Unity) PasteGameObjectsFromPasteboard
    15. 0x00007ff70728ec37 (Unity) Unsupported_CUSTOM_PasteGameObjectsFromPasteboard
    16. 0x000001eb7f62f9b7 (Mono JIT Code) (wrapper managed-to-native) UnityEditor.Unsupported:PasteGameObjectsFromPasteboard (UnityEngine.Transform)
    17.  
    (I've also uploaded a crash report, if that's helpful)
     
  27. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    594
    Please do post the case number here if possible, I'll make sure it's on the fastest lane.
     
  28. djarcas

    djarcas

    Joined:
    Nov 15, 2012
    Posts:
    245
    Case 1332088

    Thank you for the fast response!
     
  29. emmanueldolderer

    emmanueldolderer

    Joined:
    Apr 3, 2021
    Posts:
    3
    Is it possible to kind of teleport the articulation body? I know that there's the teleport root, but I am not sure if that's what I want. So, I have a spaceship and I have the spaceship's interior. The spaceship interior is on another object not connected to the spaceship itself which is then teleported to the spaceship's position and rotation every frame, thus causing all the physics objects inside to be teleported "by magic" and thus their oh physics not being affected by the displacement. I also have an articulation body connected by a joint to kinematic object with a joint on it. However, the articulation body's physics are still affected by the movement of the space ship which shouldn't be happening. How do I go about negating that?
     
  30. hackan

    hackan

    Joined:
    Aug 2, 2013
    Posts:
    1
    I'm experiencing issues moving the root of an ArticulationBody, and hope this is the correct thread to ask about it.
    • Setting velocity to the root of an ArticulationBody results in different velocities depending on if it has gravity enabled.
    • For an object not symmetric along the y-axis, applying angular velocity to the root can lead to a floating object if gravity is disabled. Initial thought is that it would be related to intertia / center of mass.
    I'm using Unity to simulate a mobile manipulator, but with this behaviour I need to disable gravity - which leads to a floating and tilting robot. Attached file is very simplified, just to show the issue, with three different objects with and without gravity enabled.

    I've just updated to Unity 2020.3.7f1, also tried with 2021.1.5f1.

    Is this a bug, or am I completely misunderstanding how to use ArticulationBody? Is there a way I can avoid a floating robot but still have correct velocities?
     

    Attached Files:

  31. Gustorvo

    Gustorvo

    Joined:
    Oct 26, 2017
    Posts:
    32
    I have a feeling that I must have misunderstood some basic concept regarding articulations, or rather joint space (or reduced coordinates). Here is the simplified version of the problem. Essentially I'm trying to find a target rotation in order to achieve a desired result. For example, the things start going very weird when simply trying to achieve rotation of an object of 90 degrees on Z and X axis. I'm using spherical joint, setting Z and X drives to 90 degrees. See green cube on screenshot below.
    Is it a normal behaviour ? Have I totally misunderstood the concept behind articulation bodis?
    upload_2021-5-7_21-6-30.png upload_2021-5-7_21-7-33.png
     
    Last edited: May 7, 2021
  32. laurent_quark

    laurent_quark

    Joined:
    Jan 10, 2021
    Posts:
    9
    hi, try this code, and write the value (x,y,z) of driveTarget in X,Y,ZDrive.Target
    i can't help u more. it's new for me too, but do u have the same result with a classic cube (without articulationBody, just write 90 90 90 in transform.rotation) ?

    Code (CSharp):
    1.  Quaternion normalizedRotation = Quaternion.Normalize(Quaternion.Inverse(m_articulationBody.transform.rotation) * quaternion;
    2.  
    3.                 // Calculate drive targets
    4.                 Vector3 driveTarget = new Vector3(
    5.                   Mathf.DeltaAngle(0, normalizedRotation.eulerAngles.x),
    6.                   Mathf.DeltaAngle(0, normalizedRotation.eulerAngles.y),
    7.                   Mathf.DeltaAngle(0, normalizedRotation.eulerAngles.z)) * m_rotationStrength;
     
  33. Gustorvo

    Gustorvo

    Joined:
    Oct 26, 2017
    Posts:
    32
    Your code doesn't make any difference, I get the same result.
    No, I don't have the same result when rotating cube by 90 on X and Z neither from inspector, nor using transform.rotation, results are correct. However, when trying to achieve the same result by just using drive targets (Z and X drives set to 90) will give me this weird rotation (X=34, Y=76, Z 137). Strange thing thought that just using only one DOF of articulation works fine (i.e. drive target of 90 will result in obj being rotated by 90 degrees on that DOF). Looks like a bug for me. Could someone from unity physics team confirm this please?
     
    Last edited: May 8, 2021
    laurent_quark likes this.
  34. TimHogklint

    TimHogklint

    Joined:
    Nov 24, 2017
    Posts:
    40
    Regarding the transpose demo.

    Is there a way to restrict this to only say the arm chain of an humanoid rig ? Im having problems since my "orgin" of transpose is not the root joint.
     
    Last edited: May 8, 2021
  35. Hakazaba

    Hakazaba

    Joined:
    Jul 1, 2015
    Posts:
    119
    Hi, I'm having an issue where GetDofStartIndices does not seem to be returning the correct targets for SetDriveTargets

    The drive targets of the wrong articulation bodies are being set. Is there something obviously wrong with this code?
    Code (CSharp):
    1. root.GetDofStartIndices(driveIndexs);
    2.         foreach(KeyValuePair<ArticulationBody,Transform> joint in altJoint){
    3.             int dof = joint.Key.dofCount;
    4.             int index = joint.Key.index;
    5.            
    6.             int driveIndex = driveIndexs[index];
    7.            
    8.            
    9.             if (dof == 3){
    10.    
    11.                 Quaternion v = joint.Value.localRotation * Quaternion.Inverse(initialTransform[index]);
    12.                
    13.                 driveTargets[driveIndex] = v.x;
    14.                 driveTargets[driveIndex+1] = v.y;
    15.                 driveTargets[driveIndex+2] = v.z;
    16.            
    17.             }
    18.             else if(dof==1){// elbow, always uses x even though joints use y. Or finger, uses a different angle
    19.                 if(joint.Key.mass < 1)//Fingers way less than 1
    20.                 driveTargets[driveIndex] = (joint.Value.localRotation *Quaternion.Inverse(initialTransform[index])).y;
    21.  
    22.                
    23.                 else
    24.                 driveTargets[driveIndex] = (joint.Value.localRotation* Quaternion.Inverse(initialTransform[index])).x;
    25.             }
    26.            
    27.    
    28.         }
    29.         root.SetDriveTargets(driveTargets);
     
  36. Gustorvo

    Gustorvo

    Joined:
    Oct 26, 2017
    Posts:
    32
    I have the same issue when using unity version 2021.1.6f1.
    However, 2020.3.01f seems to work as expected.
    P.S. Also, make sure you convert your 'target values' to radians, since nothing is consistent.
     
  37. Gustorvo

    Gustorvo

    Joined:
    Oct 26, 2017
    Posts:
    32
    I use this extension method for finding the correct target rotation to apply to my articulation body. This will also take care of axis miss-match (i.e. when you've rotated your articulation body using anchor rotation so that vectors' directions between reference obj and articulation obj are different). This will also remove the
    necessity of taking care of DOF count of each body. I choose not to wrap the angle in range [-180,180] because of the side effects when art body spins backwards when out of that range.
    Code (CSharp):
    1.  public static Vector3 ToTargetRotationInReducedSpace(this ArticulationBody body, Quaternion targetLocalRotation)
    2.     {
    3.         if (body.isRoot)
    4.             return Vector3.zero;
    5.         Vector3 axis;
    6.         float angle;
    7.  
    8.         //Convert rotation to angle-axis representation (angles in degrees)
    9.         targetLocalRotation.ToAngleAxis(out angle, out axis);
    10.  
    11.         // Convert into reduced coordinates and apply target rotation
    12.         Vector3 rotInReducedSpace = Quaternion.Inverse(body.anchorRotation) * axis * angle;
    13.  
    14.         return rotInReducedSpace;
    15.     }
     
    Hakazaba and TimHogklint like this.
  38. Hakazaba

    Hakazaba

    Joined:
    Jul 1, 2015
    Posts:
    119
    Hey, after having orientation issues as you predicted i tried out this code, im not sure if i've setup something incorrectly on my end, but this code has created some added unexpected offsets in rotation when no rotation had taken place.

    Is there something i need to do to the local rotation first?

    The joint has a fairly extreme transformation that causes gimbal lock issues if i simply negate this initial translation, and causes transformations which are different than expected. It is a character's shoulder, im trying to use a second rig to drive the rotations of a rig of articulation bodies.
     
    Last edited: May 29, 2021
  39. felbj694

    felbj694

    Joined:
    Oct 23, 2016
    Posts:
    35
  40. JuozasK

    JuozasK

    Unity Technologies

    Joined:
    Mar 23, 2017
    Posts:
    84
    Heya! What's wrong with using teleport root? Could you elaborate on why that method doesn't work for your use case?

    Please report a case on this, not sure if it's a bug yet, but at the very least it merits some more investigation.

    Could you report this? Looks like it could be a problem.

    It looks like the connected Articulation Body could be snappier than it is right now. Compared to the rigidity of the fixed joint of the Rigid body + rigidbody, the Rigid body + Articulation body via Fixed joint looks like jelly.

    You could try to enable the Temporal Gauss Seidel solver type in the Project settings window for slightly better results, but in general looks like it could be functioning better. Your case should be converted to a bug soon. After that we'll take a look when we can :)
     
  41. felbj694

    felbj694

    Joined:
    Oct 23, 2016
    Posts:
    35
    Ok, i tried using the Temporal Gauss Seidel, and yes a bit snappier but not greatly...


    It is also strange that the joint seem to work to keep the distance, as you can see on the top right small box which doesn't spring up and down.

    I did create a bug report, case 1339597
     
    JuozasK likes this.
  42. Mccbbi

    Mccbbi

    Joined:
    Feb 8, 2015
    Posts:
    12
    Hi!
    How can I stop body drive following target?
    I thought about setting forceLimit or Stiffness to zero, but can't access those values to set.
     
    Last edited: Jun 1, 2021
  43. emmanueldolderer

    emmanueldolderer

    Joined:
    Apr 3, 2021
    Posts:
    3
    Well, I have my articulation body connected to a configurable joint that moves the articulation body to the position of the VR controller. This is done in place of simply teleporting the articulation body to controller's position in order to allow for collision to occur (i.e. if you move your real life hand into the virtual wall and through it, the in-game hand won't be able to simply teleport to the other side of the wall.) I also can't lerp the position because I need to calculate forces for various physical interactions. With a regular rigid body connected to a joint, you can teleport the joint and the rigid body connected won't take that teleportation into account, but the articulation body does. How can I fix this?
     
  44. JuozasK

    JuozasK

    Unity Technologies

    Joined:
    Mar 23, 2017
    Posts:
    84
    The separate drive properties don't have setters, something that we may change in the future, but for now you should be able to create a temporary copy of the ArticulationDrive, change the stiffness or forceLimit and then set the copy back to the Articulation body.
    For example:
    Code (CSharp):
    1.         var ab = GetComponent<ArticulationBody>();
    2.         var tempDrive = ab.xDrive;
    3.         tempDrive.stiffness = 100;
    4.         tempDrive.upperLimit = 90;
    5.         ab.xDrive = tempDrive;
    You should be able to set stiffness to 0 and then the body will not follow the target anymore.
     
    Mccbbi likes this.
  45. Gustorvo

    Gustorvo

    Joined:
    Oct 26, 2017
    Posts:
    32
    Thank you for pointing out. I have investigated it more precisely and I can confirm the issue. In my case the rotation issue was miserable so I barely noticed it. It looks like a bug related to articulation body. For now I'll stick with the old approach (which also has an issue described here) but works fine for me since my setup doesn't involve those "extensive" rotations. If you happen to solve the issue (in case it's not a bug), let me know.
    UPDATE:
    Looks like I found the root of the issue, which is caused by "Compute Parent Anchor" checkbox...seems like parent anchor is computed incorrectly. See my screenshot. Unchecking "Compute Parent Anchor" and manually setting up Parent Anchor Rotation (which should have same values as Anchor rotation) solved the issue in my case!
    upload_2021-6-3_21-42-58.png upload_2021-6-3_21-42-58.png
     
    Last edited: Jun 3, 2021
  46. Gustorvo

    Gustorvo

    Joined:
    Oct 26, 2017
    Posts:
    32
    You can move you articulation body using AddForce method, for rotation use AddTorque. Alternatively, you can attach your art body to a rigidbody (rigidbody being a patent to art body) using fixed joint and then apply the same alternative methods to move and rotate your rigidbody. The second approach has benefits since you can enable Interpolate to eliminate jerkiness in movement, which would normally occur if you move your art body (referencing VR controller) as art body lacks that property.
     
  47. flimflamm

    flimflamm

    Joined:
    Jan 6, 2020
    Posts:
    43
    I would advise against using AddTorque or Force() for VR controller movement, mainly because (AFAIK) they act like one time force additions that do not dynamically resolve for a target through the iterative physics system. Target rotations do this, so they're almost always going to be quicker and more precise for getting a given body to a target location or rotation.
     
  48. Gustorvo

    Gustorvo

    Joined:
    Oct 26, 2017
    Posts:
    32
    Hmm, not sure what you mean here... An alternative method to move root of articulation body other than AddTorque and AddForce() ?
     
  49. Mccbbi

    Mccbbi

    Joined:
    Feb 8, 2015
    Posts:
    12
    Is it possible to connect two Articulation bodies together?
    Imagine that in ArmRobot sample scene those two robotic hands get linked together and fight who is stronger.
    I tryed using FixedJoint, linked to both of them, but I cant achieve a "realy fixed" joint connection behavior. Maybe I miss something here? Thanks!
     
    Last edited: Jun 8, 2021
  50. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    594
    Though it's certainly possible to connect two articulation bodies together by an iterative joint in PhysX, we still don't have this in Unity due to some design limitations with our Joints that were introduced a decade ago. What we've made possible not long ago is to connect an ArticulationBody with a Rigidbody using an iteration joint, so I imagine you could have an intermediate Rigidbody though which to link. Would that work out as a workaround for now?
     
    Mccbbi likes this.