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

Need help, or want to share a macro? Post here!
User avatar
bambuko
Posts: 523
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

Postby bambuko » Sat May 15, 2021 2:32 pm

edwilliams16 wrote: Sat May 15, 2021 1:59 pm Oops, sign is a numpy function, not bare python
numpy function?
I am such a numpty had to search what it is :mrgreen:


...Replace that line of code with

Code: Select all

    angle = angle - cmp(angle, 0)
did this, and got another error message :oops: :
angle = angle - cmp(angle, 0)
<class 'NameError'>: name 'cmp' is not defined



...Yes this code is to zero the angle, starting anywhere....
thank you for confirmation (better ask than get it wrong ;) )


... We can go the dropbox route if this doesn’t do it...
I am happy to carry on testing your suggestions.
edwilliams16
Posts: 431
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

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

Postby edwilliams16 » Sat May 15, 2021 5:10 pm

To add insult to injury, cmp() was removed from python in 3.x. (For those old enough to have learned to program in the 60's, it went the way of the Fortran arithmetic if)

Code: Select all

angle = int(FreeCAD.ActiveDocument.getObject("Constraint016").Angle)
while angle != 0:
    if angle > 0:
        angle -= 1
    else:
        angle += 1
    FreeCAD.ActiveDocument.getObject("Constraint016").Angle = angle
    Gui.runCommand('asm3CmdQuickSolve',0)
FreeCADGui.updateGui()
should at least get rid of that bug.
User avatar
bambuko
Posts: 523
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

Postby bambuko » Sat May 15, 2021 6:26 pm

edwilliams16 wrote: Sat May 15, 2021 5:10 pm To add insult to injury, cmp() was removed from python in 3.x. (For those old enough to have learned to program in the 60's, it went the way of the Fortran arithmetic if)
I am old enough to remember being taught Fortran at uni... (unfortunately, long since evaporated from my head :P )
but... and here is the great news - your latest macro is proper dog's cojones :mrgreen:
it works! :ugeek:

Tested it in quite a few scenarios and so far it hasn't failed - great!

The only difference from the original (set desired angle) macro is that in yours it all happens in the background, with timer symbol whirling around, until it suddenly snaps back to 0deg,
whereas in original macro depending on the value I set for angle it goes one angular increment at a time.

Compared the two and the only difference was:

Code: Select all

 time.sleep(0.001)
and hey presto, both behave the same :D

Thank you very much indeed - that is exactly what I was after :!:
edwilliams16
Posts: 431
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)

Postby edwilliams16 » Sat May 15, 2021 8:20 pm

There's a bug here if the initial angle is less than 1 degree. It's also inefficient to move in 1 degree chunks.

Code: Select all

angle = FreeCAD.ActiveDocument.getObject("Constraint016").Angle
nsteps = int(abs(angle)//20) + 1
steps = [m*angle/n for m in list(range(0,nsteps))][::-1]
for ang in steps:
    FreeCAD.ActiveDocument.getObject("Constraint016").Angle = ang
    Gui.runCommand('asm3CmdQuickSolve',0)
FreeCADGui.updateGui()
rotates in 20 degreechunks.

There may be an issue here if FreeCAD.ActiveDocument.getObject("Constraint016").Angle returns its value in radians, not degrees. Can you check that?
If it does, the first line needs to be replaced by

Code: Select all

import math
angle = math.degrees(FreeCAD.ActiveDocument.getObject("Constraint016").Angle)
User avatar
bambuko
Posts: 523
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)

Postby bambuko » Sun May 16, 2021 8:19 am

edwilliams16 wrote:..
Thank you!



edwilliams16 wrote:...There's a bug here if the initial angle is less than 1 degree...
It is not possible to rotate using the original macro in less than 1 degree:
class 'TypeError'>: 'float' object cannot be interpreted as an integer
and it works fine for 1 degree rotated assembly, so I think this is non-issue?



edwilliams16 wrote:....It's also inefficient to move in 1 degree chunks...
1 degree is perhaps extreme :D , but...

- (at least for my original macro) I used 1 degree increment because I wanted to rotate with 1 degree precision
how do you rotate to (for example) 237 degrees if your increments are 20 degrees?

- in case of your macro (return to O degree) I guess it is not an issue?, but...

- both macros have adavantage of doing things in small increments to make assembly solver life easy.
too big jumps totally confuse the solver

- if it was that simple, I could simply manually modify value of "Angle" for the "Constraint016" in Property view...
works OK for small increments, but goes totally wobbly for bigger ones
(hence my desire for macros which take away the tedium of manually rotating at small increments)


edwilliams16 wrote:

Code: Select all

angle = FreeCAD.ActiveDocument.getObject("Constraint016").Angle
nsteps = int(abs(angle)//20) + 1
steps = [m*angle/n for m in list(range(0,nsteps))][::-1]
for ang in steps:
    FreeCAD.ActiveDocument.getObject("Constraint016").Angle = ang
    Gui.runCommand('asm3CmdQuickSolve',0)
FreeCADGui.updateGui()
rotates in 20 degreechunks.
I am afraid :oops: this one doesn't work...
line 18, in <listcomp>
steps = [m*angle/n for m in list(range(0,nsteps))][::-1]
<class 'TypeError'>: unsupported operand type(s) for /: 'float' and 'str'



edwilliams16 wrote:There may be an issue here if FreeCAD.ActiveDocument.getObject("Constraint016").
Angle returns its value in radians, not degrees. Can you check that?
angle.jpg
angle.jpg (37.04 KiB) Viewed 970 times
edwilliams16
Posts: 431
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)

Postby edwilliams16 » Sun May 16, 2021 1:04 pm

Typo! Mea culpa.

Code: Select all

[steps = m*angle/nsteps for m in list(range(0,nsteps))][::-1]
To test the return value, you need to type it in the Python console. It is very common in Freecad for angles to be displayed in degrees even though they are internally carried in radians. Without playing with a model using this workbench, I have no way to check. I suspect this case is an exception.
User avatar
bambuko
Posts: 523
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)

Postby bambuko » Sun May 16, 2021 2:10 pm

edwilliams16 wrote: Sun May 16, 2021 1:04 pm Typo! Mea culpa.

Code: Select all

[steps = m*angle/nsteps for m in list(range(0,nsteps))][::-1]
There is no culpa about it ;)
I am most grateful for all your assistance!
However... this one was also a typo (didn't work as above)
so I modified it to?:

Code: Select all

steps = [m*angle/nsteps for m in list(range(0,nsteps))][::-1]

This, kind of works... but not very well I am afraid :oops:
Having rotated (for example) to my desired position of 30deg, I tried the "return to zero in 20deg chunks" macro and it returned back to 15 deg...


edwilliams16 wrote: Sun May 16, 2021 1:04 pmTo test the return value, you need to type it in the Python console. ...
I was guessing that this is what was needed, but whatever I tried didn't work :oops:
I am afraid I have reached the level of my incompetence...
Any hints how to do it, please?
edwilliams16
Posts: 431
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)

Postby edwilliams16 » Sun May 16, 2021 5:21 pm

Your correction is good. My 2:00 am proofreading on my ipad could stand improvement.

It looks like it is doing degrees not radians What do you get if you reduce the “20” in the script to 15, 10, 2, 5 or 1?
Does it start working at some point? If not, where does it end up?
User avatar
bambuko
Posts: 523
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)

Postby bambuko » Sun May 16, 2021 9:05 pm

edwilliams16 wrote: Sun May 16, 2021 5:21 pm ...What do you get if you reduce the “20” in the script to 15, 10, 2, 5 or 1?
As a test I have rotated assembly 30 deg FWD
using your latest macro results in following:
(1) -> returns to 29.03deg
(5) -> returns to 25.71deg
(10) -> returns to 22.50deg
(20) -> returns to 15.0deg

most puzzling... :o
edwilliams16
Posts: 431
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)

Postby edwilliams16 » Sun May 16, 2021 10:00 pm

The only explanation I can come up with is you have lost the formatting in the macro and so the loop body is not being executed.

Code: Select all

angle = FreeCAD.ActiveDocument.getObject("Constraint016").Angle
print(f'Initial angle is {angle} degrees')
nsteps = int(abs(angle)//10) + 1
steps = [m*angle/nsteps for m in list(range(0,nsteps))][::-1]
for ang in steps:
    FreeCAD.ActiveDocument.getObject("Constraint016").Angle = ang
    Gui.runCommand('asm3CmdQuickSolve',0)
    print(f'Doing {ang}')
FreeCADGui.updateGui()
print("done")
The four spaces in front of each statement in the for block are essential. It's how python groups statements. Make sure when you paste it into a macro, you don't lose them. You should get some progress diagnostics in the report view. I get:

Code: Select all

11:59:11  Initial angle is 30 degrees
11:59:11  Doing 22.5
11:59:11  Doing 15.0
11:59:11  Doing 7.5
11:59:11  Doing 0.0
11:59:11  done
In a summer job as a teenager, I had to do some programming. After I'd punched the cards, I had a 70 mile round-trip to the computer center. I would collected the previous day's output and hand my new, perhaps recorrected deck to the white-coated acolytes attending the computer, to be run later in the day - then drive back to the office. It was slow progress.