Tomato1107 / Cycloidal-Drive-Animation

Based on matplotlib
MIT License
55 stars 21 forks source link

fusion 360 import #1

Closed jschoch closed 2 years ago

jschoch commented 2 years ago

Thansk for sharing this, it is a great way to visualize different configurations!!!!

I took a stab at getting your demo 6 code into fusion 360 but i'm a python noob and it only sort of works. would you be able to help me troubleshoot it? It would be super helpful if you can tell me where you sourced the equations for the ball reducer so I can double check my code.

Tomato1107 commented 2 years ago

You can check the details of the equation for the ball reducer from lines 815 to 818, while the function "update_ehypocycloidA(se,sN,sD,sd, phi)" and "update_ehypocycloidE(se,sN,sD,sd, phi)" contain their own rotation and rotation around the blue orbit.

jschoch commented 2 years ago

yes, but there is lots of copy pasting and some subtle changes that are hard to detect. I was wondering where the original formula came from? I seem to be importing the correct "fixed" shape, but oddly the eccentric is not complete. image

I tried to use the arrays numpy generates with t = linspace ... but it seemed to miss some points and didn't work at all for the "fixed" curves. I'm assuming that t is just some equal slice of 2pi, and that phis is just the same but tied to the current animation frame.

here is the code, i'm a python noob.


import adsk.core, adsk.fusion, adsk.cam, traceback, math
import sys, os
packagepath = os.path.join(os.path.dirname(sys.argv[0]), 'Lib/site-packages/')
if packagepath not in sys.path:
    sys.path.append(packagepath)
#import numpy as np
#np = math

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        install_numpy = sys.path[0] +'\Python\python.exe -m pip install numpy'
        try:
            import numpy as np
        except:
            ui.messageBox('failed to install numpy\n{}'.format(traceback.format_exc()))
        #ui.messageBox('Hello script')       
        design = app.activeProduct
        # Get the root component of the active design.       
        rootComp = design.rootComponent     
        # Create a new sketch on the xy plane.       
        sketches = rootComp.sketches       
        xyPlane = rootComp.xYConstructionPlane        
        sketch = sketches.add(xyPlane)

        # Create an object collection for the points.        
        points = adsk.core.ObjectCollection.create()              
        Dia = 10 #Diameter of the pin circle                
        #R = Dia/2 # Radius of the toro        
        #E = 0.3 # Eccentricity of input shaft        
        Rr = 0.3 # Radius of the rollers        
        #N = 19 # Number of rollers        
        n = 10 # num rollers
        e = .2 # eccentricity
        d = Rr * 2 # roller diameter

        #t = np.linspace(0, 2*np.pi, 400)

        #  2 pi for full 360 degrees
        l = math.pi *2 
        #l = 10
        i = 0        
        shaft_radius = .8
        #splinePoints = (n-1)*20      
        #splinePoints = n9 * 11
        #splinePoints = 2
        splinePoints = (n -1) * 40

        RD=Dia/2
        rd=d/2 
        rc = (n-1)*(RD/n)
        rm = (RD/n)

        # draw a shaft circle
        circles = sketch.sketchCurves.sketchCircles
        circle1 = circles.addByCenterRadius(adsk.core.Point3D.create(0, 0, 0), shaft_radius)
        circleA = circles.addByCenterRadius(adsk.core.Point3D.create((rc+rm) - rd,0,0),1)
        inner_pinA = circles.addByCenterRadius( adsk.core.Point3D.create((-rd - (2 * e)), 0,0),0.2)

        # fixed outer
        # ehypocycloidA

        while i <= splinePoints:       
            t = (l/splinePoints)*i        

            #xCoord = (R*math.cos(t))-(Rr*math.cos(t+math.atan(math.sin((1-N)*t)/((R/(E*N))-math.cos((1-N)*t)))))-(E*math.cos(N*t))            
            #yCoord = (-R*math.sin(t))+(Rr*math.sin(t+math.atan(math.sin((1-N)*t)/((R/(E*N))-math.cos((1-N)*t)))))+(E*math.sin(N*t))            

            xa = (rc+rm)*np.cos(t)-e*np.cos((rc+rm)/rm*t)
            ya = (rc+rm)*np.sin(t)-e*np.sin((rc+rm)/rm*t)

            dxa = (rc+rm)*(-np.sin(t)+(e/rm)*np.sin((rc+rm)/rm*t))
            dya = (rc+rm)*(np.cos(t)-(e/rm)*np.cos((rc+rm)/rm*t))
            phis =  t
            #phis = (l/splinePoints)*i

            # create fixed disk outer path
            xCoord = (xa + rd/np.sqrt(dxa**2 + dya**2)*(-dya))*np.cos(-2*phis/(n-1))-(ya + rd/np.sqrt(dxa**2 + dya**2)*dxa)*np.sin(-2*phis/(n-1))  + 2*e*np.cos(phis)
            yCoord = (xa + rd/np.sqrt(dxa**2 + dya**2)*(-dya))*np.sin(-2*phis/(n-1))+(ya + rd/np.sqrt(dxa**2 + dya**2)*dxa)*np.cos(-2*phis/(n-1))  + 2*e*np.sin(phis)
            points.add(adsk.core.Point3D.create(xCoord,yCoord,0))                   
            i = i + 1

        sketch.sketchCurves.sketchFittedSplines.add(points)

        # fixed inner
        # ehypocycloidE
        points = adsk.core.ObjectCollection.create()
        i = 0

        while i <= splinePoints:
            t = (l/splinePoints)*i        
            xa = (rc+rm)*np.cos(t)-e*np.cos((rc+rm)/rm*t)
            ya = (rc+rm)*np.sin(t)-e*np.sin((rc+rm)/rm*t)

            dxa = (rc+rm)*(-np.sin(t)+(e/rm)*np.sin((rc+rm)/rm*t))
            dya = (rc+rm)*(np.cos(t)-(e/rm)*np.cos((rc+rm)/rm*t))
            phis =  t

            # create fixed disk inner path
            xCoord = (xa - rd/np.sqrt(dxa**2 + dya**2)*(-dya))*np.cos(-2*phis/(n-1))-(ya - rd/np.sqrt(dxa**2 + dya**2)*dxa)*np.sin(-2*phis/(n-1))  + 2*e*np.cos(phis) 
            yCoord = (xa - rd/np.sqrt(dxa**2 + dya**2)*(-dya))*np.sin(-2*phis/(n-1))+(ya - rd/np.sqrt(dxa**2 + dya**2)*dxa)*np.cos(-2*phis/(n-1))  + 2*e*np.sin(phis)
            points.add(adsk.core.Point3D.create(xCoord,yCoord,0))  
            #
            i = i + 1        

        sketch.sketchCurves.sketchFittedSplines.add(points)

        #  Add moving eccentric disk  od
        # ehypocycloidD
        sketch = sketches.add(xyPlane)
        circles = sketch.sketchCurves.sketchCircles
        # should be eccentric
        circle1 = circles.addByCenterRadius(adsk.core.Point3D.create(0, 0, 0), shaft_radius)
        circleD = circles.addByCenterRadius(adsk.core.Point3D.create((rc+rm) - rd, 0,0),0.1)
        points = adsk.core.ObjectCollection.create()

        rc = (n+1)*(RD/n)
        i = 0

        while i <= splinePoints:
            t = (l/splinePoints)*i        
            xa = (rc-rm)*np.cos(t)+e*np.cos((rc-rm)/rm*t)
            ya = (rc-rm)*np.sin(t)-e*np.sin((rc-rm)/rm*t)

            dxa = (rc-rm)*(-np.sin(t)-(e/rm)*np.sin((rc-rm)/rm*t))
            dya = (rc-rm)*(np.cos(t)-(e/rm)*np.cos((rc-rm)/rm*t))
            phis =  t

            # create fixed disk inner path
            xCoord = (xa - rd/np.sqrt(dxa**2 + dya**2)*(-dya))
            yCoord = (ya - rd/np.sqrt(dxa**2 + dya**2)*dxa)
            points.add(adsk.core.Point3D.create(xCoord,yCoord,0))  
            #
            i = i + 1        

        sketch.sketchCurves.sketchFittedSplines.add(points)

        #  Add moving eccentric disk  id
        # ehypocycloidF
        points = adsk.core.ObjectCollection.create()
        i = 0

        while i <= splinePoints:
            t = (l/splinePoints)*i        
            xa = (rc-rm)*np.cos(t)+e*np.cos((rc-rm)/rm*t)
            ya = (rc-rm)*np.sin(t)-e*np.sin((rc-rm)/rm*t)
            dxa = (rc-rm)*(-np.sin(t)-(e/rm)*np.sin((rc-rm)/rm*t))
            dya = (rc-rm)*(np.cos(t)-(e/rm)*np.cos((rc-rm)/rm*t))
            phis =  t

            # create fixed disk inner path
            xCoord = (xa + rd/np.sqrt(dxa**2 + dya**2)*(-dya))

            #yCoord = (ya - rd/np.sqrt(dxa**2 + dya**2)*dxa)
            yCoord = (ya + rd/np.sqrt(dxa**2 + dya**2)*dxa)
            points.add(adsk.core.Point3D.create(xCoord,yCoord,0))  
            #
            i = i + 1        

        sketch.sketchCurves.sketchFittedSplines.add(points)

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
jschoch commented 2 years ago

I also looked into generating dxf from matplotlib but that seems beyond my python skills. It would be great to use your animation to get something that looked good and then export the dxf curves so I could make parts in fusion.

Tomato1107 commented 2 years ago

I also looked into generating dxf from matplotlib but that seems beyond my python skills. It would be great to use your animation to get something that looked good and then export the dxf curves so I could make parts in fusion.

Thanks a lot! Give me some time, I am not familiar with fusion360 programming yet. Maybe you can check the equations at https://woodencaliper.hatenablog.com/entry/2018/11/19/003515 and https://woodencaliper.hatenablog.com/entry/2018/12/01/224317.

jschoch commented 2 years ago

I don't think that is the equation for the ball reducer. maybe i'm wrong or google translate isn't quite helping...

Tomato1107 commented 2 years ago

Yes, but you can see how the basic equations come from. The offset part is a little different.

Jesse Schoch @.***>于2022年6月16日 周四11:41写道:

I don't think that is the equation for the ball reducer. maybe i'm wrong or google translate isn't quite helping...

— Reply to this email directly, view it on GitHub https://github.com/Tomato1107/Cycloidal-Drive-Animation/issues/1#issuecomment-1157169260, or unsubscribe https://github.com/notifications/unsubscribe-auth/AETYYIAOM2MSIUPFWBEOGP3VPKH5LANCNFSM5Y46T7ZA . You are receiving this because you commented.Message ID: @.***>

jschoch commented 2 years ago

This seems to be working, though i'm not quite sure how to position the eccentric disk. what is the center and is the offset e or e + ball_diameter


import adsk.core, adsk.fusion, adsk.cam, traceback, math
import sys, os
packagepath = os.path.join(os.path.dirname(sys.argv[0]), 'Lib/site-packages/')
if packagepath not in sys.path:
    sys.path.append(packagepath)
#import numpy as np
#np = math

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        install_numpy = sys.path[0] +'\Python\python.exe -m pip install numpy'
        try:
            import numpy as np
        except:
            ui.messageBox('failed to install numpy\n{}'.format(traceback.format_exc()))
        #ui.messageBox('Hello script')       
        design = app.activeProduct
        # Get the root component of the active design.       
        rootComp = design.rootComponent     
        # Create a new sketch on the xy plane.       
        sketches = rootComp.sketches       
        xyPlane = rootComp.xYConstructionPlane        
        sketch = sketches.add(xyPlane)

        # Create an object collection for the points.        
        points = adsk.core.ObjectCollection.create()              
        Dia = 10 #Diameter of the pin circle                
        #R = Dia/2 # Radius of the toro        
        #E = 0.3 # Eccentricity of input shaft        
        Rr = 0.3 # Radius of the rollers        
        #N = 19 # Number of rollers        
        n = 10 # num rollers
        e = .2 # eccentricity
        d = Rr * 2 # roller diameter

        #  2 pi for full 360 degrees
        l = math.pi *2 
        #l = 10
        i = 0        
        shaft_radius = .8
        #splinePoints = (n-1)*20      
        #splinePoints = n9 * 11
        #splinePoints = 2
        splinePoints = (n -1) * 20
        t = np.linspace(0, 2*np.pi, splinePoints)

        RD=Dia/2
        rd=d/2 
        rc = (n-1)*(RD/n)
        rm = (RD/n)

        # draw a shaft circle
        circles = sketch.sketchCurves.sketchCircles
        circle1 = circles.addByCenterRadius(adsk.core.Point3D.create(0, 0, 0), shaft_radius)
        circleA = circles.addByCenterRadius(adsk.core.Point3D.create((rc+rm) - rd,0,0),1)
        inner_pinA = circles.addByCenterRadius( adsk.core.Point3D.create((-rd - (2 * e)), 0,0),0.2)

        # moving eccentric inner
        # ehypocycloidA

        xa = (rc+rm)*np.cos(t)-e*np.cos((rc+rm)/rm*t)
        ya = (rc+rm)*np.sin(t)-e*np.sin((rc+rm)/rm*t)

        dxa = (rc+rm)*(-np.sin(t)+(e/rm)*np.sin((rc+rm)/rm*t))
        dya = (rc+rm)*(np.cos(t)-(e/rm)*np.cos((rc+rm)/rm*t))
        xCoord = xa + rd/np.sqrt(dxa**2 + dya**2)*(-dya) 
        yCoord = ya + rd/np.sqrt(dxa**2 + dya**2)*dxa 

        for i in range(splinePoints):
            #t = (l2/splinePoints)*i        
            points.add(adsk.core.Point3D.create(xCoord[i],yCoord[i],0))                   

        sketch.sketchCurves.sketchFittedSplines.add(points)

        # moving eccentric  outer
        # ehypocycloidE
        points = adsk.core.ObjectCollection.create()

        rc = (n-1)*(RD/n)
        rm = (RD/n)
        xa = (rc+rm)*np.cos(t)-e*np.cos((rc+rm)/rm*t)
        ya = (rc+rm)*np.sin(t)-e*np.sin((rc+rm)/rm*t)

        dxa = (rc+rm)*(-np.sin(t)+(e/rm)*np.sin((rc+rm)/rm*t))
        dya = (rc+rm)*(np.cos(t)-(e/rm)*np.cos((rc+rm)/rm*t))

        xCoord = xa - rd/np.sqrt(dxa**2 + dya**2)*(-dya) 
        yCoord = ya - rd/np.sqrt(dxa**2 + dya**2)*dxa
        for i in range(splinePoints):
            points.add(adsk.core.Point3D.create(xCoord[i],yCoord[i],0))  

        sketch.sketchCurves.sketchFittedSplines.add(points)

        #  Add moving eccentric disk  od
        # ehypocycloidD
        sketch = sketches.add(xyPlane)
        circles = sketch.sketchCurves.sketchCircles
        # should be eccentric
        circle1 = circles.addByCenterRadius(adsk.core.Point3D.create(0, 0, 0), shaft_radius)
        circleD = circles.addByCenterRadius(adsk.core.Point3D.create((rc+rm) - rd, 0,0),0.1)
        points = adsk.core.ObjectCollection.create()

        rc = (n+1)*(RD/n)
        rm = (RD/n)
        xa = (rc-rm)*np.cos(t)+e*np.cos((rc-rm)/rm*t)
        ya = (rc-rm)*np.sin(t)-e*np.sin((rc-rm)/rm*t)

        dxa = (rc-rm)*(-np.sin(t)-(e/rm)*np.sin((rc-rm)/rm*t))
        dya = (rc-rm)*(np.cos(t)-(e/rm)*np.cos((rc-rm)/rm*t))

        xCoord = xa - rd/np.sqrt(dxa**2 + dya**2)*(-dya) 
        yCoord = ya - rd/np.sqrt(dxa**2 + dya**2)*dxa

        for i in range(splinePoints):
            points.add(adsk.core.Point3D.create(xCoord[i],yCoord[i],0))

        sketch.sketchCurves.sketchFittedSplines.add(points)

        #  Add moving eccentric disk  id
        # ehypocycloidF
        points = adsk.core.ObjectCollection.create()
        i = 0

        rc = (n+1)*(RD/n)
        rm = (RD/n)
        xa = (rc-rm)*np.cos(t)+e*np.cos((rc-rm)/rm*t)
        ya = (rc-rm)*np.sin(t)-e*np.sin((rc-rm)/rm*t)

        dxa = (rc-rm)*(-np.sin(t)-(e/rm)*np.sin((rc-rm)/rm*t))
        dya = (rc-rm)*(np.cos(t)-(e/rm)*np.cos((rc-rm)/rm*t))

        xCoord = xa + rd/np.sqrt(dxa**2 + dya**2)*(-dya) 
        yCoord = ya + rd/np.sqrt(dxa**2 + dya**2)*dxa
        for i in range(splinePoints):
            points.add(adsk.core.Point3D.create(xCoord[i],yCoord[i],0))

        sketch.sketchCurves.sketchFittedSplines.add(points)

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
Tomato1107 commented 2 years ago

@jschoch You can check my script below


import adsk.core, adsk.fusion, adsk.cam, traceback, math

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface

        #ui.messageBox('Hello script')       
        design = app.activeProduct
        # Get the root component of the active design.       
        rootComp = design.rootComponent     
        # Create a new sketch on the xy plane.       
        sketches = rootComp.sketches       
        xyPlane = rootComp.xYConstructionPlane        
        sketch = sketches.add(xyPlane)

        # Create an object collection for the points.        

        D = 10 #Diameter of the pin circle                
        #R = Dia/2 # Radius of the toro        
        #E = 0.3 # Eccentricity of input shaft           
        #N = 19 # Number of rollers  
        Rr = 0.3 # Radius of the rollers         
        n = 10 # num rollers
        e = .2 # eccentricity
        d = 2*Rr # roller diameter
        shaft_radius = .8

        #t = np.linspace(0, 2*np.pi, 400)

        #  2 pi for full 360 degrees
        l = math.pi *2 
        i = 0   
        splinePoints = (n -1) * 20

        RD=D/2
        rd=d/2 
        rc = (n-1)*(RD/n)
        rm = (RD/n)

        # draw a shaft circle
        circles = sketch.sketchCurves.sketchCircles  
        circle0 = circles.addByCenterRadius(adsk.core.Point3D.create(0, 0, 0), shaft_radius)
        circle2 = circles.addByCenterRadius(adsk.core.Point3D.create(2*e, 0, 0), shaft_radius+2*e)        

        # draw ball
        sketch = sketches.add(xyPlane)
        points = adsk.core.ObjectCollection.create() 
        circles = sketch.sketchCurves.sketchCircles
        for i in range(int(n)): 
            circleA = circles.addByCenterRadius(adsk.core.Point3D.create(RD*math.cos(2*i*math.pi/n)+e,RD*math.sin(2*i*math.pi/n),0),rd)

        # fixed outer
        # ehypocycloidA
        i=0
        #sketches = rootComp.sketches       
        #xyPlane = rootComp.xYConstructionPlane  
        sketch = sketches.add(xyPlane)
        points = adsk.core.ObjectCollection.create() 
        circles = sketch.sketchCurves.sketchCircles
        circle2 = circles.addByCenterRadius(adsk.core.Point3D.create(2*e, 0, 0), shaft_radius+2*e)
        while i <= splinePoints:       
            t = (l/splinePoints)*i    

            xa = (rc+rm)*math.cos(t)-e*math.cos((rc+rm)/rm*t)
            ya = (rc+rm)*math.sin(t)-e*math.sin((rc+rm)/rm*t)

            dxa = (rc+rm)*(-math.sin(t)+(e/rm)*math.sin((rc+rm)/rm*t))
            dya = (rc+rm)*(math.cos(t)-(e/rm)*math.cos((rc+rm)/rm*t))

            # create fixed disk outer path
            xCoord = (xa + rd/math.sqrt(dxa**2 + dya**2)*(-dya))  + 2*e
            yCoord = (ya + rd/math.sqrt(dxa**2 + dya**2)*dxa)  
            points.add(adsk.core.Point3D.create(xCoord,yCoord,0))                   
            i = i + 1

        sketch.sketchCurves.sketchFittedSplines.add(points)

        # fixed inner        
        # ehypocycloidB
        i=0
        sketch = sketches.add(xyPlane)
        points = adsk.core.ObjectCollection.create() 
        circles = sketch.sketchCurves.sketchCircles
        circle2 = circles.addByCenterRadius(adsk.core.Point3D.create(2*e, 0, 0), shaft_radius+2*e)
        while i <= splinePoints:       
            t = (l/splinePoints)*i    

            xa = (rc+rm)*math.cos(t)-e*math.cos((rc+rm)/rm*t)
            ya = (rc+rm)*math.sin(t)-e*math.sin((rc+rm)/rm*t)

            dxa = (rc+rm)*(-math.sin(t)+(e/rm)*math.sin((rc+rm)/rm*t))
            dya = (rc+rm)*(math.cos(t)-(e/rm)*math.cos((rc+rm)/rm*t))

            # create fixed disk outer path
            xCoord = (xa - rd/math.sqrt(dxa**2 + dya**2)*(-dya))  + 2*e
            yCoord = (ya - rd/math.sqrt(dxa**2 + dya**2)*dxa)  
            points.add(adsk.core.Point3D.create(xCoord,yCoord,0))                   
            i = i + 1

        sketch.sketchCurves.sketchFittedSplines.add(points)        

        # inner        
        # ehypocycloidC
        i=0
        sketch = sketches.add(xyPlane)
        points = adsk.core.ObjectCollection.create()
        rc = (n+1)*(RD/n)       
        circles = sketch.sketchCurves.sketchCircles
        circle1 = circles.addByCenterRadius(adsk.core.Point3D.create(0, 0, 0), shaft_radius)        
        while i <= splinePoints:       
            t = (l/splinePoints)*i    

            xa = (rc-rm)*math.cos(t)+e*math.cos((rc-rm)/rm*t)
            ya = (rc-rm)*math.sin(t)-e*math.sin((rc-rm)/rm*t)

            dxa = (rc-rm)*(-math.sin(t)-(e/rm)*math.sin((rc-rm)/rm*t))
            dya = (rc-rm)*(math.cos(t)-(e/rm)*math.cos((rc-rm)/rm*t))

            # create fixed disk outer path
            xCoord = (xa - rd/math.sqrt(dxa**2 + dya**2)*(-dya))  
            yCoord = (ya - rd/math.sqrt(dxa**2 + dya**2)*dxa)  
            points.add(adsk.core.Point3D.create(xCoord,yCoord,0))                   
            i = i + 1

        sketch.sketchCurves.sketchFittedSplines.add(points)  

        # inner        
        # ehypocycloidD
        i=0
        sketch = sketches.add(xyPlane)
        points = adsk.core.ObjectCollection.create() 
        rc = (n+1)*(RD/n)
        circles = sketch.sketchCurves.sketchCircles
        circle1 = circles.addByCenterRadius(adsk.core.Point3D.create(0, 0, 0), shaft_radius)
        while i <= splinePoints:       
            t = (l/splinePoints)*i    

            xa = (rc-rm)*math.cos(t)+e*math.cos((rc-rm)/rm*t)
            ya = (rc-rm)*math.sin(t)-e*math.sin((rc-rm)/rm*t)

            dxa = (rc-rm)*(-math.sin(t)-(e/rm)*math.sin((rc-rm)/rm*t))
            dya = (rc-rm)*(math.cos(t)-(e/rm)*math.cos((rc-rm)/rm*t))

            # create fixed disk outer path
            xCoord = (xa + rd/math.sqrt(dxa**2 + dya**2)*(-dya)) 
            yCoord = (ya + rd/math.sqrt(dxa**2 + dya**2)*dxa)  
            points.add(adsk.core.Point3D.create(xCoord,yCoord,0))                   
            i = i + 1

        sketch.sketchCurves.sketchFittedSplines.add(points)  

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
Tomato1107 commented 2 years ago

The script works now, and still need some time to improve the whole functions.