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 »

manuelkrause wrote: Sat Jul 28, 2018 9:01 pm @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
Hi Manuel,
this is one of the usual FreeCAD problems while editing parts. An edge index, before edit, was pointing to a circle. After editing, indexes are mixed up by FreeCAD and same number is pointing to a line instead of circle, somewhere in random position. At moment, it is not checked by A2plus and you get such errors.

Only solution ATM: delete constraints of parts you want to update. Reconstraint these parts after update. Same problem with Hamish's assembly 2. He tried to catch such things, but it is impossible without topological naming within FreeCAD.
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 11:37 pm
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
Hmm...
You're right about the 1/2 and 0.5 in the multiply.
But it's very strange that the constants are not converted to float automatically...
The "v2 = v0.add(Base.Vector(2,2,2))" resulted in "v2: Vector (0.0, 0.0, 0.0)" after all.
If I change it to (2.0,2.0,2.0) it produces expected results.

I still have no explanation about the calcSpincCenter results:

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
Very strange...
project4
Posts: 237
Joined: Fri Jul 12, 2013 12:53 pm

Re: Another approach to assembly solver (A2plus)

Post by project4 »

project4 wrote: Sun Jul 29, 2018 5:18 am Hmm...
You're right about the 1/2 and 0.5 in the multiply.
But it's very strange that the constants are not converted to float automatically...
The "v2 = v0.add(Base.Vector(2,2,2))" resulted in "v2: Vector (0.0, 0.0, 0.0)" after all.
If I change it to (2.0,2.0,2.0) it produces expected results.

I still have no explanation about the calcSpincCenter results:

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
Very strange...
Ignore the problem... Looks lie I accidentally deleted that line:

Code: Select all

            self.spinCenter = newSpinCenter
And printed the self.spinCenter before it was changed...

Now I have proper spinCenter, but don't get to the expected angles yet. Will keep exploring.
project4
Posts: 237
Joined: Fri Jul 12, 2013 12:53 pm

Re: Another approach to assembly solver (A2plus)

Post by project4 »

@kbwbe

You will probably have faster answer than I'll get by myself...
I have the spinCenter point.
I have 2 vectors to 2 refPoints:

Code: Select all

# Pseuto-code:
spinCenter = self.spinCenter
v1 = spinCenter.add(dep.refPoint)
v2 = spinCenter.add(foreignDep.refPoint)
How do I get the angle between the 2 vectors?

Code: Select all

angle = v1.getAngle(v2)
It's probably don't enough since the v1 and v1 vectors are probably pointing to the refPoints from the zero coordinates.
Probably have to multiply by something, but by what?
I want to find the angle of 2 vectors pointing from the centerPoint.

Thanks.
Turro75
Posts: 179
Joined: Mon Aug 15, 2016 10:23 pm

Re: Another approach to assembly solver (A2plus)

Post by Turro75 »

project4 wrote: Sun Jul 29, 2018 5:58 am @kbwbe

You will probably have faster answer than I'll get by myself...
I have the spinCenter point.
I have 2 vectors to 2 refPoints:

Code: Select all

# Pseuto-code:
spinCenter = self.spinCenter
v1 = spinCenter.add(dep.refPoint)
v2 = spinCenter.add(foreignDep.refPoint)
How do I get the angle between the 2 vectors?

Code: Select all

angle = v1.getAngle(v2)
It's probably don't enough since the v1 and v1 vectors are probably pointing to the refPoints from the zero coordinates.
Probably have to multiply by something, but by what?
I want to find the angle of 2 vectors pointing from the centerPoint.

Thanks.
Substract spincenter to both v1 and v2, now you have two vectors which are both starting at origin and keep original angle. So now getangle gives you a reliable value.

As Kbwbe already said be careful on using methods on spincenter as most of them modify spincenter too
project4
Posts: 237
Joined: Fri Jul 12, 2013 12:53 pm

Re: Another approach to assembly solver (A2plus)

Post by project4 »

Turro75 wrote: Sun Jul 29, 2018 7:28 am
project4 wrote: Sun Jul 29, 2018 5:58 am @kbwbe

You will probably have faster answer than I'll get by myself...
I have the spinCenter point.
I have 2 vectors to 2 refPoints:

Code: Select all

# Pseuto-code:
spinCenter = self.spinCenter
v1 = spinCenter.add(dep.refPoint)
v2 = spinCenter.add(foreignDep.refPoint)
How do I get the angle between the 2 vectors?

Code: Select all

angle = v1.getAngle(v2)
It's probably don't enough since the v1 and v1 vectors are probably pointing to the refPoints from the zero coordinates.
Probably have to multiply by something, but by what?
I want to find the angle of 2 vectors pointing from the centerPoint.

Thanks.
Substract spincenter to both v1 and v2, now you have two vectors which are both starting at origin and keep original angle. So now getangle gives you a reliable value.

As Kbwbe already said be careful on using methods on spincenter as most of them modify spincenter too
Thanks!
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: Sun Jul 29, 2018 5:58 am @kbwbe

You will probably have faster answer than I'll get by myself...
I have the spinCenter point.
I have 2 vectors to 2 refPoints:

Code: Select all

# Pseuto-code:
spinCenter = self.spinCenter
v1 = spinCenter.add(dep.refPoint)
v2 = spinCenter.add(foreignDep.refPoint)
How do I get the angle between the 2 vectors?

Code: Select all

angle = v1.getAngle(v2)
It's probably don't enough since the v1 and v1 vectors are probably pointing to the refPoints from the zero coordinates.
Probably have to multiply by something, but by what?
I want to find the angle of 2 vectors pointing from the centerPoint.

Thanks.
Hi @project4,
hi @turro75,

Turro's explanation is correct. You have to work with vector-differences and extract angles later between them.
This pseudocode makes sense:

Code: Select all

# Pseuto-code:
spinCenter = self.spinCenter

/*Edit: changed order of sub operation to get right direction of vectors*/
v1 = dep.refPoint.sub(spinCenter) #<=== v1 is newly calculated, spinCenter and dep.refPoint stay untouched
v2 = foreignDep.refPoint.sub(spinCenter)#<=== v1 is newly calculated, spinCenter and foreignDep.refPoint stay untouched

angle = v2.getAngle(v1)#<=== angle is returned in radians, but a later rot=FreeCAD.Rotation(axis,angle) takes degrees !!
Calculated angles are always in this range: 0.0 < angle < math.pi
In most cases you have to work with vector.sub(vector) to get relative vectors you are calculating with.
As all vectors within rigid and dependencies are vectors from zero-coordinates to a location. These vectors can be prettily easy handled by global placement operations. Everything in solver is following this principle.
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
Jee-Bee
Veteran
Posts: 2566
Joined: Tue Jun 16, 2015 10:32 am
Location: Netherlands

Re: Another approach to assembly solver (A2plus)

Post by Jee-Bee »

Is there a reason that you are working with math and not with numpy. Since numpy is using vectors all the time I expect it should be faster and more easy to use...
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 »

Jee-Bee wrote: Sun Jul 29, 2018 10:48 am Is there a reason that you are working with math and not with numpy. Since numpy is using vectors all the time I expect it should be faster and more easy to use...
Hi @JeeBee,

i am not really firm to use numpy. Therefore i decided for myself to use FreeCAD's API functions in hope, that they are fast enough as coded in C.

Do you expect a big difference in calculation speed using numpy instead of FreeCAD's API ?
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 »

Hi @project4,@turro75,@manuelkrause,

Branch "solver-stabilization" has been updated again.
There is a new command "repair-treeview". After deleting an imported part and further undoing this by FreeCAD, the constraints were not grouped under the import parts any more. By using "repair-treeview" they are sorted again to correct place.

I do not know how to start this automatically after "undo", therefore a new command at moment.
@project4: Do you know how to start the "repair-treeview" after undo automatically ?
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