Joints, where are you?

Joints, where are you?

RogerInHawaii
Collaborator Collaborator
2,117 Views
15 Replies
Message 1 of 16

Joints, where are you?

RogerInHawaii
Collaborator
Collaborator

I've expanded on the sample program (provided by Fusion 360) that traverses the model assembly so that it not only lists the Occurrences but also lists the various Bodies and Joints for each Occurrence. In addition, I made it so that it also lists those items for the Root Component. It works fairly well, but I've noticed something odd. When I display the hierarchical list that I've generated with a Message Box most all of the items line up quite nicely with what I see in the browser. Except for one item, the Joint. I have a Revolute Joint named "Rev Joint under root component" that appears within the Joint section of the Root in the Browser, but in my created hierarchical list it shows up as being under my Component6.

joints list.jpg

For each of the various Occurrences (which is what most of the objects that we refer to as Components actually are) I pick up the JointList thusly...

Ptr<JointList> JointsList = ThisOccurrence->joints();

and go through the list.

For the RootComponent, which is NOT an Occurrence object but has much of the same structure, I pick up the JointList similarly, but referencing the RootComponent...

Ptr<JointList> RootComponentJointsList = RootComponent->joints();

And I process each such JointsList the same way.

I would expect that the JointsList that shows up directly beneath the Root Component in the Browser would be the same JointsList that I pick up in my Script and should therefore show up beneath the root component in the hierarchical list that I generate. But it doesn't. Instead, that Joint that seems to be under the Root Component is under my Component6.

Why is it different between what I see in the browser and what I find in the actual hierarchical structure of the RootComponent and its Occurrences?

2,118 Views
15 Replies
Replies (15)
Message 2 of 16

Anonymous
Not applicable

hawaii joints.PNG

 

 

 

 

joints reference.PNG

0 Likes
Message 3 of 16

RogerInHawaii
Collaborator
Collaborator

My question is not about how to access the joint parameter of a Component, it's why a Joint will appear directly under the ROOT component in the browser window but when you traverse the hierarchy yourself it appears somewhere else, under a different object.

0 Likes
Message 4 of 16

Anonymous
Not applicable

In Fusion 360 a joint: eg. "myJoint" is created between two objects: A and B.

 

A and B can be two occurrences or an occurrence and the (root)component.

 

When you traverse the hierarchy then "myJoint" will be shown at least twice because it belongs to A and to B.

 

This is the reason why you can see your revolute joint under "Component6" (whis is an occurrence in API terms). Lets say this is object A.

 

The revolute joint should also be listed under your root-component (object B).  I assume you created the joint between the root-component and Component6 - because no other occurrence lists this joint.

 

The reason why it is not listed under the root-component is what I tried to show in my previous message:

If you want to extract the joints of the root-component, you have to use Ptr<Joints> as return type, not Ptr<JointList> (which will result in a nullptr). 

 

Edit/addendum:

I forgot to mention. If you create a joint between two occurrences (A,B) located in the root-component, the joint-name appears three time on hierarchy-traversal (root-component, A, B).

 

0 Likes
Message 5 of 16

Anonymous
Not applicable

Here is an example:

joint "Rigid-root-Component1" is created between root and Component1

joint "Rigid-Component2-Component1" is created between Component2 and Component1

 

The browser shows this:

RogerInHawaii browser.PNG

 

Your API traversal should show

 

two joints under root-component

  • "Rigid-root-Component1"
  • "Rigid-Component2-Component1"

 

two joints under the occurrence "Component1"

  • "Rigid-root-Component1"
  • "Rigid-Component2-Component1"

 

one joint under the occurrence "Component2"

  • Rigid-Component2-Component1"

 

 

0 Likes
Message 6 of 16

RogerInHawaii
Collaborator
Collaborator

I really appreciate that you've taken the time to explain how this all works.

So,

 

AnOccurrence->joints is of type JointList

 

but

 

TheRootComponent->joints is of type Joints.

 

Two identically named items but two different types. That's, well, kinda confusing.

 

I had defined my method that handles the list of joints as expecting a JointList parameter, ...

 

MyJointsProcessingMethod(Ptr<JointList> TheJointsList)

 

and it works fine for passing in the JointList that I can retrieve from an Occurrence but clearly does not work if I pass it a Joints object acquired from the root component.

 

Do I really need a separate method to handle the root component's list of Joints in addition to my method to handle JointLists from Occurrences, or is there a way to cast from JointList to Joints or something like that?

0 Likes
Message 7 of 16

RogerInHawaii
Collaborator
Collaborator

More confusion. Here's some code I added to traverse the Joints object acquired from the root component..

Ptr<Joints> RootComponentJointsList = RootComponent->joints();
Ptr<Joint> ARootJoint;

if (RootComponentJointsList)
{
	ui->messagebox("We have a joints object for the Root Component");
	if (RootComponentJointsList->count() > 0)
	{
		ui->messagebox("Root Joint List has some items\n";
		for (int i = 0; i < RootComponentJointsList->count(); ++i)
		{
			ARootJoint = RootComponentJointsList->item(i);
			resultString += "FOUND ROOT JOINT: " + ARootJoint->name() + "\n";
		}
	}
	else
	{
		ui->messagebox("Root Joint List has NO items\n";
	}
}

 And here's what the browser looks like for the project that I'm applying the script to. As you can see there are several Joints at the root, and NONE for any of the other components (occurrences).

Component joint problem 1.jpg
When I run the script and it goes through the section of code where I'm trying to look through the set of Joints for the Root, it finds none. That Joints object for the root exists, but it's empty. The message box that pops up says, "Root Joint List has NO items".



 

0 Likes
Message 8 of 16

RogerInHawaii
Collaborator
Collaborator

I also tried picking up the AllJoints property of the Root Component and iterating through that...

std::vector<Ptr<Joint>> AllJoints = RootComponent->allJoints();
resultString += "AllJoints from RootComponent " + RootComponent->name() + " has " + std::to_string(AllJoints.size()) + " entries.\n";
Ptr<Joint> ARootJoint;
for (std::size_t i = 0; i < AllJoints.size(); ++i)
{
	ARootJoint = AllJoints[i];
	resultString += "FOUND ROOT JOINT: " + ARootJoint->name() + "\n";
}

and all that did was show that there's nothing in the AllJoints vector, even though the Browser still shows that there are Joints beneath the Root Component. There are NO joints found anywhere in the hierarchy, not even beneath the Occurrences.

Component joint problem 2.jpg

 

So I'm pretty much at a loss as to how to actually acquire access to those joints that are listed as being part of the root component.

0 Likes
Message 9 of 16

RogerInHawaii
Collaborator
Collaborator

More attempts. I tried accessing the joints  through both the joints() property as well as the allJoints() property of the root component and I get DIFFERENT results depending on which CAD model it's referencing. In one case it finds a different number of joints depending on whether it's accessing them  through Joints() or allJoints() and in the other case it finds the SAME set of joints via either property. It SEEMS that maybe it's a difference in the KINDs of joints that are in each property, since in one case it seems to miss the Revolute joint.

I'm just very confused.

Joints B.jpgjoints list A.jpg

 

joints C.jpg

0 Likes
Message 10 of 16

RogerInHawaii
Collaborator
Collaborator

I know that my Script is indeed finding Joints for SOME of my CAD models. Sometimes it's finding all of them in both the joints() and the allJoints() properties of the root component but sometimes not.

The WORST case is in the CAD model that I'm most interested in accessing a specific joint so that I can, via the script, manipulate the joint, but in that CAD model NEITHER the joints() nor the allJoints() properties of the root component contain the joint. In fact, they contain NO JOINTS, in spite of the fact that the Browser clearly shows the joints and I can MANUALLY move the joints in the display window.

joints D.jpg

0 Likes
Message 11 of 16

BrianEkins
Mentor
Mentor

I can't guarantee that I'll get a chance to look at it, but can you post your model here?  I am curious about this and that's not the behavior I would expect. 

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
0 Likes
Message 12 of 16

Anonymous
Not applicable

@RogerInHawaii wrote:

More confusion. Here's some code I added to traverse the Joints object acquired from the root component..

....

......

When I run the script and it goes through the section of code where I'm trying to look through the set of Joints for the Root, it finds none. That Joints object for the root exists, but it's empty. The message box that pops up says, "Root Joint List has NO items".



 


I am even more confused now. How did you get your posted script code running? Big mystery for me.

 

Here is why.

 

When I copy your code into Visual Studio then I get errors (no surprise) and as a consequence, Visual Studio is not able to create a new Build (no surprise).

 

Here are the Visual Studio screenshots:

First error: ui->messagebox() should be =>  ui->messageBox()

messageBox.PNG

 

 

Second error: missing end bracket

 

bracket.PNG

 

If I correct the mistakes, then the script works as expected:

 

we have joints in root.PNG

 

root list has items.PNG

 

 

 

If you got the posted script running, then your IDE/Compiler is doing miracles. But then it´s difficult to support you because I just have an ordinary Visual Studio IDE.

 

Maybe you can solve this mystery - I´m really curious.

0 Likes
Message 13 of 16

Anonymous
Not applicable

@RogerInHawaii wrote:

I know that my Script is indeed finding Joints for SOME of my CAD models. Sometimes it's finding all of them in both the joints() and the allJoints() properties of the root component but sometimes not.

The WORST case is in the CAD model that I'm most interested in accessing a specific joint so that I can, via the script, manipulate the joint, but in that CAD model NEITHER the joints() nor the allJoints() properties of the root component contain the joint. In fact, they contain NO JOINTS, in spite of the fact that the Browser clearly shows the joints and I can MANUALLY move the joints in the display window.

.......

........

 


BTW - only an idea: can you confirm that all the joints in your designs are of the "Joint" type? Maybe there are also one or more "As-Built Joints" in the designs?

 

You are not able to visually determine the different joint types in the browser. They look the same. You only can find out if you click on the joint, then press the right-mouse-button.

 

In the API these are different objects:

 

Component Properties:

 

joints.PNG

 

as-built joints.PNG

 

 

So if you extract only "joints", then "asBuiltJoints" are missing in your list.

0 Likes
Message 14 of 16

RogerInHawaii
Collaborator
Collaborator

Let me start off by saying that I DO APPRECIATE all the responses and help that everyone has provided.

THANK YOU !

OK, so I added a section of code to ALSO traverse the AsBuiltJoints property of the root component and, lo and behold, my Joints show up in THAT property. See the pic at the end of this post.

But this has been frustrating. One would reasonably think that RootComponent->allJoints() would indeed list ALL JOINTS, especially since its description in the API defines it as a flat listing of "all joints throughout the project". It was stated in one of the responses to my original post that AsBuiltJoints are somehow different from just regular Joints. But, man, from a user interface standpoint it appears that the AsBuiltJoint tool merely provides a different METHOD of creating a Joint, not an actually different KIND of joint, especially since, with the AsBuiltJoint tool you can still specify the kind of joint (Rigid, Revolute, etc.) AND they appear identical in the Browser.

At the very least the description of AllJoints should make it very clear, both in the API documentation as well as in the Example code, that it only includes Joint objects and explicitly EXCLUDES AsBuiltJoints, and that if you really want to access all the joints in your project that you need to traverse both of those Root Component properties. It should also explain the difference in the Joint and AsBuiltJoint class descriptions in the API.

 

It's also frustrating that the joints property in an Occurrence is DIFFERENT from a joints property in a Component.  They traverse the same type of thing, but they use different classes for the traversal. If the properties have the same name, they really ought to use the same TYPE of list.

And since there's also an allAsBuiltJoints property for Occurrences, it means I also have to traverse THAT separate list in order to actually find "all joints".

I also notice that for a JointList (available via an Occurrence) there is an itemByName() method that lets you easily find a Joint just by its name, without having to go searching through the entire sequence of joints. That's very helpful. BUT, for a Component (i.e. the Root Component), even though it has a list of Joints (NOT a JointList type), there is no such ByName() method. Which means that for that kind of list I have to sequence through one-by-one to find the one with the name that I'm seeking.

All in all, a very frustrating situation. And I'm still not quite clear on what the difference is between the RootComponent->joints() and the RootComponent->allJoint() properties.

And one final observation: My Root Component for my model also shows a couple of Motion Link objects, yet, in my Script, for my Root Component, there is no property for a Component that is a list of Motion Links. If I actually wanted to recreate the entire set of things that are in the Browser, or wanted to be able to find a given Motion Link via my code, where do I find the list of Motion Links? 

And let me state again: I DO APPRECIATE all the responses and help that everyone has provided.

joints E.jpg

Message 15 of 16

Anonymous
Not applicable

My pleasure. I'm glad you could identify all the joints. Congratulations!

 

As far as I know, the API has no functions for motion-links. Maybe @BrianEkins can say more about it.

 

The Joints object also has an itemByName method:

 

joints itemByName.PNG

0 Likes
Message 16 of 16

RogerInHawaii
Collaborator
Collaborator

The whole purpose of being able o get access to these joints is for a robot hand I'm trying to develop and simulate within Fusion 360. After all your help, I was finally able to do that and actually manipulate the finger part of the hand using a script. And it now works!!!

You should be able to see it here: https://www.facebook.com/rogerinhawaii/videos/10213951033677656/