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 »

Turro75 wrote: Wed Aug 01, 2018 5:58 am @Kbwbe
@project4

Is there a way to check every x thousand steps if the solver is doing well and movement rotation are acctually reducing the gap to the target?
Hi @Turro + @project4,

it is inside branch "devel" now. There are some new parameters at head of "solversystem.py".

Code: Select all

SOLVER_STEPS_CONVERGENCY_CHECK = 1000
SOLVER_MIN_CONVERGENCY_RATE = 0.9999
SOLVER_CONVERGENY_ERROR_INIT_VALUE = 1.0e+20
I tested these values and this combination worked for my assemblies. The values detect surely if a constraint is not solvable. It was not possible to set SOLVER_MIN_CONVERGENCY_RATE = 0.99. In this case, some test cases did not work anymore. Perhaps you can play with the values for your assemblies.

Most work is implemented in Rigid.calculateWorkList(). It looks now as:

Code: Select all

    def calculateWorkList(self, doc, workList):
        self.printList("WorkList", workList)

        for rig in workList:
            rig.enableDependencies(workList)

        self.lastPositionError = SOLVER_CONVERGENY_ERROR_INIT_VALUE
        self.lastAxisError = SOLVER_CONVERGENY_ERROR_INIT_VALUE
        self.convergencyCounter = 0

        calcCount = 0
        goodAccuracy = False
        while not goodAccuracy:
            maxPosError = 0.0
            maxAxisError = 0.0

            calcCount += 1
            self.stepCount += 1
            self.convergencyCounter += 1
            # First calculate all the movement vectors
            for w in workList:
                w.calcMoveData(doc, self)
                if w.maxPosError > maxPosError:
                    maxPosError = w.maxPosError
                if w.maxAxisError > maxAxisError:
                    maxAxisError = w.maxAxisError

            # Perform the move
            for w in workList:
                w.move(doc)
                # Enable those 2 lines to see the computation progress on screen
                #w.applySolution(doc, self)
                #FreeCADGui.updateGui()

            # The accuracy is good, apply the solution to FreeCAD's objects
            if (maxPosError <= self.mySOLVER_POS_ACCURACY and
                maxAxisError <= self.mySOLVER_SPIN_ACCURACY):
                # The accuracy is good, we're done here
                goodAccuracy = True
                # Mark the rigids as tempfixed and add its constrained rigids to pending list to be processed next
                FreeCAD.Console.PrintMessage( "{} counts \n".format(calcCount) )
                for r in workList:
                    r.applySolution(doc, self)
                    r.tempfixed = True
                    
            if self.convergencyCounter > SOLVER_STEPS_CONVERGENCY_CHECK:
                if (
                    maxPosError > SOLVER_MIN_CONVERGENCY_RATE * self.lastPositionError or
                    maxAxisError > SOLVER_MIN_CONVERGENCY_RATE * self.lastAxisError
                    ):
                    FreeCAD.Console.PrintMessage( "System not solvable, convergency is to bad !\n" )
                    return False
                self.lastPositionError = maxPosError
                self.lastAxisError = maxAxisError
                self.convergencyCounter = 0
                
            if self.stepCount > SOLVER_MAXSTEPS:
                FreeCAD.Console.PrintMessage( "Reached max calculations count ({})\n".format(SOLVER_MAXSTEPS) )
                return False
        return True
P.S.: @Turro75: I opened branch "turro" at github for your PR's
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
User avatar
manuelkrause
Posts: 442
Joined: Thu Jul 05, 2018 7:16 pm

Re: Another approach to assembly solver (A2plus)

Post by manuelkrause »

Now that the solversystem outputs so much info about included parts... Wouldn't it be great upon failing _changed_ imported parts, that the solver just reminds "Please check part xyz for changed constraints!" with xyz being the part where the solver exited? I mean, instaed of all the error messages in the Report view.
...
dep2.refPoint = circleEdge2.Curve.Center
'Part.Line' object has no attribute 'Center'
...

Manuel
User avatar
manuelkrause
Posts: 442
Joined: Thu Jul 05, 2018 7:16 pm

Re: Another approach to assembly solver (A2plus)

Post by manuelkrause »

With the devel code from yesterday evening I also get completely inconsistent part placements after constraining:
Please have a look:

Screenshot_20180801_203638.png
Screenshot_20180801_203638.png (255.86 KiB) Viewed 894 times

Manuel
project4
Posts: 237
Joined: Fri Jul 12, 2013 12:53 pm

Re: Another approach to assembly solver (A2plus)

Post by project4 »

manuelkrause wrote: Wed Aug 01, 2018 5:44 pm Now that the solversystem outputs so much info about included parts... Wouldn't it be great upon failing _changed_ imported parts, that the solver just reminds "Please check part xyz for changed constraints!" with xyz being the part where the solver exited? I mean, instaed of all the error messages in the Report view.
...
dep2.refPoint = circleEdge2.Curve.Center
'Part.Line' object has no attribute 'Center'
...

Manuel
@kbwbe
I had a similar thought in that direction as well few weeks ago.
We should probably replace all the FreeCAD.Console.Print calls to a2p.print (or something like that, I don't remember the existing function name).
We could add the severity parameter to the print function (CRITICAL, ERROR, WARNING, DEBUG) and the function will print only messages with higher severity than global configuration. Similar to any Linux debug functionality...

That way we won't need to remark all the debug printouts all the time, only change the global.
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: Wed Aug 01, 2018 6:44 pm With the devel code from yesterday evening I also get completely inconsistent part placements after constraining:
Hi Manuel, in devel code from yesterday evening nothing concerning part placements was changed. Did you try "alltogether" mode ?
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: Wed Aug 01, 2018 6:48 pm
manuelkrause wrote: Wed Aug 01, 2018 5:44 pm Now that the solversystem outputs so much info about included parts... Wouldn't it be great upon failing _changed_ imported parts, that the solver just reminds "Please check part xyz for changed constraints!" with xyz being the part where the solver exited? I mean, instaed of all the error messages in the Report view.
...
dep2.refPoint = circleEdge2.Curve.Center
'Part.Line' object has no attribute 'Center'
...

Manuel
@kbwbe
I had a similar thought in that direction as well few weeks ago.
We should probably replace all the FreeCAD.Console.Print calls to a2p.print (or something like that, I don't remember the existing function name).
We could add the severity parameter to the print function (CRITICAL, ERROR, WARNING, DEBUG) and the function will print only messages with higher severity than global configuration. Similar to any Linux debug functionality...

That way we won't need to remark all the debug printouts all the time, only change the global.
Hi @project4 + @manuelkrause

these are two different types of messages.
1) the messages generated by ourself, easy to reduce...
2) freecad error messages, which has Manuel now, because of reimporting modified parts without deleting the related constraints before that . (as being recommended ATM)

I will have a look at both types.
At 1): modification according to your (@project4) suggestions
At 2): what Manuel needs is a clear message which reimported part breaks it's constraints. If there are FreeCAD errors, it is possible. But if FreeCAD gives no error, because of linking so same type of geometric element (but a false one), it can not be catched and Manuel will still have his problem.
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
User avatar
manuelkrause
Posts: 442
Joined: Thu Jul 05, 2018 7:16 pm

Re: Another approach to assembly solver (A2plus)

Post by manuelkrause »

kbwbe wrote: Wed Aug 01, 2018 7:37 pm
manuelkrause wrote: Wed Aug 01, 2018 6:44 pm With the devel code from yesterday evening I also get completely inconsistent part placements after constraining:
Hi Manuel, in devel code from yesterday evening nothing concerning part placements was changed. Did you try "alltogether" mode ?
Mmmh. The main assembly was done with earlier versions of A2plus. I've only removed the potential error-causing constraint (according to 'Report view' last failing one, what never was the culprit) and then went on constraining).
And yes, it happens with both "'alltogether" and "partial" -- maybe there's a re-action from the "toggle" mode.

Manuel
User avatar
manuelkrause
Posts: 442
Joined: Thu Jul 05, 2018 7:16 pm

Re: Another approach to assembly solver (A2plus)

Post by manuelkrause »

kbwbe wrote: Wed Aug 01, 2018 8:10 pm
project4 wrote: Wed Aug 01, 2018 6:48 pm
manuelkrause wrote: Wed Aug 01, 2018 5:44 pm Now that the solversystem outputs so much info about included parts... Wouldn't it be great upon failing _changed_ imported parts, that the solver just reminds "Please check part xyz for changed constraints!" with xyz being the part where the solver exited? I mean, instaed of all the error messages in the Report view.
...
dep2.refPoint = circleEdge2.Curve.Center
'Part.Line' object has no attribute 'Center'
...

Manuel
@kbwbe
I had a similar thought in that direction as well few weeks ago.
We should probably replace all the FreeCAD.Console.Print calls to a2p.print (or something like that, I don't remember the existing function name).
We could add the severity parameter to the print function (CRITICAL, ERROR, WARNING, DEBUG) and the function will print only messages with higher severity than global configuration. Similar to any Linux debug functionality...

That way we won't need to remark all the debug printouts all the time, only change the global.
Hi @project4 + @manuelkrause

these are two different types of messages.
1) the messages generated by ourself, easy to reduce...
2) freecad error messages, which has Manuel now, because of reimporting modified parts without deleting the related constraints before that . (as being recommended ATM)

I will have a look at both types.
At 1): modification according to your (@project4) suggestions
At 2): what Manuel needs is a clear message which reimported part breaks it's constraints. If there are FreeCAD errors, it is possible. But if FreeCAD gives no error, because of linking so same type of geometric element (but a false one), it can not be catched and Manuel will still have his problem.
Please, keep calm, I've only made some very humble proposals.
But please write, where the new development goes! "/devel/" ?
Turro75
Posts: 179
Joined: Mon Aug 15, 2016 10:23 pm

Re: Another approach to assembly solver (A2plus)

Post by Turro75 »

kbwbe wrote: Wed Aug 01, 2018 4:25 pm
Turro75 wrote: Wed Aug 01, 2018 5:58 am @Kbwbe
@project4

Is there a way to check every x thousand steps if the solver is doing well and movement rotation are acctually reducing the gap to the target?
Hi @Turro + @project4,

it is inside branch "devel" now. There are some new parameters at head of "solversystem.py".

Code: Select all

SOLVER_STEPS_CONVERGENCY_CHECK = 1000
SOLVER_MIN_CONVERGENCY_RATE = 0.9999
SOLVER_CONVERGENY_ERROR_INIT_VALUE = 1.0e+20
I tested these values and this combination worked for my assemblies. The values detect surely if a constraint is not solvable. It was not possible to set SOLVER_MIN_CONVERGENCY_RATE = 0.99. In this case, some test cases did not work anymore. Perhaps you can play with the values for your assemblies.

Most work is implemented in Rigid.calculateWorkList(). It looks now as:

Code: Select all

    def calculateWorkList(self, doc, workList):
        self.printList("WorkList", workList)

        for rig in workList:
            rig.enableDependencies(workList)

        self.lastPositionError = SOLVER_CONVERGENY_ERROR_INIT_VALUE
        self.lastAxisError = SOLVER_CONVERGENY_ERROR_INIT_VALUE
        self.convergencyCounter = 0

        calcCount = 0
        goodAccuracy = False
        while not goodAccuracy:
            maxPosError = 0.0
            maxAxisError = 0.0

            calcCount += 1
            self.stepCount += 1
            self.convergencyCounter += 1
            # First calculate all the movement vectors
            for w in workList:
                w.calcMoveData(doc, self)
                if w.maxPosError > maxPosError:
                    maxPosError = w.maxPosError
                if w.maxAxisError > maxAxisError:
                    maxAxisError = w.maxAxisError

            # Perform the move
            for w in workList:
                w.move(doc)
                # Enable those 2 lines to see the computation progress on screen
                #w.applySolution(doc, self)
                #FreeCADGui.updateGui()

            # The accuracy is good, apply the solution to FreeCAD's objects
            if (maxPosError <= self.mySOLVER_POS_ACCURACY and
                maxAxisError <= self.mySOLVER_SPIN_ACCURACY):
                # The accuracy is good, we're done here
                goodAccuracy = True
                # Mark the rigids as tempfixed and add its constrained rigids to pending list to be processed next
                FreeCAD.Console.PrintMessage( "{} counts \n".format(calcCount) )
                for r in workList:
                    r.applySolution(doc, self)
                    r.tempfixed = True
                    
            if self.convergencyCounter > SOLVER_STEPS_CONVERGENCY_CHECK:
                if (
                    maxPosError > SOLVER_MIN_CONVERGENCY_RATE * self.lastPositionError or
                    maxAxisError > SOLVER_MIN_CONVERGENCY_RATE * self.lastAxisError
                    ):
                    FreeCAD.Console.PrintMessage( "System not solvable, convergency is to bad !\n" )
                    return False
                self.lastPositionError = maxPosError
                self.lastAxisError = maxAxisError
                self.convergencyCounter = 0
                
            if self.stepCount > SOLVER_MAXSTEPS:
                FreeCAD.Console.PrintMessage( "Reached max calculations count ({})\n".format(SOLVER_MAXSTEPS) )
                return False
        return True
P.S.: @Turro75: I opened branch "turro" at github for your PR's
Hi Kbwbe,

Why do you apply the min convergency rate? It wasn't enough comparing max error with the last one?
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: Thu Aug 02, 2018 11:24 am Why do you apply the min convergency rate? It wasn't enough comparing max error with the last one?
Hi @Turro75,
it' so simple that i did not see it. I will try out.
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