Root/cw.py

1#!/usr/bin/python
2
3import sys, math
4import shape
5
6
7group = None
8g = 9.81 # gravitational acceleration, m/s2
9
10# density, g/cm3
11
12density = 11.34 # pure lead (Pb)
13density = 9.31 # Pb50Sn50
14density = 10.00 # Pb67Sn33
15#density = 7.28 # pure tin (Sn)
16
17#
18# The z coordinate of the plane limiting the top of the counterweight. This is
19# the altitude of the board surface minus the board clearance.
20#
21z_ceiling = 5.0 # mm
22
23#
24# The y coordinate of the axis around which our system rotates, i.e., the
25# position of the center of the rear feet
26#
27y_axis = 16.0
28
29off_x = -15+18
30off_y = -46+5
31
32#
33# Radius for lead inlets and air escapes
34#
35channel_radius = 1 # mm
36
37#
38# Inlets have a large opening on the outside: first a cylinder of radius
39# "inlet_radius" and depth "inlet_streight", then a cone to the channel radius.
40# The cone's height is variable. At the end, there is a channel of length
41# "shaft". The goals are to have a wide opening to make it easy to pour the
42# metal, and to create a buffer for thermal energy.
43#
44inlet_radius = 6.5
45inlet_straight = 3 # for 2" wood
46inlet_straight = 33 # for 3" wood
47shaft = 3
48
49#
50# This maximum y dimension of the piece from which the mold is machined
51#
52ymax_piece = 45 # 2" wood
53ymax_piece = 75 # 3" wood, piece is really 70 mm, but we need slack
54
55#
56# Mold compression. If using a wooden mold, the two parts compress, making the
57# counterweight a bit thinner.
58#
59mold_compression = 0.1
60
61#
62# Cumulative mass and torque.
63#
64total_mass = 0
65total_torque = 0
66
67
68#
69# solve a quadratic equation of the form a*x^2+b*x+c = 0
70#
71
72def qeq(a, b, c):
73    d = math.sqrt(b*b-4*a*c)
74    return ((-b-d)/2/a, (-b+d)/2/a)
75
76
77#
78# find the x-coordinate of the center of mass of a trapezoid/trapezium with the
79# four corners (0, 0), (x, 0), (0, y0), and (x, y0)
80# we assume the mass distribution to be uniform
81#
82
83def cm_trap_a(x, y0, y1):
84    if y0 == y1:
85    return x/2.0
86    f = float(y1-y0)/x/2
87    return qeq(2*f, 2.0*y0, -x*(y0+y1)/2.0)[1]
88
89
90#
91# calculate a rectangle's contribution to mass and torque
92#
93
94def rect_calc(x0, y0, z0, x1, y1, z1):
95    global total_mass, total_torque
96
97    # mass, in g
98    m = (x1-x0)*(y1-y0)*(z_ceiling-(z0+z1)/2.0)*density/1e3;
99
100    # center of mass on y axis, in y coordinates (mm)
101    y_center = y0+cm_trap_a(y1-y0, z_ceiling-z0, z_ceiling-z1)
102
103    # weight, in N
104    w = m*g/1000.0
105
106    # torque, in Nm
107    t = w*(y_center-y_axis)/1000.0
108
109    total_mass += m
110    total_torque += t
111
112#
113# gnuplot a rectangle
114#
115
116def rect_gnuplot(x0, y0, z0, x1, y1, z1):
117    print x0, y0, z0
118    print x1, y0, z0
119    print x1, y1, z1
120    print x0, y1, z1
121    print x0, y0, z0
122    print
123    print
124
125
126#
127# add inlets and air escapes for gravitation casting
128#
129
130def channel(sk, x, y, r0, r1):
131    if r0 == r1:
132    cad.cylinder(x, y, 0, r0, ymax_piece-y)
133        obj = cad.getlastobj()
134    else:
135    cad.cylinder(x, y, 0, r0, shaft)
136    cyl = cad.getlastobj()
137    cad.cone(x, y, shaft, r0, r1, ymax_piece-y-shaft-inlet_straight)
138    cone = cad.getlastobj()
139    cad.fuse(cyl, cone)
140    obj = cad.getlastobj()
141    cad.cylinder(x, y, ymax_piece-inlet_straight-y, r1, inlet_straight)
142    cyl = cad.getlastobj()
143    cad.fuse(obj, cyl)
144    obj = cad.getlastobj()
145    cad.rotate(obj, x, y, 0, 1, 0, 0, -math.pi/2)
146    cad.cut(sk, obj)
147    return cad.getlastobj()
148
149
150def inlet(sk, x, y):
151    return channel(sk, x+off_x, y+off_y, channel_radius, inlet_radius)
152    pass
153
154
155def escape(sk, x, y):
156    return channel(sk, x+off_x, y+off_y, channel_radius, channel_radius)
157
158
159#
160# add a rectangle to the CAD model
161#
162
163def do_rect_cad(x0, y0, z0, x1, y1, z1):
164    cad.sketch()
165    sk = cad.getlastobj()
166
167    cad.line3d(x0, y0, z0, x1, y0, z0)
168    line = cad.getlastobj()
169    cad.add(sk, line)
170
171    cad.line3d(x1, y0, z0, x1, y1, z1)
172    line = cad.getlastobj()
173    cad.add(sk, line)
174
175    cad.line3d(x1, y1, z1, x0, y1, z1)
176    line = cad.getlastobj()
177    cad.add(sk, line)
178
179    cad.line3d(x0, y1, z1, x0, y0, z0)
180    line = cad.getlastobj()
181    cad.add(sk, line)
182
183    cad.reorder(sk)
184
185    return sk
186
187
188def rect_cad(x0, y0, z0, x1, y1, z1):
189    global group
190
191    sk = do_rect_cad(x0, y0, z0, x1, y1, z1)
192
193    cad.extrude(sk, 3)
194
195    if group is None:
196    group = cad.getlastobj()
197    else:
198    cad.fuse(group, cad.getlastobj())
199    group = cad.getlastobj()
200
201
202#
203# add a rectangle with the following corners:
204# (x0, y0, z0)
205# (x1, y0, z0)
206# (x0, y1, z1)
207# (x1, y1, z1)
208#
209
210def rect(x0, y0, z0, x1, y1, z1):
211    rect_calc(x0, y0, z0, x1, y1, z1)
212    do(x0, y0, z0, x1, y1, z1)
213
214
215if __name__ == "__main__":
216    do = rect_gnuplot
217else:
218    import HeeksPython as cad
219    do = rect_cad
220
221shape.rect = rect
222shape.make_base()
223
224#
225# for wax model
226#
227#if __name__ != "__main__":
228# sk = do_rect_cad(10, 40, z_ceiling, 110, 70, z_ceiling)
229# cad.extrude(sk, 3)
230# sk = cad.getlastobj()
231# cad.cut(group, sk)
232# group = cad.getlastobj()
233# cad.translate(group, -15, -69, -5)
234# cad.rotate(group, 0, 0, 0, 1, 0, 0, math.pi)
235
236#
237# add rectangular block for mold, then subtract the counterweight
238#
239
240if __name__ != "__main__":
241    cad.translate(group, -15, -46, -5)
242    cad.translate(group, 18, 5, -mold_compression)
243    sk = do_rect_cad(0, 0, 0, 120, ymax_piece, 0)
244    cad.extrude(sk, -10)
245    sk = cad.getlastobj()
246    cad.cut(sk, group)
247    sk = cad.getlastobj()
248    sk = escape(sk, 15+channel_radius, 69.5)
249    sk = inlet(sk, 34-channel_radius, 69.5)
250    sk = inlet(sk, 89.5+channel_radius, 69)
251    sk = escape(sk, 100-channel_radius, 69)
252    sk = escape(sk, 60.5-channel_radius, 65)
253    sk = escape(sk, 62.5+channel_radius, 65)
254    sk = escape(sk, 82.5-channel_radius, 65)
255    sk = inlet(sk, 50, 65)
256
257print >>sys.stderr, "total mass =", total_mass, "g"
258print >>sys.stderr, "total torque =", total_torque*1000.0, "mNm"
259

Archive Download this file

Branches:
master



interactive