assembly without solver

Discussion about the development of the Assembly workbench.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Mark Szlazak
Posts: 439
Joined: Tue Apr 04, 2017 6:06 pm
Location: SF Bay Area, California

Re: assembly without solver

Post by Mark Szlazak »

NormandC wrote: Tue Jan 01, 2019 4:44 pm
Zolko wrote: Mon Dec 31, 2018 11:18 am No, at the beginning of a project, parts are not yet made, you only have a vague idea how all the — future — parts are going to fit together. This means that a project always begins with the master assembly, containing some datum objects, functional sketches, and allowed volumes.
Uh... No. Maybe that's the "proper" way of doing it for complex projects, but it most definitely not always begins that way. At work, we often create small assemblies for which we have already figured out the parts, therefore we don't need to start with a master assembly.

Zolko wrote: Mon Dec 31, 2018 11:18 am all high-end CAD systems provide the functionality we're talking about (mating of pairs of LCS): Catia V5, SolidWorks, Siemens NX, T-Flex....
Solidworks is not a high-end CAD system, it's mid-range.
What Zolko says is in the advance classes of both Creo and Solidworks. These classes look more into "top-down" design than beginner courses. Having these features may help with bringing FreeCAD into college classes.
User avatar
Zolko
Veteran
Posts: 2213
Joined: Mon Dec 17, 2018 10:02 am

Re: assembly without solver

Post by Zolko »

NormandC wrote: Tue Jan 01, 2019 4:44 pm At work, we often create small assemblies for which we have already figured out the parts, therefore we don't need to start with a master assembly.
...
Solidworks is not a high-end CAD system, it's mid-range.
These are actually very important remarks: what are we aiming at ? What's the goal for FreeCAD ? Is the purpose to make a nice CAD system for single-person use to assemble 10 parts and show-off the screenshots in a gallery, or is the purpose to go after the heavy-lifters and propose a system that can take on hard-core engineering for an army of development engineers ?

I'll be very clear: my idea is (was ?) to be as good as the best that's out there, and getting inspiration from other open-source successes that are the Linux kernel, Apache, Python, MySQL, OpenOffice, LaTeX ... therefore no half-baked assembly workbench is going to fit my needs: if it can't handle an entire Airbus it's not good enough. And you don't assemble an Airbus with zillions of constraints, it's done by proper interfaces and LCS.
try the Assembly4 workbench for FreCAD — tutorials here and here
User avatar
Zolko
Veteran
Posts: 2213
Joined: Mon Dec 17, 2018 10:02 am

Re: assembly without solver

Post by Zolko »

realthunder wrote: Mon Dec 31, 2018 12:06 am If you actually try to code your idea of a LCS only assembly, you'll soon find yourself in trouble with dependency mess. If you walk through the chain of LCS pairs, you'll find loops in very simple assemblies.
Zolko wrote: Sun Dec 30, 2018 1:54 pm
In fact, FreeCAD's AttachEngine is used for this purpose.
Supposed, for example, that I have an assembly, a part, each having 2 LCS, and I want to attach — using your App::Link framework — the part by one of its LCS to the assembly, twice, once on each LCS. Would it be possible to do it today ?
That's how PartDesign body builds on, attaching sketch to existing body feature, and then create new feature. It works well because the body is supposed to produce fixed geometries, and you are actually building those geometries along the way, whereas in assembly, the parts are already built, possibly from different people. AttachEgnine are in src/Mod/Part/App/Attacher.h/cpp.
Soooooooooooooo ............ "show me the code", as a famous kernel maintainer once said. I did actually code my assembly: one Part with 3 LCS, and one Assembly with 7 LCS, and the Part is inserted 6 times on 6 LCS of the assembly, attached at one of its 3 LCS (of the part). It is surprisingly easy, once you know how to do it, and I think that the assembly workbench without solver is not that far away. I used my own compiled FreeCAD from the LinkStage3 branch by realthunder, and I'v also tested the result with the AppImage he has provided.

I first created a Part in PartDesign, with 3 LCS (the thig was to make it assymetric) :
Part+LCS_0.png
Part+LCS_0.png (175.82 KiB) Viewed 3466 times

It's important that the LCS are in the Body container, or else they are not "mounted" during lining.

Then an Assembly, with a sketch having a hexagon, and 6 LCS at each corner, using different MapModes (translation, OXY, OYZ...) :
Assembly+Sketch.png
Assembly+Sketch.png (162.01 KiB) Viewed 3466 times

It's all parametric of course: if you modify the hexagon, the LCS all move with it as they should. I then inserted an App::Link, assigned the correct Document:

Code: Select all

App.getDocument('Assembly').addObject('App::Link','Part_1')
FreeCAD.getDocument("Assembly").getObject("Part_1").LinkedObject = (App.getDocument('Part').getObject('Body'),'')
...and here comes the magic: you can place the linked part where the (target) LCS in the assembly is, and multiplying it by the inverse of the placement where the (attachment) LCS is in the part:

Code: Select all

App.getDocument("Assembly").Part_1.Placement = App.getDocument("Assembly").LCS_1.Placement.multiply( App.getDocument("Part").LCS_1.Placement.inverse() )
The first LCS_1 is the target LCS in the Assembly, the second LCS_1 is the attachment LCS in the Part (yes, I realized later that I could have chosen better names, sorry, but you get the thing). And you do that for all 6 links:

Code: Select all

App.getDocument("Assembly").Part_1.Placement = App.getDocument("Assembly").LCS_1.Placement.multiply( App.getDocument("Part").LCS_1.Placement.inverse() )
App.getDocument("Assembly").Part_2.Placement = App.getDocument("Assembly").LCS_2.Placement.multiply( App.getDocument("Part").LCS_1.Placement.inverse() )
App.getDocument("Assembly").Part_3.Placement = App.getDocument("Assembly").LCS_3.Placement.multiply( App.getDocument("Part").LCS_2.Placement.inverse() )
App.getDocument("Assembly").Part_4.Placement = App.getDocument("Assembly").LCS_4.Placement.multiply( App.getDocument("Part").LCS_0.Placement.inverse() )
App.getDocument("Assembly").Part_5.Placement = App.getDocument("Assembly").LCS_5.Placement.multiply( App.getDocument("Part").LCS_1.Placement.inverse() )
App.getDocument("Assembly").Part_6.Placement = App.getDocument("Assembly").LCS_6.Placement.multiply( App.getDocument("Part").LCS_2.Placement.inverse() )
And all 6 Parts are placed where they should be:
Assembly+Parts.png
Assembly+Parts.png (198.12 KiB) Viewed 3466 times

You can see that for Part_3 attached to LCS_3, the LCS are perfectly aligned:
Part_3+LCS.png
Part_3+LCS.png (169.81 KiB) Viewed 3466 times

I've done the same thing in SolidWorks to cross-check:
Assembly_SolidWorks.png
Assembly_SolidWorks.png (290.7 KiB) Viewed 3466 times

So what's the catch ? Well, the Parts (the Links) are placed by Placement, not by attachment, therefore when I change the size of the hexagon, the LCS all follow (because they are placed by attachment) but the parts remain where they have been placed. I need to re-run the placement commands to have them get to their new/correct position.

(I can't attach the FreeCAD files I used for this, I'll do it in another post) The Part weights 32kB, and the Assembly 13kB.
Last edited by Zolko on Fri Jan 04, 2019 10:33 am, edited 1 time in total.
try the Assembly4 workbench for FreCAD — tutorials here and here
User avatar
Zolko
Veteran
Posts: 2213
Joined: Mon Dec 17, 2018 10:02 am

Re: assembly without solver

Post by Zolko »

And here are the files. Works only with the App::Link version of FreeCAD.
Attachments
Part.FCStd
(32.82 KiB) Downloaded 78 times
Assembly.FCStd
(13.53 KiB) Downloaded 97 times
try the Assembly4 workbench for FreCAD — tutorials here and here
realthunder
Veteran
Posts: 2190
Joined: Tue Jan 03, 2017 10:55 am

Re: assembly without solver

Post by realthunder »

Zolko wrote: Thu Jan 03, 2019 11:23 pm So what's the catch ? Well, the Parts (the Links) are placed by Placement, not by attachment, therefore when I change the size of the hexagon, the LCS all follow (because they are placed by attachment) but the parts remain where they have been placed. I need to re-run the placement commands to have them get to their new/correct position.
There is another catch. Each attachment completely fixes the corresponding LCS, and therefore the attached part as well. Like I said, if each part has only one constraint, you can do it with the existing attach engine. But what if there are more constraints? What if two parts has an angle requirement between each other? How do you imagine to code the attach engine? It ceases to be a "Local" solver, because it has to consider requirements outside of its coordinate system. That is exactly what a proper solver does.
Zolko wrote: Mon Dec 17, 2018 7:27 pm
Zolko wrote: Later, it should be possible to define degrees of freedom in the LCS and develop constraints to solve them (for example you can leave the rotation around an axis free, or a translation...). The number of degrees of freedom would be limited to those expressly authorised, thus the solver much simpler than having to solve all 6 degrees of freedom for all parts. This can be implemented at a later stage to provide a full assembly functionality that wouldn't lag the leading CAD systems.
I said "later", meaning that doing assembly like I propose is not a dead end, it can later evolve to something more sophisticated, even if it begins very simple. I tried to anticipate remarks.
I highly double it can somehow "evolve" like you casually described. Once you introduced any non-fixed degree of freedom, it requires a non-local solver, which takes an almost completely different approach. On the other hand, a proper solver can easily handle hundreds and thousands of isolated LCS. And a more advanced solver will try to identify isolated LCS that are difficult to do manually.


That being said, with the proper solver, you still need a way for user to define LCS to constrain up on. You can ask the user to explicitly define the coordinate system, or just let them select a face and use its position and orientation. Does that really matter? You can do both in A3.
Try Assembly3 with my custom build of FreeCAD at here.
And if you'd like to show your support, you can donate through patreon, liberapay, or paypal
User avatar
Zolko
Veteran
Posts: 2213
Joined: Mon Dec 17, 2018 10:02 am

Re: assembly without solver

Post by Zolko »

realthunder wrote: Fri Jan 04, 2019 1:26 am Each attachment completely fixes the corresponding LCS, and therefore the attached part as well.
Not sure to understand: the LCS are defined in a parametric way, you can move them them around. These are functional LCS, in the sense that they define a function (rotation axis, translation direction, fixation point ...) therefore they move with the function.

What is missing in my example is a third Placement, that would move the Part in the Assembly relative to its target LCS. So there are 3 information that are needed for each part:
  • the ID or name of the attachment LCS (in the Part)
  • the ID or name of the target LCS (in the Assembly)
  • an optional additional App::Placement of the attachment LCS relative to the target LCS
Like I said, if each part has only one constraint, you can do it with the existing attach engine.
App::Part and App::Link don't seem to obey to the attachment engine, or at least I didn't succeed in doing so. Could you please explain what you mean ?

But what if there are more constraints? What if two parts has an angle requirement between each other? How do you imagine to code the attach engine?
What would prevent you from defining 2 LCS, with the specified angle between them ?

Zolko wrote: Mon Dec 17, 2018 7:27 pm
Zolko wrote: Later, it should be possible to define degrees of freedom in the LCS and develop constraints to solve them (for example you can leave the rotation around an axis free, or a translation...). The number of degrees of freedom would be limited to those expressly authorised, thus the solver much simpler than having to solve all 6 degrees of freedom for all parts. This can be implemented at a later stage to provide a full assembly functionality that wouldn't lag the leading CAD systems.
I said "later", meaning that doing assembly like I propose is not a dead end, it can later evolve to something more sophisticated, even if it begins very simple. I tried to anticipate remarks.
I highly double it can somehow "evolve" like you casually described.
It's certainly non-trivial, I agree.

You can ask the user to explicitly define the coordinate system, or just let them select a face and use its position and orientation. Does that really matter? You can do both in A3.
It matters if no face is present. Or if you don't know "how" a part is fixed, only "where". For example — and this is a real-world example — we have to fix optics, and for that opticians make the optical design, then give us the output in STEP format, and we have to make mechanics around to hold everything together. The first step is to import the STEP file, with the optics floating around, with other external things (bench, motor, feet, cables...), check that every-thing fits, and if not give feed-back to the opticians how they have to modify their design to fit into the allowed space-envelope. We don't begin mechanical design before that frist step is more-or-less done, we only do the assembly, but there is no geometry which can be used for constraints, only datum objects. What's more, optics have weird shapes, we don't use geometrical solvers to determine the tangent on an aspheric lens for example, or on an ellipsoid mirror, we place it with its centre, and design the mechanics around it.

As for A3, can-you use LCS to assemble parts ? When I create an assembly in A3, I can't insert a datum plane into it, I first have to create a body, but that body is created outside the assembly.

EDIT: ah, actually it's possible to insert a datum plane in an assembly, but when drawing a sketch on that plane the sketch gets put outside the assembly. So my remark remains identical.

So I guess I'd have to first create a Part, make a body, create the reference datums there and insert that body as first element of the assembly, fixed, and assemble everything to that, right ? That's how Catia V5 works, and it's absolute crap, please don't copy that behaviour, its ages behind more advanced CAD systems (Catia V5 is a 20 year old design ! Shouldn't be taken as example for a new CAD system). NX does it mostly right, and in NX there is no difference between a Part and an Assembly.
try the Assembly4 workbench for FreCAD — tutorials here and here
realthunder
Veteran
Posts: 2190
Joined: Tue Jan 03, 2017 10:55 am

Re: assembly without solver

Post by realthunder »

Zolko wrote: Fri Jan 04, 2019 9:55 am Not sure to understand: the LCS are defined in a parametric way, you can move them them around. These are functional LCS, in the sense that they define a function (rotation axis, translation direction, fixation point ...) therefore they move with the function.
The attach engine defines a transformation of two coordinates. It contains everything it needs to fully determine that transformation. But what if you want to leave some degree of freedom? Say the user wants two faces of two parts to be perpendicular with each other. The attach engine of neither part can fully determine a transformation now, it has to check the other part's attachment to see if the transformation is valid. I don't think it can be considered "local" in this case. You need a higher order solver to oversee both LCS.

What is missing in my example is a third Placement, that would move the Part in the Assembly relative to its target LCS. So there are 3 information that are needed for each part:
  • the ID or name of the attachment LCS (in the Part)
  • the ID or name of the target LCS (in the Assembly)
  • an optional additional App::Placement of the attachment LCS relative to the target LCS
Like I said, if each part has only one constraint, you can do it with the existing attach engine.
App::Part and App::Link don't seem to obey to the attachment engine, or at least I didn't succeed in doing so. Could you please explain what you mean ?
No, attach engine does not support App::Part and App::Link directly. What you did is exactly the missing piece. If you'd like to explore more about my branch, you can try the enhanced expression engine. Select Part_1 in the assembly, right click in the property view, and select "Show all". Then, right click in Placement field, and select "Expression...". Finally, enter the following expression,

Code: Select all

LCS_1.Placement.multiply(.<<LCS_1.>>.Placement.inverse())
The first "LCS_1" refers to the LCS_1 object in the assembly document. The second LCS_1 in that special syntax is refer the sub object of this current object (i.e. Part_1). Now you can move LCS_1 in the assembly, and the part will automatically follow it. You can find more details here. With the new enhanced expression engine and spreadsheet, you can in fact code an entire attach engine with them.

What would prevent you from defining 2 LCS, with the specified angle between them ?
What I mean is that the two parts is still attached to the original LCS, but has an additional angle requirement between them. If you change the second LCS to be attached to the first LCS, of course there is no problem, because the part still has only one constraint. In fact, even with the additional angle requirement, you can still write code or expressions to handle it without the attach engine. But it is not systematic, and will quickly go out of control with a few inter constrained parts. My point is that it requires a non-local solver, which takes a different approach in order to be efficient.

So I guess I'd have to first create a Part, make a body, create the reference datums there and insert that body as first element of the assembly, fixed, and assemble everything to that, right ? That's how Catia V5 works, and it's absolute crap, please don't copy that behaviour, its ages behind more advanced CAD systems (Catia V5 is a 20 year old design ! Shouldn't be taken as example for a new CAD system). NX does it mostly right, and in NX there is no difference between a Part and an Assembly.
There is no fixed workflow in A3. And there is no difference between assembly and part either. You add any object inside an assembly, and that object is treated as a part. There is currently no concept of an "Active Assembly", similar to an "Active Body", where new Pad, Pocket and stuff gets automatically added to the active body. For now, you need to manually add objects into the assembly.
Try Assembly3 with my custom build of FreeCAD at here.
And if you'd like to show your support, you can donate through patreon, liberapay, or paypal
User avatar
saso
Veteran
Posts: 1920
Joined: Fri May 16, 2014 1:14 pm
Contact:

Re: assembly without solver

Post by saso »

Zolko wrote: Thu Jan 03, 2019 5:54 pm These are actually very important remarks: what are we aiming at ? What's the goal for FreeCAD ? Is the purpose to make a nice CAD system for single-person use to assemble 10 parts and show-off the screenshots in a gallery, or is the purpose to go after the heavy-lifters and propose a system that can take on hard-core engineering for an army of development engineers ?

I'll be very clear: my idea is (was ?) to be as good as the best that's out there, and getting inspiration from other open-source successes that are the Linux kernel, Apache, Python, MySQL, OpenOffice, LaTeX ... therefore no half-baked assembly workbench is going to fit my needs: if it can't handle an entire Airbus it's not good enough. And you don't assemble an Airbus with zillions of constraints, it's done by proper interfaces and LCS.
+1

I don't know how long it will takes us for the Airbus :) but yes, this should at least be our vision, FreeCAD should not be a toy.
User avatar
saso
Veteran
Posts: 1920
Joined: Fri May 16, 2014 1:14 pm
Contact:

Re: assembly without solver

Post by saso »

realthunder wrote: Sat Jan 05, 2019 10:32 am There is currently no concept of an "Active Assembly", similar to an "Active Body", where new Pad, Pocket and stuff gets automatically added to the active body. For now, you need to manually add objects into the assembly.
This IMO is one of the things that should be fixed first. Regardless of PDN or Asm3, it is very bad that we cannot work normally inside this containers. If I remember correctly DeepSOIC had some suggestions how to fix it... ?
User avatar
Zolko
Veteran
Posts: 2213
Joined: Mon Dec 17, 2018 10:02 am

Re: assembly without solver

Post by Zolko »

realthunder wrote: Sat Jan 05, 2019 10:32 am No, attach engine does not support App::Part and App::Link directly. What you did is exactly the missing piece. If you'd like to explore more about my branch, you can try the enhanced expression engine. Select Part_1 in the assembly, right click in the property view, and select "Show all". Then, right click in Placement field, and select "Expression...". Finally, enter the following expression,

Code: Select all

LCS_1.Placement.multiply(.<<LCS_1.>>.Placement.inverse())
Brilliant, that works !!!

Now, what is needed is an additional Placement between the LCS in the Part and the LCS in the Assembly, if one wants to put the Part relative to the LCS but not exactly ON that LCS. There might be — at least — 2 reasons to do that:
  • If one wants to use 1 LCS and place several Parts on it, they would be offsetted. Think about a screw and a washer, or an axis and a bearing
  • the LCS in the Part and the LCS in the Assembly might be oriented differently, so rotation(s) by 90° around some (several) axis might be necessary to correctly orient the Part.
there is no difference between assembly and part either.
Why call it "Assembly" then ? I agree with saso here:

saso wrote: Sat Jan 05, 2019 11:24 am I think If we look at it as an NX Part it probably works quite well. If it can work like this then the existing FC Part would become obsolete.
...
This is an old and ongoing confusion in FC, the definitions of Part, Solid, Body are all badly mixed and misused.
We had Part, Solid, Body, it was confusing, and now we have additionally Assembly ... We need the mandatory xkcd citation:

Image
try the Assembly4 workbench for FreCAD — tutorials here and here
Post Reply