How to create a custom joint direction for a revolute joint motion?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
I am trying to create a script using Fusion360 API to automatically generate a Bennett mechanism with basic geometry as the link.
Here is what a Bennett mechanism looks like.
So I need to joint two links as revolute joint but the joint axis is not a regular axis such xAxis or zAxis. I need to create a revolute joint axis with a twist angle.
Currently I think there are two ways:
1. Use customRotationAxisEntity when setting joinInput:
jointInput_var.setAsRevoluteJointMotion(rotationAxis, customRotationAxisEntity)
but customRotationAxisEntity can only be linear BRepEdge, ConstructionAxis, or a SketchLine(Am I right?). This is not very convenient to set a custom rotation axis.
2. Change the jointOrign's axis at first and then use whatever axis for example xAxis:
# Set the value of the property.
jointOrigin_var.xAxisEntity = propertyValue
I am not sure with the second method so I try the first method. Here is my code:
#Author-
#Description-
import adsk.core, adsk.fusion, adsk.cam, traceback
import math
def generateBox(x, y, z, rootCom: adsk.fusion.Component) -> adsk.fusion.Component:
"""
generate a box component inside rootComponent
box is a basic geometry element of SDF:
http://sdformat.org/spec?ver=1.10&elem=geometry#geometry_box
x, y, z unit: m
return: component generated by extrude object
"""
extrudes = rootCom.features.extrudeFeatures
x = x*100.0 # convert from m to cm
y = y*100.0
z = z*100.0
# Create a new sketch on the xy plane
sketches = rootCom.sketches
xyPlane = rootCom.xYConstructionPlane
sketch = sketches.add(xyPlane)
# Draw a rectangle on the xy plane
point1 = adsk.core.Point3D.create(-x/2, y/2, 0.0)
point2 = adsk.core.Point3D.create(x/2, y/2, 0.0)
point3 = adsk.core.Point3D.create(x/2, -y/2, 0.0)
point4 = adsk.core.Point3D.create(-x/2, -y/2, 0.0)
sketch_lines = sketch.sketchCurves.sketchLines
line1 = sketch_lines.addByTwoPoints(point1, point2)
line2 = sketch_lines.addByTwoPoints(point2, point3)
line3 = sketch_lines.addByTwoPoints(point3, point4)
line4 = sketch_lines.addByTwoPoints(point4, point1)
# Get the profile defined by the four lines
prof = sketch.profiles.item(0)
# Define the distance to extrude
distance = adsk.core.ValueInput.createByReal(z)
# extrude = extrudes.addSimple(prof, distance, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
extrude = extrudes.addSimple(prof, distance, adsk.fusion.FeatureOperations.NewComponentFeatureOperation)
return extrude.parentComponent
def rotateZ(degree)->adsk.core.Matrix3D:
"""
retrun a transform matrix to rotate about world frame's z-axis with degree
"""
rotZ = adsk.core.Matrix3D.create()
rotZ.setCell(0, 0, math.cos(math.radians(degree)))
rotZ.setCell(1, 0, math.sin(math.radians(degree)))
rotZ.setCell(2, 0, 0.0)
rotZ.setCell(3, 0, 0.0)
rotZ.setCell(0, 1, -math.sin(math.radians(degree)))
rotZ.setCell(1, 1, math.cos(math.radians(degree)))
rotZ.setCell(2, 1, 0.0)
rotZ.setCell(3, 1, 0.0)
rotZ.setCell(0, 2, 0.0)
rotZ.setCell(1, 2, 0.0)
rotZ.setCell(2, 2, 1.0)
rotZ.setCell(3, 2, 0.0)
rotZ.setCell(0, 3, 0.0)
rotZ.setCell(1, 3, 0.0)
rotZ.setCell(2, 3, 0.0)
rotZ.setCell(3, 3, 1.0)
def run(context):
ui = None
try:
app = adsk.core.Application.get()
ui = app.userInterface
textPalette = ui.palettes.itemById("TextCommands")
if not textPalette.isVisible:
textPalette.isVisible = True
# doc = app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType)
product = app.activeProduct
design = adsk.fusion.Design.cast(product)
# design.designType = adsk.fusion.DesignTypes.ParametricDesignType
design.designType = adsk.fusion.DesignTypes.DirectDesignType
rootComp = design.rootComponent
extBox = generateBox(0.1, 0.1, 1, rootComp)
# textPalette.writeText("num of bRepBodies: {}".format(extBox.bRepBodies.count))
extBody = extBox.bRepBodies.item(0)
# textPalette.writeText("num of bRepFaces: {}".format(extBody.faces.count))
extJointFace1 = extBody.faces.item(4) # item 4 is the end extrude face, item 5 is the start extrude face
point1 = extJointFace1.centroid
# for i in range(6):
# textPalette.writeText("bRepFace areas: {}".format(extBody.faces.item(i).area))
# Create the joint geometry
jointGeo = adsk.fusion.JointGeometry.createByPlanarFace(extJointFace1, None, adsk.fusion.JointKeyPointTypes.CenterKeyPoint)
jointOrigins = extBox.jointOrigins
jointOriginInput = jointOrigins.createInput(jointGeo)
jointOrigin1 = jointOrigins.add(jointOriginInput)
# jointXAxis = jointOrigin1.secondaryAxisVector
extBox2 = generateBox(0.1, 0.1, 0.5, rootComp)
extBody2 = extBox2.bRepBodies.item(0)
extJointFace2 = extBody2.faces.item(4)
jointGeo2 = adsk.fusion.JointGeometry.createByPlanarFace(extJointFace2, None, adsk.fusion.JointKeyPointTypes.CenterKeyPoint)
jointOrigins2 = extBox2.jointOrigins
jointOriginInput2 = jointOrigins.createInput(jointGeo2)
jointOrigin2 = jointOrigins2.add(jointOriginInput2)
# Define a axis of rotation
# This can be a linear BRepEdge, ConstructionAxis, or a SketchLine
sketches1 = extBox.sketches
sketch = sketches1.add(extJointFace1)
sketchOrigin = sketch.origin
sketchOriginPoint = sketch.originPoint
theta = 30 # degree
sketchPoint1 = adsk.core.Point3D.create(0.0, 0.0, 0.0)
sketchPoint2 = adsk.core.Point3D.create(math.cos(math.radians(theta))*10, math.sin(math.radians(theta))*10, 0.0)
sketchLine = sketch.sketchCurves.sketchLines.addByTwoPoints(sketchPoint1, sketchPoint2)
textPalette.writeText("sketch line isVisible: {}".format(sketchLine.isVisible))
textPalette.writeText("sketch line is2D: {}".format(sketchLine.is2D))
textPalette.writeText("sketch line length: {}".format(sketchLine.length))
# Create jont
joints = rootComp.joints
jointInput = joints.createInput(jointOrigin1, jointOrigin2)
# jointInput.setAsRevoluteJointMotion(adsk.fusion.JointDirections.XAxisJointDirection)
jointInput.setAsRevoluteJointMotion(adsk.fusion.JointDirections.CustomJointDirection, sketchLine)
joint1 = joints.add(jointInput)
joint1Motion = joint1.jointMotion
except:
if ui:
ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
But I got an RuntimeError:
joint1 = joints.add(jointInput)
RuntimeError: 2 : InternalValidationError : Utils::getObjectPath(object, objPath, nullptr, context)
I don't know what is going on.
Can anyone help me with my error or tell me how to create revolute joint with custom axis?
Thanks a lot!
😀