gumyr / build123d

A python CAD programming library
Apache License 2.0
432 stars 81 forks source link

Update child part positions when parent Joint position is changed #151

Open gumyr opened 1 year ago

gumyr commented 1 year ago

When many joints are used to connect many parts together, it should be possible to update a joint position and have the parts connected to this joint reposition themselves. For example, an industrial robot with many segment rotates its base - all the other parts should move appropriately.

bernhard-42 commented 1 year ago

I would say that this is a feature for hierarchical assemblies. It is exactly how cadquery-massembly works today. Each partgroup at each level of the assembly hierarchy has its own location, By changing a partgroups location, the whole subtree moves/rotates. Hexapod works like that. When you rotate the upper leg around the base, the lower leg follows, since the lower leg is hierarchically below the upper leg.

The question is, whether we could introduce a function "assemble" that works similar to "connect", but creates and assembly instead of a compound?

gumyr commented 1 year ago

I've been thinking about the overlap in functionality between connected joints and assemblies. The connect_to method could also be building an assembly by assigning children/parent; however, it would have to be working with a Compound to start with or even "upgrade" the Shape to a Compound.

What if there was an option to connect_to to flag that an assembly should be built? Should building an assembly be fully automatic?

bernhard-42 commented 1 year ago

I don't think we need a separate method, a flag would be good.

What do you mean with "automatic"?

Another task that assembly building would need to do if we want to move parts and hierarchies is to relocate every object in the hierarchy so that its origin and rotation is aligned with the joint around which it has its dof. Because then rotate about z or move y units in joint direction could be given in local coords (i.e. in joint degrees or units relative to the hierarchy it wants to move) which is very intuitive

Jojain commented 1 year ago

In traditionnal CAD softwares assemblies and mecanism are separate concepts while being very related. The assembly definition would be:

The mechanism definition would be :

So the two concepts are quite similar but the assembly focuses on the positionning of parts in a rigid manner (for a specific configuration how would look like my assembly when not moving) while the mechanism focuses on kinematics (of my parts moves together, given the constrain of their joints).

Currently in B123D joints are closer to creating a mechanism than an assembly (in the traditional meaning). That being said it's totally possible to make b123d joints behave as constraints to define an assembly. We would have then only one concept for both which is fine IMO. That would make b123d assemblies more representative of the reality.

gumyr commented 1 year ago

By "automatic" I mean then when a user enters Solid_1.connect_to(Solid_2, ...):

  1. Solid_1 is converted to a Compound e.g. Compound_1
  2. Solid_2 is relocated relative to Compound_1
  3. Compound_1 is assigned as Solid_2's parent (i.e. creating an assembly)

As this impacts Solid_1 a flag allowing user control of this behaviour seems appropriate.

Another task that assembly building would need to do if we want to move parts and hierarchies is to relocate every object in the hierarchy so that its origin and rotation is aligned with the joint around which it has its dof. Because then rotate about z or move y units in joint direction could be given in local coords (i.e. in joint degrees or units relative to the hierarchy it wants to move) which is very intuitive

I believe that just re-evaluating the connect_to of each child part/joint would achieve this.

bernhard-42 commented 1 year ago

Understood. Without automation the difference of an "atomic" object (i.e. Solid) and a fused/cut object (i.e. Compound) needs to be understood. It is the difference between assembly = Compound(solid).connect_to ... and assembly = compound.connect_to ....

I believe that just re-evaluating the connect_to of each child part/joint would achieve this.

Not sure I understand the implication of your described step. Let me explain what I did in MAssembly and then you can see whether we actually mean the same. In MAssembly this is the location handling:

This approach ensures that when you rotate an object e.g. around the z-axis, all objects below in the sub hierarchy automatically follow that movement. They are actually grouped together. threejs has implemented the exact same approach, btw.

Note that the relocation step (the second bullet) to the primary mate is only needed when you plan to animate the assembly along the mates/joints. Without animation, this step can be omitted.

It would be great if build123d would already add this step for future animation needs.