Another approach to assembly solver (A2plus)

Discussion about the development of the Assembly workbench.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
kbwbe
Veteran
Posts: 1052
Joined: Tue Apr 10, 2018 3:12 pm
Location: Germany, near Köln (Cologne)

Re: Another approach to assembly solver (A2plus)

Post by kbwbe »

Hi @project4,

branch solver-stabilization has been updated again. A2plus got a preferences page.
You can select there:
- enable/disable autosolve
- select the solver mode partial (if deselected it will be 'magnetic' mode)
- Settings for a projectfolder (experimental linux only). All project files have to be beneath this folder (but only unique). It's behaviour is like AD-Inventor.

With using of projectfile, you can move your files better from one machine to another with different folder structure.
KBWBE

https://github.com/kbwbe/A2plus
latest release: v0.4.56, installable via FreeCAD's addon manager
Tutorial: gripper assembly https://www.youtube.com/watch?v=QMxcQ5tssWk
Documentation: https://www.freecadweb.org/wiki/A2plus_Workbench
kbwbe
Veteran
Posts: 1052
Joined: Tue Apr 10, 2018 3:12 pm
Location: Germany, near Köln (Cologne)

Re: Another approach to assembly solver (A2plus)

Post by kbwbe »

project4 wrote: Fri Jul 27, 2018 2:36 pm
Sorry, could not correct code within last post (i am still on job)
Code should be:

Code: Select all

    def calcSpinCenter(self):
        newSpinCenter = Base.Vector(0,0,0)
        countRefPoints = 0
        for dep in self.dependencies:
            if dep.refPoint != None:
                newSpinCenter = newSpinCenter.add(dep.refPoint) #<=============== changed =======
                FreeCAD.Console.PrintMessage("Ref point: {}, new center {}\n".format(dep.refPoint, newSpinCenter))
                countRefPoints += 1
        if countRefPoints > 0:
            newSpinCenter.multiply(1.0/countRefPoints) #<==== this is correct ==========
            self.spinCenter = newSpinCenter #<=========== correct too =============
            FreeCAD.Console.PrintMessage("Spin center: {} num of points: {}\n".format(self.spinCenter, countRefPoints))
KBWBE

https://github.com/kbwbe/A2plus
latest release: v0.4.56, installable via FreeCAD's addon manager
Tutorial: gripper assembly https://www.youtube.com/watch?v=QMxcQ5tssWk
Documentation: https://www.freecadweb.org/wiki/A2plus_Workbench
Turro75
Posts: 179
Joined: Mon Aug 15, 2016 10:23 pm

Re: Another approach to assembly solver (A2plus)

Post by Turro75 »

Hi Kbwbe,

in the meanwhile I'm working on dof management, I'm at a good point, soon I'll provide a library which could help the method getcandidates on identifying subassemblies, may be the solver will automatically detect the right way to solve each assembly without an user parameter

that's said I found a strange behavior, the fixed part changes position/orientation just a little bit.
Can You please double check if that rigid is always skipped in the solver?
kbwbe
Veteran
Posts: 1052
Joined: Tue Apr 10, 2018 3:12 pm
Location: Germany, near Köln (Cologne)

Re: Another approach to assembly solver (A2plus)

Post by kbwbe »

Turro75 wrote: Sat Jul 28, 2018 9:33 am Hi Kbwbe,

in the meanwhile I'm working on dof management, I'm at a good point, soon I'll provide a library which could help the method getcandidates on identifying subassemblies, may be the solver will automatically detect the right way to solve each assembly without an user parameter
Thats what we need !
Turro75 wrote: Sat Jul 28, 2018 9:33 am that's said I found a strange behavior, the fixed part changes position/orientation just a little bit.
Can You please double check if that rigid is always skipped in the solver?
I also recognized that. Somewhere is a bug. I will look for it...
KBWBE

https://github.com/kbwbe/A2plus
latest release: v0.4.56, installable via FreeCAD's addon manager
Tutorial: gripper assembly https://www.youtube.com/watch?v=QMxcQ5tssWk
Documentation: https://www.freecadweb.org/wiki/A2plus_Workbench
kbwbe
Veteran
Posts: 1052
Joined: Tue Apr 10, 2018 3:12 pm
Location: Germany, near Köln (Cologne)

Re: Another approach to assembly solver (A2plus)

Post by kbwbe »

Branch "solver-stabilization" has been updated again.
Rigid.calcSpinCenter() is fixed.
Also some improvements for project-folder stuff are done. So project folder option is usable for different operation systems.
KBWBE

https://github.com/kbwbe/A2plus
latest release: v0.4.56, installable via FreeCAD's addon manager
Tutorial: gripper assembly https://www.youtube.com/watch?v=QMxcQ5tssWk
Documentation: https://www.freecadweb.org/wiki/A2plus_Workbench
project4
Posts: 237
Joined: Fri Jul 12, 2013 12:53 pm

Re: Another approach to assembly solver (A2plus)

Post by project4 »

kbwbe wrote: Sat Jul 28, 2018 4:08 pm Branch "solver-stabilization" has been updated again.
Rigid.calcSpinCenter() is fixed.
Also some improvements for project-folder stuff are done. So project folder option is usable for different operation systems.
Hi,
Didn't have much time this weekend, but I'm playing with the code a bit and I think I don't understand how do I get that result...

My calcSpinCenter code looks like that (with added printouts):

Code: Select all

    def calcSpinCenter(self):
        newSpinCenter = Base.Vector(0,0,0)
        countRefPoints = 0
        for dep in self.dependencies:
            if dep.refPoint != None:
                newSpinCenter = newSpinCenter.add(dep.refPoint)
                FreeCAD.Console.PrintMessage("{} - Ref point: {}, new center {}\n".format(self.label, dep.refPoint, newSpinCenter))
                countRefPoints += 1
        if countRefPoints > 0:
            newSpinCenter.multiply(1.0/countRefPoints)
            FreeCAD.Console.PrintMessage("{} - Spin center: {} num of points: {}\n".format(self.label, self.spinCenter, countRefPoints))
Here's an object with 2 dependencies and the vector values from the printouts:

Code: Select all

big-plate_001 - Ref point: Vector (50.0, 150.0, 20.0), new center Vector (50.0, 150.0, 20.0)
big-plate_001 - Ref point: Vector (150.0, 50.0, 20.0), new center Vector (200.0, 200.0, 40.0)
big-plate_001 - Spin center: Vector (200.0, 100.0, 10.0) num of points: 2
Both refPoints are on the same level of the Z afix (value 20.0)
I would expect to see the result's Z axis value to be 20 as well and not 10...
So we should be looking on 2D middle point in that case...
The X value is not logical as well...
What am I missing here?
Maybe we should calculate the averages for every axis separately and not using multiply?
kbwbe
Veteran
Posts: 1052
Joined: Tue Apr 10, 2018 3:12 pm
Location: Germany, near Köln (Cologne)

Re: Another approach to assembly solver (A2plus)

Post by kbwbe »

project4 wrote: Sat Jul 28, 2018 4:55 pm
kbwbe wrote: Sat Jul 28, 2018 4:08 pm Branch "solver-stabilization" has been updated again.
Rigid.calcSpinCenter() is fixed.
Also some improvements for project-folder stuff are done. So project folder option is usable for different operation systems.
Hi,
Didn't have much time this weekend, but I'm playing with the code a bit and I think I don't understand how do I get that result...

My calcSpinCenter code looks like that (with added printouts):

Code: Select all

    def calcSpinCenter(self):
        newSpinCenter = Base.Vector(0,0,0)
        countRefPoints = 0
        for dep in self.dependencies:
            if dep.refPoint != None:
                newSpinCenter = newSpinCenter.add(dep.refPoint)
                FreeCAD.Console.PrintMessage("{} - Ref point: {}, new center {}\n".format(self.label, dep.refPoint, newSpinCenter))
                countRefPoints += 1
        if countRefPoints > 0:
            newSpinCenter.multiply(1.0/countRefPoints)
            FreeCAD.Console.PrintMessage("{} - Spin center: {} num of points: {}\n".format(self.label, self.spinCenter, countRefPoints))
Here's an object with 2 dependencies and the vector values from the printouts:

Code: Select all

big-plate_001 - Ref point: Vector (50.0, 150.0, 20.0), new center Vector (50.0, 150.0, 20.0)
big-plate_001 - Ref point: Vector (150.0, 50.0, 20.0), new center Vector (200.0, 200.0, 40.0)
big-plate_001 - Spin center: Vector (200.0, 100.0, 10.0) num of points: 2
Both refPoints are on the same level of the Z afix (value 20.0)
I would expect to see the result's Z axis value to be 20 as well and not 10...
So we should be looking on 2D middle point in that case...
The X value is not logical as well...
What am I missing here?
Maybe we should calculate the averages for every axis separately and not using multiply?
Hi @project4,
the summation of the vectors seems to be correct. But multiply result is very strange ! Do not know why at moment. If dividing the x,y,z component separately by numPoints, it would be correct and it is the vector we want to have. We use multiply() very often. Is there a problem also ?
KBWBE

https://github.com/kbwbe/A2plus
latest release: v0.4.56, installable via FreeCAD's addon manager
Tutorial: gripper assembly https://www.youtube.com/watch?v=QMxcQ5tssWk
Documentation: https://www.freecadweb.org/wiki/A2plus_Workbench
project4
Posts: 237
Joined: Fri Jul 12, 2013 12:53 pm

Re: Another approach to assembly solver (A2plus)

Post by project4 »

kbwbe wrote: Sat Jul 28, 2018 5:18 pm
project4 wrote: Sat Jul 28, 2018 4:55 pm
kbwbe wrote: Sat Jul 28, 2018 4:08 pm Branch "solver-stabilization" has been updated again.
Rigid.calcSpinCenter() is fixed.
Also some improvements for project-folder stuff are done. So project folder option is usable for different operation systems.
Hi,
Didn't have much time this weekend, but I'm playing with the code a bit and I think I don't understand how do I get that result...

My calcSpinCenter code looks like that (with added printouts):

Code: Select all

    def calcSpinCenter(self):
        newSpinCenter = Base.Vector(0,0,0)
        countRefPoints = 0
        for dep in self.dependencies:
            if dep.refPoint != None:
                newSpinCenter = newSpinCenter.add(dep.refPoint)
                FreeCAD.Console.PrintMessage("{} - Ref point: {}, new center {}\n".format(self.label, dep.refPoint, newSpinCenter))
                countRefPoints += 1
        if countRefPoints > 0:
            newSpinCenter.multiply(1.0/countRefPoints)
            FreeCAD.Console.PrintMessage("{} - Spin center: {} num of points: {}\n".format(self.label, self.spinCenter, countRefPoints))
Here's an object with 2 dependencies and the vector values from the printouts:

Code: Select all

big-plate_001 - Ref point: Vector (50.0, 150.0, 20.0), new center Vector (50.0, 150.0, 20.0)
big-plate_001 - Ref point: Vector (150.0, 50.0, 20.0), new center Vector (200.0, 200.0, 40.0)
big-plate_001 - Spin center: Vector (200.0, 100.0, 10.0) num of points: 2
Both refPoints are on the same level of the Z afix (value 20.0)
I would expect to see the result's Z axis value to be 20 as well and not 10...
So we should be looking on 2D middle point in that case...
The X value is not logical as well...
What am I missing here?
Maybe we should calculate the averages for every axis separately and not using multiply?
Hi @project4,
the summation of the vectors seems to be correct. But multiply result is very strange ! Do not know why at moment. If dividing the x,y,z component separately by numPoints, it would be correct and it is the vector we want to have. We use multiply() very often. Is there a problem also ?
I don't really know... I was trying to implement the rotations I wrote before, so I added some angles printout, which didn't look too logical, so I've started to dig deeper until I came to the spinCenter calculations.

Now I'm really confused since even that simple code doesn't work :shock:

Code: Select all

            v0 = Base.Vector(0,0,0)
            v1 = v0.add(Base.Vector(10,10,10))
            v2 = v0.add(Base.Vector(2,2,2))
            a = v2
            a.multiply(1/2)
            FreeCAD.Console.PrintMessage("v0: {}\n".format(v0))
            FreeCAD.Console.PrintMessage("v1: {}\n".format(v1))
            FreeCAD.Console.PrintMessage("v2: {}\n".format(v2))
            FreeCAD.Console.PrintMessage("a: {}\n".format(a))
The output is:

Code: Select all

v0: Vector (0.0, 0.0, 0.0)
v1: Vector (10.0, 10.0, 10.0)
v2: Vector (0.0, 0.0, 0.0)
a: Vector (0.0, 0.0, 0.0)
User avatar
manuelkrause
Posts: 442
Joined: Thu Jul 05, 2018 7:16 pm

Re: Another approach to assembly solver (A2plus)

Post by manuelkrause »

@kbwbe:
ATM I'm testing your latest "solver-stabilization" from this afternoon on our A2plus-Man. I had to rework the Torso and thus used the "Update parts" button. After that I got error messages.

--->|
Running the Python command 'a2p_updateImportedParts' failed:
Traceback (most recent call last):
File "/home/manuel/.FreeCAD/Mod/A2plus/a2p_importpart.py", line 307, in Activated
updateImportedParts(doc)
File "/home/manuel/.FreeCAD/Mod/A2plus/a2p_importpart.py", line 299, in updateImportedParts
solversystem.solveConstraints(doc)
File "/home/manuel/.FreeCAD/Mod/A2plus/solversystem.py", line 1063, in solveConstraints
ss.solveSystem(doc)
File "/home/manuel/.FreeCAD/Mod/A2plus/solversystem.py", line 204, in solveSystem
self.loadSystem(doc)
File "/home/manuel/.FreeCAD/Mod/A2plus/solversystem.py", line 124, in loadSystem
Dependency.Create(doc, c, self, rigid1, rigid2)
File "/home/manuel/.FreeCAD/Mod/A2plus/solversystem.py", line 716, in Create
dep2.refPoint = circleEdge2.Curve.Center

'Part.Line' object has no attribute 'Center'
|<---

I know from previous discussions in this thread, that updating changed but already assembled parts is dangerous, so I just hope this info helps for some bug-fixing. (In my changes were only non-assembly related objects, but I'm not able to estimate the irrational 'naming changes' within "Part Design" without consistent topology naming.

In a case like shown above, do you have a hint on how to fix the assembly most easily?

Manuel
kbwbe
Veteran
Posts: 1052
Joined: Tue Apr 10, 2018 3:12 pm
Location: Germany, near Köln (Cologne)

Re: Another approach to assembly solver (A2plus)

Post by kbwbe »

project4 wrote: Sat Jul 28, 2018 5:49 pm Now I'm really confused since even that simple code doesn't work :shock:

Code: Select all

            v0 = Base.Vector(0,0,0)
            v1 = v0.add(Base.Vector(10,10,10))
            v2 = v0.add(Base.Vector(2,2,2))
            a = v2
            a.multiply(1/2)
            FreeCAD.Console.PrintMessage("v0: {}\n".format(v0))
            FreeCAD.Console.PrintMessage("v1: {}\n".format(v1))
            FreeCAD.Console.PrintMessage("v2: {}\n".format(v2))
            FreeCAD.Console.PrintMessage("a: {}\n".format(a))
The output is:

Code: Select all

v0: Vector (0.0, 0.0, 0.0)
v1: Vector (10.0, 10.0, 10.0)
v2: Vector (0.0, 0.0, 0.0)
a: Vector (0.0, 0.0, 0.0)
Hi project4, found the problem, see here:

Code: Select all

>>> a = v0.add(Base.Vector(2,2,2))
>>> a.multiply(1/2)
Vector (0.0, 0.0, 0.0)
>>> a = v0.add(Base.Vector(2,2,2))
>>> a.multiply(1.0/2.0)
Vector (1.0, 1.0, 1.0)
The problem is caused by integer division. 1/2 = 0. Float division: 1.0/2.0 = 0.5

P.S.:
This is a problem too:
a = v2
With a.multiply(1/2), v2 is damaged also, as a is a reference to v2.
This only can be avoided by:
a = Base.Vector(v2) <== de facto a copy operation
now a.multiply(1/2) does not anymore affect v2
Last edited by kbwbe on Sun Jul 29, 2018 12:01 am, edited 1 time in total.
KBWBE

https://github.com/kbwbe/A2plus
latest release: v0.4.56, installable via FreeCAD's addon manager
Tutorial: gripper assembly https://www.youtube.com/watch?v=QMxcQ5tssWk
Documentation: https://www.freecadweb.org/wiki/A2plus_Workbench
Post Reply