rotating Assy 3 model to a desired angle and back to 0deg (solved)

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
User avatar
bambuko
Veteran
Posts: 2164
Joined: Thu Oct 24, 2019 12:53 pm
Location: UK, England, North Devon

Re: rotating Assy 3 model to a desired angle and back to 0deg (solved)

Post by bambuko »

edwilliams16 wrote: Sun May 16, 2021 10:00 pm The only explanation I can come up with is you have lost the formatting in the macro ...
It is even simpler than that (and only noticed it today after good night sleep :P )
There was a single letter missing from the beginning of the line (copy and paste error)
Feel like a dummy - sorry :oops:

It is working fine (even set at 20).
Sorry for messing up.
edwilliams16 wrote: Sun May 16, 2021 10:00 pm ...After I'd punched the cards, I had a 70 mile round-trip to the computer center. ...
We must be of similar age :)
My memories are of writing program freehand giving it to a lady in computer department (yes, it was a whole floor with "the computer") to make punch cards and waiting for a result... eventually.

How things have changed in our short lives :shock:
I am using Link branch and Assembly3
you can also download ... and try it here
excellent Assembly3 tutorials here
edwilliams16
Veteran
Posts: 3107
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: rotating Assy 3 model to a desired angle and back to 0deg (solved)

Post by edwilliams16 »

bambuko wrote: Mon May 17, 2021 7:07 am
There was a single letter missing from the beginning of the line (copy and paste error)
Feel like a dummy - sorry :oops:
:
No problem. I'd made my share of typos, copying by hand... I do have a working asm3 model now, ith which I could have developed the code quicker, or at least more accurately.
User avatar
bambuko
Veteran
Posts: 2164
Joined: Thu Oct 24, 2019 12:53 pm
Location: UK, England, North Devon

Re: rotating Assy 3 model to a desired angle and back to 0deg (solved)

Post by bambuko »

edwilliams16 wrote: Tue May 18, 2021 1:26 am ... I do have a working asm3 model now, ith which I could have developed the code quicker, or at least more accurately.
Thank you!
I am still puzzled as to why is your macro happy with 20 deg increments (hasn't miss the beat once 8-) )
and the original one, which I use to rotate things to a desired angle seems to be causing solver problems when increments get too big.

Plus, the only way I have found so far to set the rotation angle with 1 deg resolution is by using 1 deg increments.
That makes it slow and inefficient, as you say.
Can it be made to rotate fast? (let's say with the same increments of 20 deg, same as your macro) and still rotate to silly angles like (for example) 127 deg?

Would appreciate your comments :)

Code: Select all

angle =0
for i in range(127):
    FreeCAD.ActiveDocument.getObject("Constraint016").Angle = angle
    Gui.runCommand('asm3CmdQuickSolve',0)
    angle -= 1
    FreeCADGui.updateGui() 
    time.sleep(0.001)
I am using Link branch and Assembly3
you can also download ... and try it here
excellent Assembly3 tutorials here
edwilliams16
Veteran
Posts: 3107
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: rotating Assy 3 model to a desired angle and back to 0deg (solved)

Post by edwilliams16 »

Your original macro will only work if the initial angle is near zero, because the first thing it does is rotate back to zero. Plus it is slow and won't do fractional degree settings. This one will do a rotation to any angle from any angle.

Code: Select all

final_angle = 10
constraint_name = "Constraint001"
angle = FreeCAD.ActiveDocument.getObject(constraint_name).Angle
#print(f'Initial angle is {angle} degrees')
#print(f'final angle is {final_angle} in degrees')
angle = angle%360 #limit range  to 0 to 360
final_angle_360 = final_angle%360 #limit range  to 0 to 360
nsteps = int(abs(final_angle_360 - angle)//20) + 1
steps = [angle + m*(final_angle_360 -angle)/nsteps for m in list(range(1,nsteps+1))]
for ang in steps:
    FreeCAD.ActiveDocument.getObject(constraint_name).Angle = ang
    Gui.runCommand('asm3CmdQuickSolve',0)
    #print(f'Doing {ang}')
FreeCAD.ActiveDocument.getObject(constraint_name).Angle = final_angle #  restore in dialog to prevent confusion
FreeCADGui.updateGui()
#print("done")
You will need to edit the final_angle and the constraint_name.

asm3 allow angle to take any value. So without additional tweaking, it would do a lot of work to rotate from 0 degrees to 36000 degrees even though nothing needs to be done. But in case you were keeping track of the number of rotations, I restore the target value of the final_angle at the end.

My test model has only this one constraint, so there's only one possible solution - so the fact that the solver doesn't find it is definitely a BUG.
Attachments
axle.FCStd
(8.94 KiB) Downloaded 55 times
indicator.FCStd
(12.96 KiB) Downloaded 45 times
axle_indicator.FCStd
(9.8 KiB) Downloaded 42 times
User avatar
bambuko
Veteran
Posts: 2164
Joined: Thu Oct 24, 2019 12:53 pm
Location: UK, England, North Devon

Re: rotating Assy 3 model to a desired angle and back to 0deg (solved)

Post by bambuko »

edwilliams16 wrote: Tue May 18, 2021 6:39 pm Your original macro will only work if the initial angle is near zero...
Yes, it was only meant as a simple animation macro to rotate full 360 deg from zero
I was trying to use it beyond it's original design brief.


edwilliams16 wrote: Tue May 18, 2021 6:39 pm...Plus it is slow and won't do fractional degree settings..
Yes, these were indeed it's limitations.


edwilliams16 wrote: Tue May 18, 2021 6:39 pm This one will do a rotation to any angle from any angle...
and... it does it admirably indeed (including fractional degrees)
More than I could have ever dreamed of ;)
Thank you.

The only thing that caught me unawares, was the polarity of:
final_angle = 10
One has to be conscious of that when specifying this angle
I was used to specifying angle and direction of rotation separately.
Here this is combined in one "final_angle".
So when specifying 270deg I ended up with model at 90deg,
because by default model rotates "backwards" only?



edwilliams16 wrote: Tue May 18, 2021 6:39 pm ...My test model has only this one constraint, so there's only one possible solution - so the fact that the solver doesn't find it is definitely a BUG.
Not quite sure whether you mean the bug in FreeCAD, or in macro, or in my design?
Even with just one constraint, for CAD systems there is often more than one geometrically correct solution,
hence sketches "flipping" or animations "unable to solve".
I have experienced it in other CAD systems (not just FreeCAD).

Unfortunately, when used with a big, complicated model, any rotation beyond 180 deg also caused problems with the solver :oops: :(

1)This seems to be making some difference?:
Gui.runCommand('asm3CmdSolve',0)
instead of, originally used:
Gui.runCommand('asm3CmdQuickSolve',0)
not entirely sure of the differences between the two commands (need to do more searching/reading)

2)Is it possible to "slow down" the macro?
I have changed the macro to:
nsteps = int(abs(final_angle_360 - angle)//2) + 1


FINAL edit:
with 1) and 2) things seem to be 100% reliable
So it looks like (unfortunately) one has to give the solver time to work things out... :mrgreen:
and... that doesn't surprise me, based on all my past CAD experience
I happily give up speed for reliability ;)

Final version of your macro that I am using and testing.
I also changed location of:
FreeCADGui.updateGui()
to make changes as happening, visible on the screen.
(previously the only thing I could see was things just jumping to new location, without indication of direction of rotation)

Code: Select all

final_angle = 75.3
constraint_name = "Constraint014"
angle = FreeCAD.ActiveDocument.getObject(constraint_name).Angle
#print(f'Initial angle is {angle} degrees')
#print(f'final angle is {final_angle} in degrees')
angle = angle%360 #limit range  to 0 to 360
final_angle_360 = final_angle%360 #limit range  to 0 to 360
nsteps = int(abs(final_angle_360 - angle)//2) + 1
steps = [angle + m*(final_angle_360 -angle)/nsteps for m in list(range(1,nsteps+1))]
for ang in steps:
    FreeCAD.ActiveDocument.getObject(constraint_name).Angle = ang
    Gui.runCommand('asm3CmdSolve',0)
    FreeCADGui.updateGui()
I am using Link branch and Assembly3
you can also download ... and try it here
excellent Assembly3 tutorials here
edwilliams16
Veteran
Posts: 3107
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: rotating Assy 3 model to a desired angle and back to 0deg (solved)

Post by edwilliams16 »

I thought you just wanted to rotate the model, not watch it move. The direction of rotation would then be immaterial.
Are you saying there was a case where with “20” it jumped to the wrong angle? I didn’t see one. Can you provide an example?

My macro should always rotate counter-clockwise to increase the final angle and clockwise to decrease it. That appeared to be natural. If you need to specify direction, it’s straightforward to add that feature.

I never found any difference between the two solvers in my simple model.

Re flipping: this applies to a situation where there really is more than one valid solution. What appears to happen here is that the solver finds a root wrong by a multiple of 90 degrees. That smells like a trigonometric bug in the solver, not a genuine ambiguity like which angle should the solver use if only given two intersecting lines and an angle constraint. (The complementary one?)
User avatar
bambuko
Veteran
Posts: 2164
Joined: Thu Oct 24, 2019 12:53 pm
Location: UK, England, North Devon

Re: rotating Assy 3 model to a desired angle and back to 0deg (solved)

Post by bambuko »

edwilliams16 wrote: Wed May 19, 2021 3:35 pm I thought you just wanted to rotate the model, not watch it move...
It just helped me to understand what was hapenning ;)

edwilliams16 wrote: Wed May 19, 2021 3:35 pm The direction of rotation would then be immaterial...
You are absolutely right.
It's just me playing and learning.
For testing it was better to see what was happening.

edwilliams16 wrote: Wed May 19, 2021 3:35 pm ... Are you saying there was a case where with “20” it jumped to the wrong angle? I didn’t see one. Can you provide an example?.
No, it wouldn't "jump to the wrong angle"
It would just stop at some random position, with solver error message, making it a fuff to restore back to normal,
i.e. the angle of rotation was different to angle displayed in properties.

edwilliams16 wrote: Wed May 19, 2021 3:35 pm ...My macro should always rotate counter-clockwise to increase the final angle and clockwise to decrease it...
Understand.

edwilliams16 wrote: Wed May 19, 2021 3:35 pm...
That appeared to be natural...
It's just a question of convention.
For me going Forward (i.e. counterclockwise rotation) increases the angle.
Going Reverse (i.e. clockwise) decreases the angle.

edwilliams16 wrote: Wed May 19, 2021 3:35 pm... I never found any difference between the two solvers in my simple model....
I am not surprised :mrgreen:
It is perfect model to test principles but not complicated enough to stress test solver/macro/animation
Since slowing things down I have not had any problems with either of the two macros - and I spent whole day playing with it.

edwilliams16 wrote: Wed May 19, 2021 3:35 pm...What appears to happen here is that the solver finds a root wrong by a multiple of 90 degrees...
It is possibly that?
I am just a user, so don't know all the details behind the scenes.
What I know (from practical experience) is that solvers seem to cope better with small increments.
Hence the need for macros - otherwise I could have just typed desired angle in Property view and "Bob is your uncle"
It doesn't work like that...
I am using Link branch and Assembly3
you can also download ... and try it here
excellent Assembly3 tutorials here
edwilliams16
Veteran
Posts: 3107
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: rotating Assy 3 model to a desired angle and back to 0deg (solved)

Post by edwilliams16 »

bambuko wrote: Wed May 19, 2021 4:26 pm
No, it wouldn't "jump to the wrong angle"
It would just stop at some random position, with solver error message, making it a fuff to restore back to normal,
i.e. the angle of rotation was different to angle displayed in properties.
Which makes it painful testing the macro. The macro reads in the current angle from the properties and then changes the angle in increments to the final angle. Given an incorrect starting point, it is subjected to the bug in asm3 we're trying to work-around.
edwilliams16 wrote: Wed May 19, 2021 3:35 pm...What appears to happen here is that the solver finds a root wrong by a multiple of 90 degrees..
bambuko wrote: Wed May 19, 2021 4:26 pm It is possibly that?
I am just a user, so don't know all the details behind the scenes.
What I know (from practical experience) is that solvers seem to cope better with small increments.
Hence the need for macros - otherwise I could have just typed desired angle in Property view and "Bob is your uncle"
It doesn't work like that...
I'm not sure it is that simple any more and it may depend on the complexity of the model.
I know nothing about the particular constraint solver that is used in asm3 (or the sketcher), but I have been solving numerical models for many decades. Your practical experience that they can handle small changes better than large ones is entirely consistent with how they work.
A typical solver will use an "error" function which measures in some way how far a given configuration is from satisfying the constraints. It returns zero when solved and a positive number that increases as the constraints are further from satisfied. (In my case of 1 DOF, the function could be (actual_angle - desired_angle)^2). If you make a small change in the constraints (desired_angle), the error function changes a bit and the current configuration finds itself up the curve, away from the zero. The solver figures out which direction is "downhill", that is, decreases the error as fast as possible and changes the configuration. It repeats until "good enough".

With 1DOF we are looking for the minimum of a curve, With 2DOF we are looking for the bottom of a valley in a landscape of hills. With more DOF it is harder to visualize. In 2D, you can see that if you make too large a change you could end up in a different drainage and the solver could march down to a different, but valid root. (Flipping) Or it can wander off and never find a solution. This a very difficult problem that has no universal solution.
User avatar
bambuko
Veteran
Posts: 2164
Joined: Thu Oct 24, 2019 12:53 pm
Location: UK, England, North Devon

Re: rotating Assy 3 model to a desired angle and back to 0deg (solved)

Post by bambuko »

Don't get me wrong :)
What I have (thanks to your help) is brilliant.
Slightly modified (i.e. giving up speed for reliability) has given me tools that (so far) seem 100% reliable.

My model is fully constrained:
<asm3.sys> sys_slvs.py(68): dof remaining: 0
apart from the rotation angle around axis.

The solver used in assembly 3 (as far as I know) is this one:
https://solvespace.com/index.pl
https://github.com/realthunder/solvespa ... ed/DOC.txt

As for the complexity of the model...
This is only a small part of it, but I am beginning to realise that I might have to review my plans :mrgreen:
This is one of the reason that I am not really going for "proper" animation,
just happy to be able to selectively rotate to the desired position (however slowly... ;) )
Having said all this - I am able to do more with FreeCAD than I could in the past with other CAD systems, so I am quite happy ;)
https://drive.google.com/file/d/1n8CH_3 ... sp=sharing
I am using Link branch and Assembly3
you can also download ... and try it here
excellent Assembly3 tutorials here
edwilliams16
Veteran
Posts: 3107
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: rotating Assy 3 model to a desired angle and back to 0deg (solved)

Post by edwilliams16 »

SLVS_C_ANGLE*

The angle between lines entityA and entityB is equal to valA, where
valA is specified in degrees. This constraint equation is written
in the form

(A dot B)/(|A||B|) = cos(valA)

where A and B are vectors in the directions of lines A and B. This
equation does not specify the angle unambiguously; for example,
note that valA = +/- 90 degrees will produce the same equation.
The documentation admits to only constraining cos(angle) - giving two valid solutions - but there's more going on than just this.
Post Reply