Community
Fusion API and Scripts
Got a new add-in to share? Need something specialized to be scripted? Ask questions or share what youโ€™ve discovered with the community.
cancel
Showing results forย 
Showย ย onlyย  | Search instead forย 
Did you mean:ย 

How to get the joint origin in world context

6 REPLIES 6
SOLVED
Reply
Message 1 of 7
spacemaster85
601 Views, 6 Replies

How to get the joint origin in world context

Hi,

maybe somebody can help me. I need to find the coordinates of all joints in a design in the context of the world.

The problem I have is that geometryOrOriginOne gives back the coordinates of the origin in the context of the linked component and not in the world coordinates (as far as I understood it).

Is there a method I missed which is giving me the joint origin in the world context, or have I to this on my own? 

If so please give me some advice how to do this ๐Ÿ™‚

 

 

import adsk.core, adsk.fusion, adsk.cam, traceback

def run(context):
    try:
        app = adsk.core.Application.get()
        product = app.activeProduct
        design = adsk.fusion.Design.cast(product)
        rootComp = design.rootComponent
        for joint in rootComp.joints:
            print(joint.name)
            print(f"Joint One: {joint.occurrenceOne.name} {joint.geometryOrOriginOne.origin.asArray()}")
            print(f"Joint Two: {joint.occurrenceTwo.name} {joint.geometryOrOriginTwo.origin.asArray()}")
    except:
        print('Failed:\n{}'.format(traceback.format_exc()))โ€‹

 

 

 
 

Fusion_Joint_Origin.PNG

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

The output of the script is:

Umdrehung2

Joint One: Komponente4:1 (0.0, 10.0, 10.0)
Joint Two: Komponente2:1 (0.0, 10.0, 5.0)
Umdrehung3
Joint One: Komponente5:1 (12.5, -10.0, 5.0)
Joint Two: Komponente4:1 (12.5, 7.5, 5.0)
Umdrehung4
Joint One: Komponente6:1 (-2.5, 2.5, -5.0)
Joint Two: Quader:1 (2.5, -2.5, 5.0)

 

You can see clearly that coordinates are not in world context.

 

Thank you for your help!

Labels (4)
6 REPLIES 6
Message 2 of 7
kandennti
in reply to: spacemaster85

Hi @spacemaster85 .

 

I created a code like this and tried it out.

#Fusion360API Python script
import adsk.core, adsk.fusion, adsk.cam, traceback

def run(context):
    try:
        app = adsk.core.Application.get()
        product = app.activeProduct
        design = adsk.fusion.Design.cast(product)
        rootComp = design.rootComponent
        for joint in rootComp.joints:
            print(joint.name)
            print(f"Joint One: {joint.occurrenceOne.name} {joint.geometryOrOriginOne.origin.asArray()}")
            print(f"Joint Two: {joint.occurrenceTwo.name} {joint.geometryOrOriginTwo.origin.asArray()}")

            print('-')
            ori1, ori2 = getJointOriginWorldCoordinates(joint)
            print(f"Joint One-Root: {joint.occurrenceOne.name} {ori1.asArray()}")
            print(f"Joint Two-Root: {joint.occurrenceTwo.name} {ori2.asArray()}")
            print('---')

    except:
        print('Failed:\n{}'.format(traceback.format_exc()))


def getJointOriginWorldCoordinates(joint :adsk.fusion.Joint):

    def getMatrixFromRoot(root_occ) -> adsk.core.Matrix3D:
        mat = adsk.core.Matrix3D.create()

        occ = adsk.fusion.Occurrence.cast(root_occ)
        if not occ:
            return mat # root

        des = adsk.fusion.Design.cast(occ.component.parentDesign)
        root = des.rootComponent

        occ_names = occ.fullPathName.split('+')
        occs = [root.allOccurrences.itemByName(name)
                    for name in occ_names]
        mat3ds = [occ.transform for occ in occs]
        mat3ds.reverse()
        for mat3d in mat3ds:
            mat.transformBy(mat3d)
        return mat

    mat :adsk.core.Matrix3D = getMatrixFromRoot(joint.occurrenceOne)
    ori1 :adsk.core.Point3D = joint.geometryOrOriginOne.origin.copy()
    ori1.transformBy(mat)

    mat = getMatrixFromRoot(joint.occurrenceTwo)
    ori2 :adsk.core.Point3D = joint.geometryOrOriginTwo.origin.copy()
    ori2.transformBy(mat)

    return ori1, ori2

This is the result.

Rev2
Joint One: Component4:1 (0.0, 10.0, 10.0)
Joint Two: Component2:1 (0.0, 10.0, 5.0)
-
Joint One-Root: Component4:1 (-15.0, 10.0, 15.0)
Joint Two-Root: Component2:1 (0.0, 10.0, 5.0)
---
Rev3
Joint One: Component5:1 (12.5, -10.0, 5.0)
Joint Two: Component4:1 (12.5, 7.5, 5.0)
-
Joint One-Root: Component5:1 (-2.5, 7.5, 10.0)
Joint Two-Root: Component4:1 (-2.5, 7.5, 10.0)
---
Rev4
Joint One: Component6:1 (-2.5, 2.5, -5.0)
Joint Two: Quader:1 (2.5, -2.5, 5.0)
-
Joint One-Root: Component6:1 (2.5, -2.5, 5.0)
Joint Two-Root: Quader:1 (2.5, -2.5, 5.0)
---

 

The geometryOrOriginTwo.origin reflects the Occurrence transform.
I got the correct values for "Rev3" and "Rev4", but not for "Rev2".

 

I found out that the reason is that it does not reflect the value of "Joint Alignment".

(Since I can't attach images, I'll attach the files.)

However, I could not figure out how to find the "offset X" and "offset Y" model parameters in the Joint object.

 

 

Message 3 of 7
Anonymous
in reply to: spacemaster85

Hi @spacemaster85,
I've used joints for a while now, but never had your issue. In my cases the originOne and originTwo are everytime at the exact same point, so I only used the originOne.origin.
Maybe there occurs an issue while creating these boxes, how did you create them, and in wich order?
To use the joints properly, you need to ground at least one component in a "joint-chain", but you left the grounding for demo reasons I think.

I found out that when you create a box with the box-feature and copy-paste this box, Fusion gets confused when you use the copies for joints. So Fusion takes as joint-Origin only the origin of the original-box, even when you created the origins manually on the copied boxes.

Message 4 of 7
spacemaster85
in reply to: kandennti

Thank you very much for your solution. It works well!

The offset is indeed still a problem, but for my actual work not relevant. I will ignore it for now and maybe come back  later to the offset topic.

Message 5 of 7
spacemaster85
in reply to: Anonymous

Hi @Anonymous 

thank you for your answer!

I guess that in my case OriginOne and OriginTwo are different because I set an offset for this particular joint.

 

Message 6 of 7

Thank you again for your great help.

With your help I was able to finish my work and would like to share it with you.

 

On https://github.com/SpaceMaster85/fusion2urdf you find an improved version of the script of syuntoku14

which can export robot models from Fusion 360 to URDF (ROS).

The new and improved features are listed in the README.

 

Thank you for your help!

 

Message 7 of 7

When you have several sub components with the same name it could be that the calculation for the joint origin in the world frame is wrong. 

The updated code is using now the assembly context to calculate the transformation matrix and not the path and component names.

 

You can find the code below:

def getJointOriginWorldCoordinates(joint :adsk.fusion.Joint):
    def getMatrixFromRoot(root_occ) -> adsk.core.Matrix3D:
        mat = adsk.core.Matrix3D.create()
        occ = adsk.fusion.Occurrence.cast(root_occ)
        if not occ:
            return mat # root
        def getParentOccs(joint):
            occs_list = []

            if joint != None:    
                occs_list.append(joint)
 
            if joint.assemblyContext != None:
                occs_list = occs_list + getParentOccs(joint.assemblyContext)

            return occs_list
        
        occs = getParentOccs(root_occ)
        mat3ds = [occ.transform for occ in occs if occ!= None]
 
        for mat3d in mat3ds:
            mat.transformBy(mat3d)
        return mat
    mat :adsk.core.Matrix3D = getMatrixFromRoot(joint.occurrenceOne)
    ori1 :adsk.core.Point3D = joint.geometryOrOriginOne.origin.copy()
    ori1.transformBy(mat)
    mat = getMatrixFromRoot(joint.occurrenceTwo)
    ori2 :adsk.core.Point3D = joint.geometryOrOriginTwo.origin.copy()
    ori2.transformBy(mat)
    return ori1, ori2 
    

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Technology Administrators


Autodesk Design & Make Report