

齿轮装配定位的几个核心动作:移动到正确的中心距、旋转到正确的啮合相位以及不同厚度齿轮的对中。
1)计算中心距 (Translation)
无论是直齿轮还是斜齿轮,标准圆柱齿轮的中心距 a 取决于法向模数 m_n、齿数z1, z2以及螺旋角beta。中心距计算公式为,

对于直齿轮,螺旋角 beta=0,cos0=1,公式自动退化为直齿轮中心距公式。
2)啮合相位补偿 (Rotation)
如前所述,在建立齿轮三维模型时,两个齿轮的中心都在原点 (0,0,0),且X轴正向都穿过某单个轮齿的正中心。当把从动轮沿X轴平移了中心距 a 后,两者的齿顶位置会发生重叠。为了让齿顶正好嵌入齿槽,主动轮需要绕其自身轴线旋转半个齿距角,

3)对中 (Alignment)
通过判断两个齿轮宽度是否相等,平移其中一个齿轮,平移距离为,
主要通过装配体对象的平移(translate)和旋转(rotate)方法实现装配定位。
因程序接口上移到asm模块,需要调整标准圆柱齿轮gear模块的代码,一个是形参取消默认值,另一个,因需要直接操作Part,把create_gear_part函数返回值改为Part对象。代码如下所示,
# -*- coding: utf-8 -*-import mathfrom abaqus import *from abaqusConstants import *import partimport sketchimport assemblydef calculate_gear_geometry(mn, z, beta, num_pts, alpha_n, ha, c, r_f):"""函数功能:计算斜齿轮(或直齿轮)在端面上的各项几何参数以及渐开线齿廓的坐标点阵。基于端面参数计算分度圆、基圆、齿顶圆、齿根圆等,并生成用于绘制齿廓的渐开线散点坐标。参数说明::param mn: 法面模数 (Normal module),单位:mm:param z: 齿数 (Number of teeth):param alpha_n: 法面压力角 (Normal pressure angle),单位:度 (°):param beta: 螺旋角 (Helix angle),单位:度 (°)。0表示直齿,非0表示斜齿,正值为右旋,负值为左旋:param ha: 齿顶高系数 (Addendum coefficient),标准齿轮通常为 1.0:param c: 顶隙系数 (Clearance coefficient),标准齿轮通常为 0.25:param r_f: 齿根圆角半径系数 (Root fillet radius coefficient),通常为 0.38:param num_pts: 渐开线拟合点数 (Number of points for involute curve),点越多曲线越平滑返回::return: geom_info (dict),包含端面模数、各项半径、导程、以及左右渐开线坐标点的字典"""# ================= 参数转换 (法面 -> 端面) =================beta_rad = math.radians(beta)alpha_n_rad = math.radians(alpha_n)# 端面模数 (mt)mt = mn / math.cos(beta_rad)# 端面压力角 (alpha_t)alpha_t_rad = math.atan(math.tan(alpha_n_rad) / math.cos(beta_rad))# 端面主要几何参数d = z * mt # 端面分度圆直径r = d / 2.0 # 端面分度圆半径rb = r * math.cos(alpha_t_rad) # 端面基圆半径ra = r + mn * ha # 齿顶圆半径rf = r - mn * (ha + c) # 齿根圆半径r_k = r_f * mn # 齿根圆角半径# 导程 (用于扭转拉伸)if abs(beta) < 1.0e-12:# 平行拉伸 (无扭转),直齿lead = 0.0else:# 扭转拉伸 (螺旋线),斜齿lead = math.pi * d / math.tan(beta_rad)theta_0 = math.pi / (2.0 * z) # 半齿厚角 (分度圆处)r_start_inv = max(rb, rf) # 渐开线起点半径# 渐开线函数 inv(alpha_t)inv_alpha_t = math.tan(alpha_t_rad) - alpha_t_rad# 渐开线点阵 (在端平面内)# 右侧渐开线节点计算 (从 r_start_inv 到 ra)right_inv = []for i in range(num_pts):R = r_start_inv + (ra - r_start_inv) * i / float(num_pts - 1)phi_R = math.acos(rb / R)inv_phi_R = math.tan(phi_R) - phi_Rtheta_R = theta_0 + inv_alpha_t - inv_phi_Rx = R * math.cos(theta_R)y = R * math.sin(theta_R)right_inv.append((x, y))# 左侧镜像参数 (关于 X 轴对称)left_inv = [(x, -y) for (x, y) in right_inv]geom_info = {'mt': mt, 'z': z, 'r': r, 'rb': rb, 'ra': ra, 'rf': rf, 'r_k': r_k, 'lead': lead,'r_start_inv': r_start_inv,'right_inv': right_inv,'left_inv': left_inv}return geom_infodef create_gear_part(model_name, part_name, mn, z, width, r_shaft, beta,num_pts, alpha_n, ha, c, r_f):"""函数功能:调用 calculate_gear_geometry 计算齿轮几何数据,并在 Abaqus 中自动化构建 3D 齿轮 Part 模型。建模思路为:先拉伸一个齿轮基体圆柱(带轴孔),再拉伸一个单齿模型,最后通过装配模块进行阵列和布尔求和操作,得到完整齿轮。参数说明::param model_name: Abaqus 模型名称 (例如: 'Model-1'):param part_name: 生成的齿轮 Part 名称 (例如: 'Gear'):param mn, z, alpha_n, beta, ha, c, r_f, num_pts: 齿轮基本参数 (同上):param width: 齿轮齿宽 (拉伸深度),单位:mm:param r_shaft: 中心轴孔半径,单位:mm返回::return: gear_part (Abaqus Part Object),返回合并后的最终 3D 齿轮 Part 实体"""if model_name in mdb.models:model = mdb.models[model_name]else:model = mdb.Model(name=model_name)# 获取齿轮几何参数g = calculate_gear_geometry(mn, z, beta, num_pts, alpha_n, ha, c, r_f)# 计算草图尺寸 (基于齿顶圆半径)sketch_size = g['ra'] * 3.0#创建齿轮基体s_base = model.ConstrainedSketch(name=part_name + '_Base_Sketch', sheetSize=sketch_size)s_base.CircleByCenterPerimeter(center=(0.0, 0.0), point1=(g['rf'], 0.0))# 绘制中心轴孔 (检查轴孔不能大于等于齿根圆)if (r_shaft > 0 and r_shaft < g['rf']):s_base.CircleByCenterPerimeter(center=(0.0, 0.0), point1=(r_shaft, 0.0))else:raise ValueError("Shaft radius must be greater than 0 and less than the root radius of the gear.")# 拉伸生成 3D 基体实体part_base = model.Part(name=part_name + '_Base', dimensionality=THREE_D, type=DEFORMABLE_BODY)part_base.BaseSolidExtrude(sketch=s_base, depth=width)# 创建单齿草图 (齿廓)s_tooth = model.ConstrainedSketch(name=part_name + '_Tooth_Sketch', sheetSize=sketch_size)# 计算一个齿距对应的齿根圆上的两个端点 (用于画齿根圆弧)point_R=(g['rf'] * math.cos(math.pi / g['z']), g['rf'] * math.sin(math.pi / g['z']))point_L=(g['rf'] * math.cos(math.pi / g['z']), -g['rf'] * math.sin(math.pi / g['z']))# 绘制齿槽底部的齿根圆弧段 (顺时针)g1 = s_tooth.ArcByCenterEnds(center=(0.0, 0.0),point1=point_R,point2=point_L, direction=CLOCKWISE)# 使用样条曲线(Spline)拟合生成左右渐开线齿廓g2 = s_tooth.Spline(points=tuple(g['left_inv']))g3 = s_tooth.Spline(points=tuple(g['right_inv']))# 绘制齿顶圆弧,连接左右渐开线的终点 (逆时针)g4 = s_tooth.ArcByCenterEnds(center=(0.0, 0.0),point1=g['left_inv'][-1],point2=g['right_inv'][-1],direction=COUNTERCLOCKWISE)# 将主要几何特征固定,防止添加倒角时发生意外变形s_tooth.FixedConstraint(entity=g1)s_tooth.FixedConstraint(entity=g2)s_tooth.FixedConstraint(entity=g3)s_tooth.FixedConstraint(entity=g4)# ================= 处理齿根过渡圆角 =================# 1):齿根圆小于基圆 (rf < rb),存在根切风险或过渡区域# 这时渐开线只能从基圆开始,基圆到齿根圆之间需要用直线(通常是刀具顶部的包络线,这里用切向直线近似)连接if g['rf'] < g['rb']:# 绘制两条直线段,大概长度为齿全高g5 = s_tooth.Line(point1=(g['right_inv'][0]), point2=(g['right_inv'][0][0] - (2*ha + c)* mn, 0))g6 = s_tooth.Line(point1=(g['left_inv'][0]), point2=(g['left_inv'][0][0] - (2*ha + c)* mn, 0))# 将这两条直线与渐开线起点处设为相切s_tooth.TangentConstraint(entity1=g5, entity2=g3)s_tooth.TangentConstraint(entity1=g6, entity2=g2)# 计算这直线的斜率,以便在直线上找点进行后续操作p1 = g5.pointOnp2 = g6.pointOnk1 = (p1[1] - g['right_inv'][0][1]) / (p1[0] - g['right_inv'][0][0])k2 = (p2[1] - g['left_inv'][0][1]) / (p2[0] - g['left_inv'][0][0])# 在直线上取点用于获取几何实体的id,进行圆角操作p5 = (g['right_inv'][0][0] - g['r_k']/2.0, g['right_inv'][0][1] - k1 * g['r_k']/2.0)p6 = (g['left_inv'][0][0] - g['r_k']/2.0, g['left_inv'][0][1] - k2 * g['r_k']/2.0)# 修剪掉直线段多余的部分(超过齿根圆的部分),以便后续进行圆角操作s_tooth.autoTrimCurve(curve1=g5, point1=(g['right_inv'][0][0] - (2*ha + c)* mn, 0))s_tooth.autoTrimCurve(curve1=g6, point1=(g['left_inv'][0][0] - (2*ha + c)* mn, 0))# 重新获取修剪后的直线段实体g55 = s_tooth.geometry.findAt(p5)g66 = s_tooth.geometry.findAt(p6)# 在直线段和齿根圆弧之间创建过渡倒圆角 (半径为 r_k)s_tooth.FilletByRadius(radius=g['r_k'],curve1=g55, nearPoint1=g['right_inv'][0],curve2=g1, nearPoint2=point_R)s_tooth.FilletByRadius(radius=g['r_k'],curve1=g66, nearPoint1=g['left_inv'][0],curve2=g1, nearPoint2=point_L)# 2):齿根圆大于等于基圆 (rf >= rb)# 这时渐开线直接从齿根圆上生出,直接在渐开线和齿根圆之间倒圆角即可else:# 在直线段和齿根圆弧之间创建过渡倒圆角 (半径为 r_k)s_tooth.FilletByRadius(radius=g['r_k'],curve1=g3, nearPoint1=g['right_inv'][1],curve2=g1, nearPoint2=point_R)s_tooth.FilletByRadius(radius=g['r_k'],curve1=g2, nearPoint1=g['left_inv'][1],curve2=g1, nearPoint2=point_L)part_tooth = model.Part(name=part_name + '_SingleTooth', dimensionality=THREE_D, type=DEFORMABLE_BODY)if abs(g['lead']) < 1.0e-12:# 平行拉伸 (无扭转),直齿part_tooth.BaseSolidExtrude(sketch=s_tooth, depth=width)else:# 扭转拉伸 (螺旋线),斜齿# 添加孤立点 (Spot) 以支持扭曲拉伸s_tooth.Spot(point=(0.0, 0.0))part_tooth.BaseSolidExtrude(sketch=s_tooth, depth=width, pitch=g['lead'])# =========================================================================# 在 Assembly 中进行周向阵列与布尔合并# =========================================================================asm = model.rootAssemblyinst_base = asm.Instance(name='Inst-Base', part=part_base, dependent=ON)inst_tooth = asm.Instance(name='Inst-Tooth-0', part=part_tooth, dependent=ON)# 默认Z轴为旋转轴,周向阵列单齿 Instanceif z > 1:asm.RadialInstancePattern(instanceList=('Inst-Tooth-0',),number=z,totalAngle=360.0)# 获取所有装配实例进行布尔合并all_insts = [asm.instances[inst_name] for inst_name in asm.instances.keys()]# 返回的是PartInstance对象,而不是Partasm.InstanceFromBooleanMerge(name=part_name, # 合并后生成的新 Part 名称instances=tuple(all_insts), # 参与合并的所有实体 InstanceoriginalInstances = DELETE, # 合并后删除原有实例domain = GEOMETRY # 针对几何实体进行布尔合并)asm.deleteAllFeatures() # 删除所有实例,避免重复del all_insts # 删除实例列表return model.parts[part_name] # 返回最终生成的齿轮 Part 对象
asm模块代码如下,
# -*- coding: utf-8 -*-from zxwc.gear.gear import create_gear_partfrom abaqus import *from abaqusConstants import *import assemblyimport mathdef asm_gear(model_name, part_name,mn, z1, z2, width1, width2, r_shaft1, r_shaft2,beta=0.0, num_pts= 40, alpha_n=20.0, ha=1.0, c=0.25, r_f=0.38):# 创建两个齿轮零件sg1 = create_gear_part(model_name, part_name + '1', mn, z1, width1, r_shaft1, beta, num_pts,alpha_n, ha, c, r_f)sg2 = create_gear_part(model_name, part_name + '2', mn, z2, width2, r_shaft2, -beta, num_pts,alpha_n, ha, c, r_f)asm = mdb.models[model_name].rootAssembly# 计算斜齿轮的螺旋角弧度beta_rad = math.radians(beta)# 计算齿轮中心距center_distance = (mn * (z1 + z2)) / (2.0* math.cos(beta_rad))# 齿轮的旋转角度,半个齿距对应的角度rotate_angle = 180.0 / z1# 创建两个齿轮的实例inst_1 = asm.Instance(name='Inst-' + sg1.name, part=sg1, dependent=ON)inst_2 = asm.Instance(name='Inst-' + sg2.name, part=sg2, dependent=ON)# 设置齿轮位置# 沿着x轴平移第二个齿轮到正确的中心距离asm.translate(instanceList=(inst_2.name,), vector=(center_distance, 0.0, 0.0))# 沿着z轴旋转主动轮(第一个齿轮)到正确的位置asm.rotate(instanceList=(inst_1.name,), axisPoint=(0.0, 0.0, 0.0), axisDirection=(0.0, 0.0, 1.0), angle=rotate_angle)if abs(width1 - width2) > 1.0e-12:# 如果两个齿轮的宽度不同,需要调整它们的位置以确保正确啮合,沿着Z轴平移asm.translate(instanceList=(inst_2.name,), vector=(0.0, 0.0, (width1 - width2)/2.0))#testif __name__ == "__main__":#创建一对斜齿轮asm_gear("Helical", "hg", mn=2, z1=21, z2=24, width1=18, width2=20, r_shaft1=8, r_shaft2=8, beta=10.0)

1)脚本中除去逻辑判断和数学运算外,几乎所有操作都是针对特定对象的,函数调用的传参和返回值,一定要明确对象的类型是否匹配。如InstanceFromBooleanMerge函数返回的不是Part对象,而是Part实例。

2)实参顺序和函数定义的形参顺序需要匹配、准确,尤其是像calculate_gear_geometry、create_gear_part以及asm_gear这种套娃形式。调用函数的时候,最好改用关键字参数传递,如上面调用asm_gear函数的测试代码。
asm_gear(model_name, part_name,mn, z1, z2, width1, width2, r_shaft1, r_shaft2,beta=0.0, num_pts= 40, alpha_n=20.0, ha=1.0, c=0.25, r_f=0.38)
create_gear_part(model_name, part_name, mn, z, width, r_shaft, beta,num_pts, alpha_n, ha, c, r_f)
calculate_gear_geometry(mn, z, beta, num_pts, alpha_n, ha, c, r_f)