Save stuff; ball screw model is finished, gantry's somewhat assembled
This commit is contained in:
parent
8923d5ef58
commit
8e7fe382d2
|
@ -0,0 +1,222 @@
|
||||||
|
import cadquery as cq
|
||||||
|
from ocp_vscode import *
|
||||||
|
from utils import *
|
||||||
|
|
||||||
|
import localselectors
|
||||||
|
|
||||||
|
tube_w = inch(2.0)
|
||||||
|
tube_h = inch(1.5)
|
||||||
|
tube_wall = inch(0.075) # 1.519 #inch(0.062)
|
||||||
|
column_spacing = 500
|
||||||
|
column_h = 400
|
||||||
|
plate_z = 2.54
|
||||||
|
plate_z2 = 10
|
||||||
|
|
||||||
|
x_rail_spacing = 240
|
||||||
|
x_carriage_spacing = 120
|
||||||
|
|
||||||
|
class Gantry:
|
||||||
|
def __init__(self, w):
|
||||||
|
self.left = tubing(
|
||||||
|
column_h,
|
||||||
|
tube_w,
|
||||||
|
tube_h,
|
||||||
|
tube_wall,
|
||||||
|
w.transformed(offset=(-0.5*column_spacing, 0, 0)))
|
||||||
|
self.right = tubing(
|
||||||
|
column_h,
|
||||||
|
tube_w,
|
||||||
|
tube_h,
|
||||||
|
tube_wall,
|
||||||
|
w.transformed(offset=(0.5*column_spacing, 0, 0)))
|
||||||
|
upper_center = column_h - 0.5*tube_w
|
||||||
|
self.upper = tubing(
|
||||||
|
column_spacing - tube_w,
|
||||||
|
tube_h,
|
||||||
|
tube_w,
|
||||||
|
tube_wall,
|
||||||
|
w.transformed(offset=(-0.5*column_spacing+0.5*tube_w, 0, upper_center), rotate=(90, 90, 0)))
|
||||||
|
lower_center = upper_center - x_rail_spacing
|
||||||
|
self.lower = tubing(
|
||||||
|
column_spacing - tube_w,
|
||||||
|
tube_h,
|
||||||
|
tube_w,
|
||||||
|
tube_wall,
|
||||||
|
w.transformed(
|
||||||
|
offset=(
|
||||||
|
-0.5*column_spacing+0.5*tube_w,
|
||||||
|
0,
|
||||||
|
lower_center), rotate=(90, 90, 0)))
|
||||||
|
self.upper_rail = HGR20(
|
||||||
|
w.transformed(
|
||||||
|
offset=(0, 0.5*tube_h + plate_z, upper_center),
|
||||||
|
rotate=(-90, 0, 0)
|
||||||
|
), column_spacing + tube_w)
|
||||||
|
self.lower_rail = HGR20(
|
||||||
|
w.transformed(
|
||||||
|
offset=(0, 0.5*tube_h + plate_z, lower_center),
|
||||||
|
rotate=(-90, 0, 0)
|
||||||
|
), column_spacing + tube_w)
|
||||||
|
self.upper_front_plate = (
|
||||||
|
w.transformed(offset=(0, tube_h/2, upper_center), rotate=(-90, 0, 0))
|
||||||
|
.rect(column_spacing + tube_w, tube_w)
|
||||||
|
.extrude(plate_z)
|
||||||
|
)
|
||||||
|
self.lower_front_plate = (
|
||||||
|
w.transformed(offset=(0, tube_h/2, lower_center), rotate=(-90, 0, 0))
|
||||||
|
.rect(column_spacing + tube_w, tube_w)
|
||||||
|
.extrude(plate_z)
|
||||||
|
)
|
||||||
|
self.upper_back_plate = (
|
||||||
|
w.transformed(offset=(0, -tube_h/2, upper_center), rotate=(90, 0, 0))
|
||||||
|
.rect(column_spacing + tube_w, tube_w)
|
||||||
|
.extrude(plate_z)
|
||||||
|
)
|
||||||
|
self.lower_back_plate = (
|
||||||
|
w.transformed(offset=(0, -tube_h/2, lower_center), rotate=(90, 0, 0))
|
||||||
|
.rect(column_spacing + tube_w, tube_w)
|
||||||
|
.extrude(plate_z)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.upper_front_plate = self.upper_rail.holes(self.upper_front_plate)
|
||||||
|
self.upper_back_plate = self.upper_rail.holes(self.upper_back_plate)
|
||||||
|
|
||||||
|
self.lower_front_plate = self.lower_rail.holes(self.lower_front_plate)
|
||||||
|
self.lower_back_plate = self.lower_rail.holes(self.lower_back_plate)
|
||||||
|
|
||||||
|
def assembly(self):
|
||||||
|
return (cq.Assembly(name="gantry")
|
||||||
|
.add(self.left, name="left column")
|
||||||
|
.add(self.right, name="right column")
|
||||||
|
.add(self.upper, name="upper platform")
|
||||||
|
.add(self.lower, name="lower platform")
|
||||||
|
.add(self.upper_rail.rail(), name="upper rail")
|
||||||
|
.add(self.lower_rail.rail(), name="lower rail")
|
||||||
|
.add(self.upper_front_plate, name="upper front plate")
|
||||||
|
.add(self.lower_front_plate, name="lower front plate")
|
||||||
|
.add(self.upper_back_plate, name="upper back plate")
|
||||||
|
.add(self.lower_back_plate, name="lower back plate")
|
||||||
|
)
|
||||||
|
#assembly.test = 7
|
||||||
|
|
||||||
|
z_rail_spacing = 120
|
||||||
|
z_carriage_spacing = 100
|
||||||
|
z_rail_len = 450
|
||||||
|
carriage_w = 250
|
||||||
|
carriage_h = 300
|
||||||
|
bolster_w = 30
|
||||||
|
bolster_z = 25
|
||||||
|
class Carriage:
|
||||||
|
def __init__(self, gantry, x=0, z=0):
|
||||||
|
self.bul = gantry.upper_rail.carriage(x)
|
||||||
|
self.bur = gantry.upper_rail.carriage(x+x_carriage_spacing)
|
||||||
|
self.bll = gantry.lower_rail.carriage(x)
|
||||||
|
self.blr = gantry.lower_rail.carriage(x+x_carriage_spacing)
|
||||||
|
back = cq.Workplane("XZ").copyWorkplane(self.bul.workplaneFromTagged("mountingholes"))
|
||||||
|
# why doesn't this track the carriage without me adding x to it?
|
||||||
|
self.plate = (back.center(-x-HGR20.L-x_carriage_spacing/2, -x_rail_spacing/2)
|
||||||
|
#.rect(HGR20.L+x_carriage_spacing, HGR20.W+x_rail_spacing)
|
||||||
|
.rect(carriage_w, carriage_h)
|
||||||
|
.extrude(plate_z2)
|
||||||
|
.faces(">z") # localselectors plugin
|
||||||
|
.workplane()
|
||||||
|
.tag("carriage_plate")
|
||||||
|
)
|
||||||
|
self.plate = gantry.upper_rail.carriageHoles(self.plate, x)
|
||||||
|
self.plate = gantry.upper_rail.carriageHoles(self.plate, x+x_carriage_spacing)
|
||||||
|
self.plate = gantry.lower_rail.carriageHoles(self.plate, x)
|
||||||
|
self.plate = gantry.lower_rail.carriageHoles(self.plate, x+x_carriage_spacing)
|
||||||
|
|
||||||
|
# creating the workplane the rails of the spindle carrier
|
||||||
|
# mount to, because HGR works from that plane forward
|
||||||
|
self.carrier_plane = (cq.Workplane()
|
||||||
|
.copyWorkplane(self.plate.workplaneFromTagged("carriage_plate"))
|
||||||
|
.transformed(offset=(0, 0, HGR20.H), rotate=(180, 0, 0))
|
||||||
|
)
|
||||||
|
|
||||||
|
self.left_rail = HGR20(
|
||||||
|
self.carrier_plane.
|
||||||
|
transformed(offset=(z_rail_spacing/2, z, 0), rotate=(0, 0, 90)),
|
||||||
|
z_rail_len)
|
||||||
|
self.right_rail = HGR20(
|
||||||
|
self.carrier_plane.
|
||||||
|
transformed(offset=(-z_rail_spacing/2, z, 0), rotate=(0, 0, 90)),
|
||||||
|
z_rail_len)
|
||||||
|
|
||||||
|
u_zcarriage_pos = z_rail_len/2 - HGR20.L/2 -z - z_carriage_spacing/2
|
||||||
|
l_zcarriage_pos = u_zcarriage_pos + z_carriage_spacing
|
||||||
|
self.ful = self.left_rail.carriage(u_zcarriage_pos)
|
||||||
|
self.fll = self.left_rail.carriage(l_zcarriage_pos)
|
||||||
|
self.fur = self.right_rail.carriage(u_zcarriage_pos)
|
||||||
|
self.flr = self.right_rail.carriage(l_zcarriage_pos)
|
||||||
|
|
||||||
|
self.plate = self.left_rail.carriageHoles(self.plate, u_zcarriage_pos)
|
||||||
|
self.plate = self.left_rail.carriageHoles(self.plate, l_zcarriage_pos)
|
||||||
|
self.plate = self.right_rail.carriageHoles(self.plate, u_zcarriage_pos)
|
||||||
|
self.plate = self.right_rail.carriageHoles(self.plate, l_zcarriage_pos)
|
||||||
|
|
||||||
|
self.lbolster = (cq.Workplane()
|
||||||
|
.copyWorkplane(self.plate.workplaneFromTagged("carriage_plate"))
|
||||||
|
.transformed(offset=(-(carriage_w - bolster_w)/2, 0, 0))
|
||||||
|
.rect(bolster_w, carriage_h)
|
||||||
|
.extrude(bolster_z)
|
||||||
|
)
|
||||||
|
self.rbolster = (cq.Workplane()
|
||||||
|
.copyWorkplane(self.plate.workplaneFromTagged("carriage_plate"))
|
||||||
|
.transformed(offset=((carriage_w - bolster_w)/2, 0, 0))
|
||||||
|
.rect(bolster_w, carriage_h)
|
||||||
|
.extrude(bolster_z)
|
||||||
|
)
|
||||||
|
# TODO add bolster mounting holes
|
||||||
|
|
||||||
|
self.wp_carrier = (cq.Workplane()
|
||||||
|
.copyWorkplane(self.plate.workplaneFromTagged("carriage_plate"))
|
||||||
|
.transformed(offset=(0, -z, HGR20.H), rotate=(0, 0, 0))
|
||||||
|
)
|
||||||
|
|
||||||
|
def assembly(self):
|
||||||
|
return (cq.Assembly(name="x carriage")
|
||||||
|
.add(self.bul, name="back ul carriage")
|
||||||
|
.add(self.bur, name="back ur carriage")
|
||||||
|
.add(self.bll, name="back ll carriage")
|
||||||
|
.add(self.blr, name="back lr carriage")
|
||||||
|
.add(self.plate, name="carrier plate")
|
||||||
|
.add(self.left_rail.rail(), name="left rail")
|
||||||
|
.add(self.right_rail.rail(), name="right rail")
|
||||||
|
.add(self.ful, name="front ul carriage")
|
||||||
|
.add(self.fur, name="front ur carriage")
|
||||||
|
.add(self.fll, name="front ll carriage")
|
||||||
|
.add(self.flr, name="front lr carriage")
|
||||||
|
.add(self.lbolster, name="left bolster")
|
||||||
|
.add(self.lbolster, name="right bolster")
|
||||||
|
)
|
||||||
|
|
||||||
|
class Carrier:
|
||||||
|
def __init__(self, carriage):
|
||||||
|
self.plane = carriage.wp_carrier
|
||||||
|
self.plate = (cq.Workplane()
|
||||||
|
.copyWorkplane(self.plane)
|
||||||
|
.rect(200, z_rail_len)
|
||||||
|
.extrude(10))
|
||||||
|
self.plate = carriage.left_rail.holes(self.plate)
|
||||||
|
self.plate = carriage.right_rail.holes(self.plate)
|
||||||
|
|
||||||
|
def assembly(self):
|
||||||
|
return (cq.Assembly(name="z carrier")
|
||||||
|
.add(self.plate, name="z plate"))
|
||||||
|
g = Gantry(cq.Workplane())
|
||||||
|
c = Carriage(g, 150, 0)
|
||||||
|
ca = Carrier(c)
|
||||||
|
|
||||||
|
# TODO add ball screws and associated assembly
|
||||||
|
|
||||||
|
full_assmbly = (cq.Assembly()
|
||||||
|
.add(g.assembly(), name="gantry")
|
||||||
|
.add(c.assembly(), name="carriage")
|
||||||
|
.add(ca.assembly(), name="carrier")
|
||||||
|
)
|
||||||
|
|
||||||
|
show_object(full_assmbly)
|
||||||
|
#show_object(ca.assembly())
|
||||||
|
#show_object(c.assembly())
|
||||||
|
#show_object(g.assembly())
|
|
@ -0,0 +1,140 @@
|
||||||
|
import cadquery as cq
|
||||||
|
|
||||||
|
from cadquery.occ_impl.geom import Vector
|
||||||
|
from cadquery.occ_impl.shape_protocols import (
|
||||||
|
geom_LUT_EDGE,
|
||||||
|
geom_LUT_FACE,
|
||||||
|
)
|
||||||
|
|
||||||
|
from pyparsing import (
|
||||||
|
pyparsing_common,
|
||||||
|
Literal,
|
||||||
|
Word,
|
||||||
|
nums,
|
||||||
|
Optional,
|
||||||
|
Combine,
|
||||||
|
oneOf,
|
||||||
|
Group,
|
||||||
|
infixNotation,
|
||||||
|
opAssoc,
|
||||||
|
)
|
||||||
|
|
||||||
|
def _makeGrammar():
|
||||||
|
"""
|
||||||
|
Define the simple string selector grammar using PyParsing
|
||||||
|
"""
|
||||||
|
|
||||||
|
# float definition
|
||||||
|
point = Literal(".")
|
||||||
|
plusmin = Literal("+") | Literal("-")
|
||||||
|
number = Word(nums)
|
||||||
|
integer = Combine(Optional(plusmin) + number)
|
||||||
|
floatn = Combine(integer + Optional(point + Optional(number)))
|
||||||
|
|
||||||
|
# vector definition
|
||||||
|
lbracket = Literal("(")
|
||||||
|
rbracket = Literal(")")
|
||||||
|
comma = Literal(",")
|
||||||
|
vector = Combine(
|
||||||
|
lbracket + floatn("x") + comma + floatn("y") + comma + floatn("z") + rbracket,
|
||||||
|
adjacent=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
# direction definition
|
||||||
|
simple_dir = oneOf(["X", "Y", "Z", "XY", "XZ", "YZ"] + ["x", "y", "z", "xy", "xz", "yz"])
|
||||||
|
direction = simple_dir("simple_dir") | vector("vector_dir")
|
||||||
|
|
||||||
|
# CQ type definition
|
||||||
|
cqtype = oneOf(
|
||||||
|
set(geom_LUT_EDGE.values()) | set(geom_LUT_FACE.values()), caseless=True,
|
||||||
|
)
|
||||||
|
cqtype = cqtype.setParseAction(pyparsing_common.upcaseTokens)
|
||||||
|
|
||||||
|
# type operator
|
||||||
|
type_op = Literal("%")
|
||||||
|
|
||||||
|
# direction operator
|
||||||
|
direction_op = oneOf([">", "<"])
|
||||||
|
|
||||||
|
# center Nth operator
|
||||||
|
center_nth_op = oneOf([">>", "<<"])
|
||||||
|
|
||||||
|
# index definition
|
||||||
|
ix_number = Group(Optional("-") + Word(nums))
|
||||||
|
lsqbracket = Literal("[").suppress()
|
||||||
|
rsqbracket = Literal("]").suppress()
|
||||||
|
|
||||||
|
index = lsqbracket + ix_number("index") + rsqbracket
|
||||||
|
|
||||||
|
# other operators
|
||||||
|
other_op = oneOf(["|", "#", "+", "-"])
|
||||||
|
|
||||||
|
# named view
|
||||||
|
named_view = oneOf(["front", "back", "left", "right", "top", "bottom"])
|
||||||
|
|
||||||
|
return (
|
||||||
|
direction("only_dir")
|
||||||
|
| (type_op("type_op") + cqtype("cq_type"))
|
||||||
|
| (direction_op("dir_op") + direction("dir") + Optional(index))
|
||||||
|
| (center_nth_op("center_nth_op") + direction("dir") + Optional(index))
|
||||||
|
| (other_op("other_op") + direction("dir"))
|
||||||
|
| named_view("named_view")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
old_getVector = cq.selectors._SimpleStringSyntaxSelector._getVector
|
||||||
|
|
||||||
|
def _getVector(self, pr):
|
||||||
|
if "simple_dir" in pr and pr.simple_dir in cq.selectors._SimpleStringSyntaxSelector.local_axes:
|
||||||
|
return cq.selectors._SimpleStringSyntaxSelector.local_axes[pr.simple_dir]
|
||||||
|
else:
|
||||||
|
return old_getVector(self, pr)
|
||||||
|
|
||||||
|
class LocalCoordinates:
|
||||||
|
def __init__(self, plane):
|
||||||
|
self.plane = plane
|
||||||
|
self.old_axes = None
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
self.old_axes, cq.selectors._SimpleStringSyntaxSelector.local_axes = (cq.selectors._SimpleStringSyntaxSelector.local_axes,
|
||||||
|
{
|
||||||
|
'x': self.plane.xDir,
|
||||||
|
'y': self.plane.yDir,
|
||||||
|
'z': self.plane.zDir,
|
||||||
|
'xy': self.plane.xDir + self.plane.yDir,
|
||||||
|
'yz': self.plane.yDir + self.plane.zDir,
|
||||||
|
'xz': self.plane.xDir + self.plane.zDir,
|
||||||
|
})
|
||||||
|
|
||||||
|
def __exit__(self, _exc_type, _exc_value, _traceback):
|
||||||
|
cq.selectors._SimpleStringSyntaxSelector.local_axes = self.old_axes
|
||||||
|
|
||||||
|
|
||||||
|
def _filter(self, objs, selector):
|
||||||
|
selectorObj: Selector
|
||||||
|
if selector:
|
||||||
|
if isinstance(selector, str):
|
||||||
|
with LocalCoordinates(self.plane):
|
||||||
|
selectorObj = cq.selectors.StringSyntaxSelector(selector)
|
||||||
|
else:
|
||||||
|
selectorObj = selector
|
||||||
|
toReturn = selectorObj.filter(objs)
|
||||||
|
else:
|
||||||
|
toReturn = objs
|
||||||
|
|
||||||
|
return toReturn
|
||||||
|
|
||||||
|
cq.selectors._SimpleStringSyntaxSelector.local_axes = {
|
||||||
|
"x": Vector(1, 0, 0),
|
||||||
|
"y": Vector(0, 1, 0),
|
||||||
|
"z": Vector(0, 0, 1),
|
||||||
|
"xy": Vector(1, 1, 0),
|
||||||
|
"yz": Vector(0, 1, 1),
|
||||||
|
"xz": Vector(1, 0, 1),
|
||||||
|
}
|
||||||
|
cq.selectors._SimpleStringSyntaxSelector._getVector = _getVector
|
||||||
|
|
||||||
|
cq.selectors._grammar = _makeGrammar() # make a grammar instance
|
||||||
|
cq.selectors._expression_grammar = cq.selectors._makeExpressionGrammar(cq.selectors._grammar)
|
||||||
|
|
||||||
|
cq.Workplane._filter = _filter
|
475
utils.py
475
utils.py
|
@ -1,78 +1,453 @@
|
||||||
|
import math
|
||||||
|
|
||||||
import cadquery as cq
|
import cadquery as cq
|
||||||
|
from ocp_vscode import *
|
||||||
|
|
||||||
# pixel coordinates based on a picture in the Hiwin's
|
import localselectors
|
||||||
# linear rail guidebook
|
|
||||||
|
|
||||||
hgr_profile = [
|
class SFU1204:
|
||||||
(0, 0),
|
def __init__(self, base, l):
|
||||||
(37, 0),
|
self.w = base.workplane()
|
||||||
(37 + 6, 6),
|
self.len = l
|
||||||
(96 - 6, 6),
|
|
||||||
(96, 0),
|
def ballscrew(self):
|
||||||
(186-17, 0),
|
profile = [
|
||||||
(186, 17),
|
(0, 0),
|
||||||
(186, 76),
|
(0, 8/2),
|
||||||
(129, 133),
|
(15, 8/2),
|
||||||
(129, 59 + 133),
|
(15, 10/2),
|
||||||
(129 + 20, 59 + 133 + 20),
|
(15+16, 10/2),
|
||||||
(31, 129 + 20 + 31, 133 + 20 + 31),
|
(15+39, 10/2),
|
||||||
(186 - 6, 316 - 42 - 25 - 6),
|
(15+39, 12/2),
|
||||||
(186, 316 - 42 - 25),
|
(self.len - 10, 12/2),
|
||||||
(186, 316 - 42),
|
(self.len - 10, 8/2),
|
||||||
(186 - 6, 316 - 42 + 6 - 1),
|
(self.len, 8/2),
|
||||||
(31, 186 - 6 - 31, 316 - 6 - 1),
|
(self.len, 0),
|
||||||
(143 + 6, 316 - 6),
|
]
|
||||||
(143, 316),
|
w = self.w.moveTo(0, 0)
|
||||||
(0, 316)
|
for v in profile[1:]:
|
||||||
]
|
w = w.lineTo(v[1], v[0])
|
||||||
|
w = w.close()
|
||||||
|
return w.revolve()
|
||||||
|
|
||||||
scale = (10/186*17/316)**0.5
|
def nut(self, x):
|
||||||
|
w = self.w.transformed(offset=(0, x, 0), rotate=(90, 0, 0))
|
||||||
|
n = (w.sketch()
|
||||||
|
.circle(40/2)
|
||||||
|
.circle(12/2, mode='s')
|
||||||
|
.rect(42, 30, mode='i')
|
||||||
|
.finalize()
|
||||||
|
.extrude(10)
|
||||||
|
.faces(">z")
|
||||||
|
.workplane()
|
||||||
|
.tag("nut_face")
|
||||||
|
.sketch()
|
||||||
|
.circle(22/2)
|
||||||
|
.circle(12/2, mode='s')
|
||||||
|
.finalize()
|
||||||
|
.extrude(25))
|
||||||
|
hole_r = 32/2
|
||||||
|
hole_pts = [
|
||||||
|
(hole_r*math.cos(angle*math.pi/180),
|
||||||
|
hole_r*math.sin(angle*math.pi/180)) for angle in
|
||||||
|
[-45, 0, 45, 180-45, 180, 180+45]]
|
||||||
|
n = (n.workplaneFromTagged("nut_face")
|
||||||
|
.pushPoints(hole_pts)
|
||||||
|
.hole(4.8)
|
||||||
|
)
|
||||||
|
return n
|
||||||
|
|
||||||
scaled_profile = [tuple((scale * v for v in vals)) for vals in hgr_profile]
|
def nutHoles(self, solid, x):
|
||||||
|
w = self.w.transformed(offset=(0, x, 0), rotate=(90, 0, 0))
|
||||||
|
hole_r = 32/2
|
||||||
|
hole_pts = [
|
||||||
|
(hole_r*math.cos(angle*math.pi/180),
|
||||||
|
hole_r*math.sin(angle*math.pi/180)) for angle in
|
||||||
|
[-45, 0, 45, 180-45, 180, 180+45]]
|
||||||
|
solid = (solid.copyWorkplane(w)
|
||||||
|
.pushPoints(hole_pts)
|
||||||
|
.hole(4.8))
|
||||||
|
return solid
|
||||||
|
|
||||||
|
def fixedBearing(self):
|
||||||
|
d1 = 12
|
||||||
|
L = 25
|
||||||
|
L1 = 5
|
||||||
|
L2 = 29
|
||||||
|
L3 = 5
|
||||||
|
C1 = 13
|
||||||
|
C2 = 6
|
||||||
|
B = 60
|
||||||
|
H = 43
|
||||||
|
b = 30
|
||||||
|
h = 25
|
||||||
|
B1 = 34
|
||||||
|
H1 = 32.5
|
||||||
|
E = 18
|
||||||
|
P = 46
|
||||||
|
d2 = 5.5
|
||||||
|
X = 6.6
|
||||||
|
Y = 10.8
|
||||||
|
Z = 1.5
|
||||||
|
w = self.w.transformed(offset=(0, 39+15-L, 0), rotate=(-90, 0, 0))
|
||||||
|
w2 = w.transformed(offset=(0, (H-H1)/2, 0))
|
||||||
|
|
||||||
|
bearing = (w
|
||||||
|
.rect(B1, B1)
|
||||||
|
.extrude(L1+L)
|
||||||
|
.copyWorkplane(w2)
|
||||||
|
.rect(B, H1)
|
||||||
|
.extrude(L)
|
||||||
|
.copyWorkplane(w.transformed(rotate=(180, 0, 0)))
|
||||||
|
.hole(d1)
|
||||||
|
.copyWorkplane(w2.transformed(rotate=(180, 0, 0)))
|
||||||
|
.rect(P, E, forConstruction=True)
|
||||||
|
.vertices()
|
||||||
|
.hole(d2)
|
||||||
|
)
|
||||||
|
# TODO the holes on the top surface
|
||||||
|
|
||||||
|
return bearing
|
||||||
|
|
||||||
|
def fixedBearingHoles(self, solid):
|
||||||
|
d1 = 12
|
||||||
|
L = 25
|
||||||
|
L1 = 5
|
||||||
|
L2 = 29
|
||||||
|
L3 = 5
|
||||||
|
C1 = 13
|
||||||
|
C2 = 6
|
||||||
|
B = 60
|
||||||
|
H = 43
|
||||||
|
b = 30
|
||||||
|
h = 25
|
||||||
|
B1 = 34
|
||||||
|
H1 = 32.5
|
||||||
|
E = 18
|
||||||
|
P = 46
|
||||||
|
d2 = 5.5
|
||||||
|
X = 6.6
|
||||||
|
Y = 10.8
|
||||||
|
Z = 1.5
|
||||||
|
|
||||||
|
w = self.w.transformed(offset=(0, 39+15-L, -(H-H1)/2), rotate=(-90, 0, 0))
|
||||||
|
return (solid
|
||||||
|
.copyWorkplane(w)
|
||||||
|
.rect(P, E, forConstruction=True)
|
||||||
|
.vertices()
|
||||||
|
.hole(d2)
|
||||||
|
)
|
||||||
|
|
||||||
|
def floatingBearing(self):
|
||||||
|
d1 = 10
|
||||||
|
L = 20
|
||||||
|
B = 60
|
||||||
|
H = 43
|
||||||
|
b = 30
|
||||||
|
h = 25
|
||||||
|
B1 = 34
|
||||||
|
H1 = 32.5
|
||||||
|
E = 18
|
||||||
|
P = 46
|
||||||
|
d2 = 5.5
|
||||||
|
X = 6.6
|
||||||
|
Y = 10.8
|
||||||
|
Z = 1.5
|
||||||
|
|
||||||
|
w = self.w.transformed(offset=(0, self.len-10, 0), rotate=(-90, 0, 0))
|
||||||
|
b = (w
|
||||||
|
.rect(B1, B1)
|
||||||
|
.extrude(L)
|
||||||
|
.faces(">z")
|
||||||
|
.workplane()
|
||||||
|
.tag("floating_far_end")
|
||||||
|
.copyWorkplane(w)
|
||||||
|
.center(0, (H-H1)/2)
|
||||||
|
.rect(B, H1)
|
||||||
|
.extrude(L)
|
||||||
|
.workplaneFromTagged("floating_far_end")
|
||||||
|
.hole(d1)
|
||||||
|
.workplaneFromTagged("floating_far_end")
|
||||||
|
.center(0, -(H-H1)/2)
|
||||||
|
.rect(P, E, forConstruction=True)
|
||||||
|
.vertices()
|
||||||
|
.hole(d2)
|
||||||
|
)
|
||||||
|
return b
|
||||||
|
|
||||||
|
def floatingBearingHoles(self, solid):
|
||||||
|
d1 = 10
|
||||||
|
L = 20
|
||||||
|
B = 60
|
||||||
|
H = 43
|
||||||
|
b = 30
|
||||||
|
h = 25
|
||||||
|
B1 = 34
|
||||||
|
H1 = 32.5
|
||||||
|
E = 18
|
||||||
|
P = 46
|
||||||
|
d2 = 5.5
|
||||||
|
X = 6.6
|
||||||
|
Y = 10.8
|
||||||
|
Z = 1.5
|
||||||
|
|
||||||
|
w = self.w.transformed(offset=(0, self.len-10+L, 0), rotate=(90, 0, 0))
|
||||||
|
solid = (solid
|
||||||
|
.copyWorkplane(w)
|
||||||
|
.center(0, -(H-H1)/2)
|
||||||
|
.rect(P, E, forConstruction=True)
|
||||||
|
.vertices()
|
||||||
|
.hole(d2)
|
||||||
|
)
|
||||||
|
return solid
|
||||||
|
|
||||||
|
# it's oriented along the y axis of the given base plane
|
||||||
class HGR20:
|
class HGR20:
|
||||||
def __init__(self, base, l):
|
def __init__(self, base, l):
|
||||||
self.base = base.workplane()
|
self.base = base.workplane()
|
||||||
self.l = l
|
self.l = l
|
||||||
|
|
||||||
def holes(self, w):
|
def holes(self, w):
|
||||||
pts = [(0, x-self.l/2) for x in range(20, self.l, 60)]
|
pts = []
|
||||||
print("points", pts)
|
x = 20
|
||||||
|
while x < self.l + 1e-6:
|
||||||
|
pts.append((x - self.l/2, 0))
|
||||||
|
x += 60
|
||||||
w = (w.copyWorkplane(self.base)
|
w = (w.copyWorkplane(self.base)
|
||||||
.transformed(offset=(0,0,17))
|
.transformed(offset=(0,0,17))
|
||||||
.pushPoints(pts)
|
.pushPoints(pts)
|
||||||
.hole(5))
|
.hole(5))
|
||||||
return w
|
return w
|
||||||
|
|
||||||
|
def rail_sketch(s = None):
|
||||||
|
# pixel coordinates based on a picture in the Hiwin's
|
||||||
|
# linear rail guidebook
|
||||||
|
|
||||||
|
hgr_profile = [
|
||||||
|
(0, 0),
|
||||||
|
(37, 0),
|
||||||
|
(37 + 6, 6),
|
||||||
|
(96 - 6, 6),
|
||||||
|
(96, 0),
|
||||||
|
(186-17, 0),
|
||||||
|
(186, 17),
|
||||||
|
(186, 76),
|
||||||
|
(129, 133),
|
||||||
|
(129, 59 + 133),
|
||||||
|
(129 + 20, 59 + 133 + 20),
|
||||||
|
#(31, 129 + 20 + 31, 133 + 20 + 31),
|
||||||
|
(186 - 6, 316 - 42 - 25 - 6),
|
||||||
|
(186, 316 - 42 - 25),
|
||||||
|
(186, 316 - 42),
|
||||||
|
(186 - 6, 316 - 42 + 6 - 1),
|
||||||
|
(31, 186 - 6 - 31, 316 - 6 - 1),
|
||||||
|
(143 + 6, 316 - 6),
|
||||||
|
(143, 316),
|
||||||
|
(0, 316)
|
||||||
|
]
|
||||||
|
scale = (10/186*17/316)**0.5
|
||||||
|
scaled_profile = [tuple((scale * v for v in vals)) for vals in hgr_profile]
|
||||||
|
if s is None:
|
||||||
|
s = cq.Sketch()
|
||||||
|
s = s.segment((0, 0), scaled_profile[1])
|
||||||
|
# TODO do arcs correctly
|
||||||
|
for v in scaled_profile[2:]:
|
||||||
|
if len(v) == 2:
|
||||||
|
s = s.segment(v)
|
||||||
|
else:
|
||||||
|
s = s.segment(v[1:])
|
||||||
|
for v in scaled_profile[-2:0:-1]:
|
||||||
|
if len(v) == 2:
|
||||||
|
s = s.segment((-v[0], v[1]))
|
||||||
|
else:
|
||||||
|
s = s.segment((-v[1], v[2]))
|
||||||
|
s = s.segment((0, 0))
|
||||||
|
return s
|
||||||
|
|
||||||
def rail(self): # workplane or face to use, length of rail
|
def rail(self): # workplane or face to use, length of rail
|
||||||
# TODO rotate w
|
# TODO rotate w
|
||||||
xy = cq.Workplane().copyWorkplane(self.base)
|
xy = cq.Workplane().copyWorkplane(self.base)
|
||||||
w = xy.transformed((90, 0, 0), (0, self.l/2, 0))
|
w = xy.transformed((90, 90, 0), (-self.l/2, 0, 0))
|
||||||
for v in scaled_profile[1:]:
|
w = w.placeSketch(HGR20.rail_sketch().assemble())
|
||||||
if len(v) == 2:
|
|
||||||
w = w.lineTo(*v)
|
|
||||||
else:
|
|
||||||
w = w.lineTo(*v[1:3]) # TODO draw an arc instead
|
|
||||||
w = w.mirrorY()
|
|
||||||
w = w.extrude(self.l)
|
w = w.extrude(self.l)
|
||||||
pts = [(0, x-self.l/2) for x in range(20, self.l, 60)]
|
|
||||||
print("points", pts)
|
x = 20
|
||||||
|
pts = []
|
||||||
|
while x < self.l:
|
||||||
|
pts.append((x-self.l/2, 0))
|
||||||
|
x += 60
|
||||||
|
#print("points", pts)
|
||||||
w = (w.copyWorkplane(xy)
|
w = (w.copyWorkplane(xy)
|
||||||
.transformed(offset=(0,0,17))
|
.transformed(offset=(0,0,17))
|
||||||
.pushPoints(pts)
|
.pushPoints(pts)
|
||||||
.hole(5)) # TODO replace with counterbore and get proper diameter
|
.hole(5)) # TODO replace with counterbore and get proper diameter
|
||||||
return w
|
return w
|
||||||
|
|
||||||
plate = (cq.Workplane("XY")
|
W = 44
|
||||||
.rect(200, 200)
|
H = 30
|
||||||
.extrude(10)
|
H1 = 4.6
|
||||||
.faces(">Z")
|
L = 77.5
|
||||||
.workplane()
|
L1 = 50.1 # for HGH20CA, TODO deal with variations
|
||||||
.tag("railmount")
|
B = 32
|
||||||
.end()
|
C = 36
|
||||||
)
|
l = 5 # M5x6
|
||||||
hgr20 = HGR20(plate.workplaneFromTagged("railmount"), 300)
|
T = 6
|
||||||
plate2 = hgr20.holes(plate)
|
|
||||||
hgrtest = hgr20.rail()
|
def carriage(self, x): # HGH20CA
|
||||||
show_object(plate2)
|
W = 44
|
||||||
show_object(hgrtest)
|
H = 30
|
||||||
|
H1 = 4.6
|
||||||
|
L = 77.5
|
||||||
|
L1 = 50.1 # for HGH20CA, TODO deal with variations
|
||||||
|
B = 32
|
||||||
|
C = 36
|
||||||
|
l = 5 # M5x6
|
||||||
|
T = 6
|
||||||
|
xy = cq.Workplane().copyWorkplane(self.base)
|
||||||
|
w = xy.transformed((90, 90, 0), (-self.l/2 + x, 0, 0)).tag("endplane")
|
||||||
|
# TODO
|
||||||
|
|
||||||
|
|
||||||
|
s = (cq.Sketch()
|
||||||
|
.segment((W/2, H1), (W/2, H))
|
||||||
|
.segment((-W/2, H))
|
||||||
|
.segment((-W/2, H1))
|
||||||
|
.segment((W/2, H1))
|
||||||
|
.assemble()
|
||||||
|
)
|
||||||
|
s = s.face(HGR20.rail_sketch().assemble(), mode="s")
|
||||||
|
s2 = (cq.Sketch()
|
||||||
|
.segment((W/2, H1), (W/2, H-3))
|
||||||
|
.segment((-W/2, H-3))
|
||||||
|
.segment((-W/2, H1))
|
||||||
|
.segment((W/2, H1))
|
||||||
|
.assemble()
|
||||||
|
)
|
||||||
|
s2 = s2.face(HGR20.rail_sketch().assemble(), mode="s")
|
||||||
|
|
||||||
|
pts = []
|
||||||
|
def savePointsF(l, p):
|
||||||
|
l.append(p)
|
||||||
|
return p
|
||||||
|
#origin = w.workplane().plane.toWorldCoords(cq.Vector(0, 0, 0))
|
||||||
|
#norm = w.workplane().plane.toWorldCoords(cq.Vector(0, 1, 0))
|
||||||
|
#norm = norm - origin
|
||||||
|
#print(norm)
|
||||||
|
# FINALLY GOT THIS WORKING
|
||||||
|
w = (w.transformed((0, 0, 0), (0, 0, L/2-L1/2))
|
||||||
|
.placeSketch(s).extrude(L1)
|
||||||
|
.workplaneFromTagged("endplane")
|
||||||
|
.placeSketch(s2)
|
||||||
|
.extrude(L)
|
||||||
|
#.faces(cq.DirectionMinMaxSelector(norm, True))
|
||||||
|
.faces(">y")
|
||||||
|
.workplane()
|
||||||
|
.transformed((0, 0, 0), (L/2 + x, 0, 0))
|
||||||
|
.rect(C, B)
|
||||||
|
.tag("mountingholes")
|
||||||
|
.vertices() # carriage mounting holes are here!
|
||||||
|
#.extrude(20)
|
||||||
|
.hole(l, T)
|
||||||
|
)
|
||||||
|
return w
|
||||||
|
|
||||||
|
def carriageHoles(self, w, x):
|
||||||
|
W = 44
|
||||||
|
H = 30
|
||||||
|
H1 = 4.6
|
||||||
|
L = 77.5
|
||||||
|
L1 = 50.1 # for HGH20CA, TODO deal with variations
|
||||||
|
B = 32
|
||||||
|
C = 36
|
||||||
|
l = 5 # M5x6
|
||||||
|
T = 6
|
||||||
|
xy = cq.Workplane().copyWorkplane(self.base).transformed(offset=(0, 0, H))
|
||||||
|
holes = (xy.transformed((0, 0, 0), (-self.l/2+L/2 + x, 0, 0))
|
||||||
|
.rect(C, B)
|
||||||
|
.vertices()
|
||||||
|
.cylinder(1000, l/2)
|
||||||
|
)
|
||||||
|
w = (w.cut(holes))
|
||||||
|
return w
|
||||||
|
|
||||||
|
class Plate:
|
||||||
|
# TODO add standard thicknesses here
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def inch(x):
|
||||||
|
return 25.4*x
|
||||||
|
|
||||||
|
def tubing(l, x, y, w, workplane):
|
||||||
|
return (workplane
|
||||||
|
.placeSketch(cq.Sketch()
|
||||||
|
.rect(x, y)
|
||||||
|
.rect(x - 2*w, y-2*w, mode='s'))
|
||||||
|
.extrude(l))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
plate = (cq.Workplane("XY")
|
||||||
|
.rect(200, 200)
|
||||||
|
.extrude(10)
|
||||||
|
.faces(">Z")
|
||||||
|
.workplane()
|
||||||
|
.tag("railmount")
|
||||||
|
.end()
|
||||||
|
)
|
||||||
|
|
||||||
|
hgr20 = HGR20(plate.workplaneFromTagged("railmount"), 300)
|
||||||
|
plate2 = hgr20.holes(plate)
|
||||||
|
hgrtest = hgr20.rail()
|
||||||
|
carriage = hgr20.carriage(0)
|
||||||
|
plate3 = (cq.Workplane("XY")
|
||||||
|
.copyWorkplane(carriage.workplaneFromTagged("mountingholes"))
|
||||||
|
.rect(200, 200)
|
||||||
|
.extrude(5)
|
||||||
|
)
|
||||||
|
plate3 = hgr20.carriageHoles(plate3, 0)
|
||||||
|
tube1 = tubing(500, inch(2), inch(1), inch(0.062), cq.Workplane("XZ"))
|
||||||
|
|
||||||
|
ball_screw = SFU1204(cq.Workplane(), 500)
|
||||||
|
|
||||||
|
#show_object(plate2)
|
||||||
|
#show_object(hgrtest)
|
||||||
|
#show_object(carriage)
|
||||||
|
#show_object(plate3)
|
||||||
|
#show_object(tube1)
|
||||||
|
|
||||||
|
show_object(ball_screw.ballscrew())
|
||||||
|
show_object(ball_screw.nut(200))
|
||||||
|
nut_holder = (cq.Workplane("XZ")
|
||||||
|
.transformed(offset=(0, 0, -200-50))
|
||||||
|
.rect(40, 30)
|
||||||
|
.extrude(50)
|
||||||
|
.faces(">z")
|
||||||
|
.hole(12.4)
|
||||||
|
)
|
||||||
|
nut_holder = ball_screw.nutHoles(nut_holder, 200)
|
||||||
|
fixed = ball_screw.fixedBearing()
|
||||||
|
show_object(nut_holder)
|
||||||
|
show_object(fixed)
|
||||||
|
bearing_holder = (cq.Workplane("XZ")
|
||||||
|
.transformed(offset=(0, 0, 0))
|
||||||
|
.rect(60, 80)
|
||||||
|
.extrude(20)
|
||||||
|
.faces(">z")
|
||||||
|
.hole(12.4)
|
||||||
|
)
|
||||||
|
bearing_holder = ball_screw.fixedBearingHoles(bearing_holder)
|
||||||
|
show_object(bearing_holder)
|
||||||
|
bearing2 = ball_screw.floatingBearing()
|
||||||
|
show_object(bearing2)
|
||||||
|
bearing_holder2 = (cq.Workplane("XZ")
|
||||||
|
.transformed(offset=(0, 0, -540))
|
||||||
|
.rect(60, 80)
|
||||||
|
.extrude(20)
|
||||||
|
.faces(">z")
|
||||||
|
.hole(12.4)
|
||||||
|
)
|
||||||
|
bearing_holder2 = ball_screw.floatingBearingHoles(bearing_holder2)
|
||||||
|
show_object(bearing_holder2)
|
||||||
|
|
||||||
|
#show_object(cq.Workplane().placeSketch(HGR20.rail_sketch().assemble()).extrude(10))
|
Loading…
Reference in New Issue