"""Три шарика опираются на три пары стальных стержней. Магниты под опорами дают предварительный прижим. Шарики закрепляются в верхней детали, точность проверяется измерением.""" import FreeCAD # noqa: F401 (initialize the CAD runtime first) # isort: split import math import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parents[1])) from common import Part, Piece, Pose, V, cyl, main, params, require MODEL_ID = "kinematic" DEFAULTS = { "base_radius": 27, "station_radius": 17, "ball_radius": 3, "rod_radius": 2, "rod_spacing": 7, "rod_length": 12, "plate_thickness": 3, "clearance": 0.05, } NOTE = "Три шарика опираются на три пары стальных стержней. Магниты под опорами дают предварительный прижим. Шарики закрепляются в верхней детали, точность проверяется измерением." MODE = "rigid" def make_parts(supplied=None): p = params(DEFAULTS, supplied) ro, s, r, rr, space, l, b, c = [ p[k] for k in ( "base_radius", "station_radius", "ball_radius", "rod_radius", "rod_spacing", "rod_length", "plate_thickness", "clearance", ) ] require( ro > s + l / 2 and rr + r + c > space / 2 and space > 2 * rr, "Ball must bridge each pair of rods", ) rod_z = 4.8 ball_z = rod_z + math.sqrt((r + rr + c) ** 2 - (space / 2) ** 2) base = cyl(ro, 3) plate = cyl(ro - 2, b, (0, 0, ball_z + r - 0.4)) parts = [] for j, angle in enumerate((90, 210, 330)): ar = math.radians(angle) x, y = s * math.cos(ar), s * math.sin(ar) for k, dy in enumerate((-space / 2, space / 2)): rod = ( cyl(rr, l, (-l / 2, dy, rod_z), (1, 0, 0)) .rotated(V(), V(0, 0, 1), angle) .translated(V(x, y, 0)) ) base = base.cut( cyl(rr + 0.05, l, (-l / 2, dy, rod_z), (1, 0, 0)) .rotated(V(), V(0, 0, 1), angle) .translated(V(x, y, 0)) ) parts.append( Piece(f"rod{j}{k}", "Контактный стержень", rod, role="hardware") ) sphere = Part.makeSphere(r, V(x, y, ball_z)) plate = plate.cut(Part.makeSphere(r + c, V(x, y, ball_z))) parts.append( Piece( f"ball{j}", "Сферическая опора", sphere, lambda t: Pose(offset=(0, 0, 18 * (1 - t))), role="hardware", ) ) magnet = cyl(2.8, 2, (x, y, 0.5)) base = base.cut(cyl(2.9, 2.1, (x, y, 0.5))) parts.append( Piece( f"magnet{j}", "Магнит предварительного прижима", magnet, role="hardware" ) ) return [ Piece("receiver", "Основание трёх опор", base), Piece( "plate", "Сменная площадка", plate, lambda t: Pose(offset=(0, 0, 18 * (1 - t))), ), *parts, ] if __name__ == "__main__": main(make_parts, DEFAULTS, MODEL_ID, __file__, NOTE, MODE)