chiark / gitweb /
filamentspool: Provide doc comment
[reprap-play.git] / filamentspool.scad
1 // -*- C -*-
2
3 // Filament spool for filament coils as supplied by Faberdashery
4 //
5 // Each spool is a hub with 3 or 4 arms.  Each arm has a cup for
6 // holding the filament.  The effective diameter can be adjusted by
7 // setting the cup into a different seat in the arm.  The cups are
8 // held on with simple clips, so the filement coil can easily be
9 // removed and replaced.
10 //
11 // This file (and its includes) can generate:
12 //
13 //   - Heavy duty 4-armed spool suitable for holding a 100m
14 //     Faberdashery coil on the spool arm of a Lulzbot TAZ-5.
15 //
16 //     Set
17 //           fdia=2.85
18 //           lightduty=false
19 //     And print following parts
20 //            Hub
21 //            ArmEnd x 4
22 //            FilamentCup x 4  (or FilamentCupPair x 2)
23 //            CupSecuringClup x 4
24 //
25 //     You will also need  4 x M4 machine screws and nuts
26 //
27 //   - Light duty 3-armed spool suitable for up to around 30m
28 //     of Faberdashery 2.85mm PLA.
29 //
30 //     Set
31 //           fdia=2.85
32 //           lightduty=true
33 //     And print following parts
34 //           Hub
35 //           ArmEnd x 3
36 //           FilamentCup x 3  (or FilamentCup + FilamentCupPair)
37 //           CupSecuringClup x 3
38 //           TowerDoveClipPin x 6
39 //
40 //     When assembling, insert one TowerDoveClipPin from each side,
41 //     joining each ArmEnd to the Hub with two TowerDoveClipPins.
42 //     Modest force with pliers is good to seat them properly.
43 //
44 //     (note that the light duty and heavy duty CupSecuringClips
45 //      are slightly different)
46 //
47 // For the above, I generally used the Cura `Standard' PLA profile.
48 //
49 //   - Storage arm suitable for screwing to walls, bookshelves,
50 //     etc. (requires non-countersunk M4 screws); will hold two
51 //     heavy duty spools each with a 100m coil.
52 //
53 //     Set
54 //           fdia=2.85
55 //           lightduty=false
56 //     And print one of these, according to taste
57 //            StorageArmLeft
58 //            StorageArmRight
59 //
60 //     NB that the `light duty' version of this is shorter and
61 //     will only take two `light duty' spools.
62 //
63 // For the above, I used the Cura `High detail' PLA profile because
64 // I wanted it pretty, but the `Standard' profile should do fine.
65 //
66 //   - Spool (in many parts) for handing 1.75mm filament, printable
67 //     on, and with parts for mounting on, a Reprappro Huxley.
68
69
70 fdia=2.85; // or 1.75
71 lightduty=false; // or true
72
73
74 slop=0.5;
75 bigslop=slop*2;
76
77 function selsz(sm,lt,lg) = fdia < 2 ? sm : lightduty ? lt : lg;
78 function usedove() = selsz(true,true,false);
79
80 num_arms = selsz(3,3,4);
81
82 channelslop=selsz(slop,0.75,slop);
83
84 exteffrad = 70;
85 hubeffrad = selsz(30, 82, 40);
86 hubbigrad = selsz(20, 38, 38);
87 hublwidth = selsz(3, 2.5, 4);
88 hubstemwidth = 2;
89 hublthick = 10;
90 hubaxlerad = selsz(5, 28/2, 28/2);
91 totalheightfromtower = 240;
92 axletowerfudgebend = 0;
93 axleaxlefudgebend = 3;
94 axlepadlen = 1.0;
95
96 armend_length = 120;
97
98 prongthick=selsz(5,4,5);
99 prongwidth=selsz(5,4,5);
100 prongribwidth=3;
101 prongribheight=selsz(0,0,4);
102 ratchetstep=15;
103 ratchettooth=3;
104 ratchettoothheight=5;
105 ratchettoothsmoothr=1;
106 ratchettoothslope=0.75;
107 overlap=0.5;
108 cupwidth=selsz(40,25,50);
109 cupheight=selsz(55,25,55);
110
111 cupstrong_dx=selsz(0,0,-10);
112
113 propxshift = -6;
114
115 doveclipheight = 10;
116
117 teethh=3;
118 teethgapx=4+fdia;
119
120 prongstalkxwidth=3;
121
122 stalklength=selsz(35,25,55);
123 overclipcupgap=5;
124 overclipdepth=15;
125 overcliproundr=2.0;
126 overclipthick=1.0;
127 overclipcupnextgap=selsz(20,15,20);
128
129 hubaxlelen = selsz(25, 62.5, 77.5);
130 echo(hubaxlelen);
131
132 overclipsmaller=-2.5;
133 overclipbigger=0.0;
134
135 wingspoke=2.5;
136 wingsize=6;
137 wingthick=3;
138
139 armendwallthick=selsz(2.5, 1.8, 2.5);
140 armendbasethick=selsz(1.2, 1.2, 1.2);
141
142 axlehorizoffset = 12.5;
143 axlevertheight = 100;
144 towercliph = 16;
145 towerclipcount = 3;
146 towerpillarw = 5;
147
148 axlepinrad = 2;
149 axlepintabrad = 5;
150
151 washerthick = 1.2;
152 washerthinthick = 0.8;
153 washerverythinthick = 0.4;
154 washerrad = hubaxlerad + 7.5;
155 frictionwasherarmwidth = 3;
156 frictionwasherextrapush = 1.0;
157
158 ratchetpawl=ratchetstep-ratchettooth-bigslop*2;
159
160 nondove_armhole_x = 32;
161 nondove_armhole_hole = 4 + 0.8;
162 nondove_armhole_support = 7;
163 nondove_armhole_wall = 3.2;
164 nondove_armhole_slop = 0.5;
165 nondove_armhole_slop_x = 0.5;
166
167 nondove_armbase = nondove_armhole_x + nondove_armhole_hole/2 +
168   nondove_armhole_support;
169 echo(nondove_armbase);
170
171 include <doveclip.scad>
172 include <cliphook.scad>
173 include <filamentteeth.scad>
174 include <axlepin.scad>
175
176 channelwidth = prongthick + channelslop;
177 channeldepth = prongwidth + ratchettoothheight;
178 totalwidth = armendwallthick*2 + channelwidth;
179 totalheight = channeldepth + armendbasethick;
180 stalkwidth = prongwidth + prongstalkxwidth;
181
182 module ArmEnd(length=armend_length){ ////toplevel
183   if (usedove()) {
184     translate([ratchettoothsmoothr, channelwidth/2, -armendbasethick]) {
185       rotate([0,0,-90])
186         DoveClipPairBase(h=doveclipheight);
187     }
188   } else {
189     difference(){
190       translate([1, -armendwallthick, -armendbasethick])
191         mirror([1,0,0])
192         cube([nondove_armbase+1, totalwidth, totalheight]);
193       translate([-nondove_armbase + nondove_armhole_x,
194                  -armendwallthick + totalwidth/2,
195                  -armendbasethick -1])
196         cylinder(r= nondove_armhole_hole/2, h=totalheight+2, $fn=10);
197     }
198   }
199
200   difference(){
201     translate([0, -armendwallthick, -armendbasethick])
202       cube([length, totalwidth, totalheight]);
203     translate([-1, 0, 0])
204       cube([length+1 - ratchettooth, channelwidth, channeldepth+1]);
205     translate([-1, 0, ratchettoothheight])
206       cube([length+2, channelwidth, channeldepth+1]);
207   }
208   for (dx = [0 : ratchetstep : length - ratchetstep]) translate([dx,0,0]) {
209     translate([ratchettoothsmoothr+0.5, armendwallthick/2, 0]) minkowski(){
210       rotate([90,0,0])
211         cylinder($fn=20, r=ratchettoothsmoothr, h=armendwallthick);
212       multmatrix([      [       1, 0, ratchettoothslope, 0      ],
213                         [       0,      1,      0,      0       ],
214                         [       0,      0,      1,      0       ],
215                         [       0,      0,      0,      1       ]])
216         cube([ratchettooth - ratchettoothsmoothr*2,
217               channelwidth, ratchettoothheight - ratchettoothsmoothr]);
218     }
219   }
220 }
221
222 module FilamentCupHandle(){
223   pawlusewidth = ratchetpawl-ratchettoothsmoothr*2;
224   mirror([0,1,0]) {
225     cube([stalklength, stalkwidth, prongthick]);
226     translate([stalklength, stalkwidth/2, 0])
227       cylinder(r=stalkwidth/2, h=prongthick, $fn=20);
228     translate([ratchettoothsmoothr, stalkwidth, 0]) {
229       minkowski(){
230         cylinder($fn=20,r=ratchettoothsmoothr, h=1);
231         multmatrix([    [       1, -ratchettoothslope, 0, 0     ],
232                         [       0,      1,      0,      0       ],
233                         [       0,      0,      1,      0       ],
234                         [       0,      0,      0,      1       ]])
235           cube([pawlusewidth,
236                 ratchettoothheight - ratchettoothsmoothr,
237                 prongthick - 1]);
238       }
239     }
240   }
241 }
242
243 module FilamentCupCup(){
244   for (my=[0,1]) mirror([0,my,0]) {
245     translate([0, cupwidth/2, 0])
246       cube([cupheight + prongwidth, prongwidth, prongthick]);
247   }
248 }
249
250 module FilamentCup() { ////toplevel
251   FilamentCupHandle();
252
253   gapy = prongwidth;
254   dy = cupwidth/2 + gapy + overclipcupgap;
255   baselen = dy+cupwidth/2;
256
257   translate([0, dy, 0])
258     FilamentCupCup();
259   cube([prongwidth, baselen+1, prongthick]);
260
261   translate([cupstrong_dx, prongwidth, 0]) {
262     cube([prongwidth, baselen-prongwidth, prongthick]);
263     for (y = [0, .33, .67, 1])
264       translate([0, (baselen - prongwidth) * y, 0])
265         cube([-cupstrong_dx + 1, prongwidth, prongthick]);
266   }
267   if (cupstrong_dx != 0) {
268     rotate([0,0,45])
269       translate([-prongwidth*.55, -prongwidth*2.1, 0])
270       cube([prongwidth*(2.65), prongwidth*4.2, prongthick]);
271   }
272
273   translate([0, -0.2, 0])
274     cube([prongribwidth, baselen, prongthick + prongribheight]);
275
276   if (prongribheight > 0) {
277     translate([-prongwidth, baselen, 0])
278       cube([cupheight/2, prongwidth + prongribheight, prongribwidth]);
279   }
280
281   midrad = cupwidth/2 + prongwidth/2;
282
283   propshift = stalklength - overclipdepth - prongthick + propxshift;
284   proptaken = propshift;
285   echo(midrad, propshift, proptaken);
286
287   translate([propshift, -1, 0]) {
288     // something is wrong with the y calculation
289     cube([prongwidth,
290           gapy+2,
291           prongthick]);
292   }
293   for (y = [overclipcupgap, overclipcupgap+overclipcupnextgap]) {
294     translate([cupstrong_dx, y + prongwidth, 0])
295       rotate([0,0, 102 + fdia])
296       FilamentTeeth(fdia=fdia, h=teethh);
297   }
298   for (x = [-0.3, -1.3]) {
299     translate([cupheight + overclipcupnextgap*x, baselen + prongwidth, 0])
300       rotate([0,0, 12 + fdia])
301       FilamentTeeth(fdia=fdia, h=teethh);
302   }      
303 }
304
305 module CupSecuringClipSolid(w,d,h1,h2){
306   rotate([0,-90,0]) translate([0,-h1/2,-w/2]) linear_extrude(height=w) {
307     polygon(points=[[0,0], [d,0], [d,h2], [0,h1]]);
308   }
309 }
310
311 module CupSecuringClipSolidSmooth(xrad=0, xdepth=0){
312   hbase = totalheight + prongstalkxwidth - overcliproundr*2;
313   minkowski(){
314     CupSecuringClipSolid(w=totalwidth,
315                          d=overclipdepth + xdepth,
316                          h1=hbase - overclipsmaller,
317                          h2=hbase + overclipbigger);
318     cylinder($fn=20, h=0.01, r=overcliproundr+xrad);
319   }
320 }
321
322 module CupSecuringClip(){ ////toplevel
323   wingswidth = wingspoke*2 + overclipthick*2 + overcliproundr*2 + totalwidth;
324   difference(){
325     union(){
326       CupSecuringClipSolidSmooth(xrad=overclipthick, xdepth=0);
327       translate([-wingswidth/2, -wingsize/2, 0])
328         cube([wingswidth, wingsize, wingthick]);
329       translate([-wingsize/2, -wingswidth/2, 0])
330         cube([wingsize, wingswidth, wingthick]);
331     }
332     translate([0,0,-0.1])
333       CupSecuringClipSolidSmooth(xrad=0, xdepth=0.2);
334   }
335 }
336
337 module ArmDoveClipPin(){ ////toplevel
338   DoveClipPin(h=doveclipheight);
339 }
340
341 module TowerDoveClipPin(){ ////toplevel
342   DoveClipPin(h=towercliph/2);
343 }
344
345 module Hub(){ ////toplevel
346   axlerad = hubaxlerad + slop;
347   xmin = axlerad+hublwidth/2;
348   xmax = hubbigrad-hublwidth/2;
349   hole = hubeffrad - hubbigrad - DoveClip_depth() - hublwidth*2;
350   holewidth = DoveClipPairSane_width() - hubstemwidth*2;
351   nondove_allwidth = nondove_armhole_wall*2 + totalwidth;
352   difference(){
353     union(){
354       difference(){
355         cylinder($fn=60, h=hublthick, r=hubbigrad);
356         translate([0,0,-1])
357           cylinder($fn=30, h=hublthick+2, r=(hubbigrad-hublwidth));
358       }
359       cylinder(h=hubaxlelen, r=axlerad+hublwidth);
360       for (ang=[0 : 360/num_arms : 359])
361         rotate([0,0,ang]) {
362           if (usedove()){
363             difference() {
364               translate([hubeffrad,0,0])
365                 DoveClipPairSane(h=doveclipheight,
366                                  baseextend = (hubeffrad - DoveClip_depth()
367                                                - hubbigrad + hublwidth));
368               if (hole>hublwidth && holewidth > 2) {
369                 translate([hubbigrad + hublwidth, -holewidth/2, -1])
370                   cube([hole, holewidth, hublthick+2]);
371               }
372             }
373           } else {
374             difference(){
375               translate([0,
376                          -nondove_allwidth/2,
377                          0])
378                 cube([hubeffrad + nondove_armhole_x
379                       + nondove_armhole_hole/2 + nondove_armhole_support,
380                       nondove_allwidth,
381                       nondove_armhole_wall + totalheight]);
382               translate([hubeffrad - nondove_armhole_slop_x,
383                          -nondove_allwidth/2
384                          + nondove_armhole_wall - nondove_armhole_slop,
385                          nondove_armhole_wall])
386                 cube([nondove_armhole_x + 50,
387                       totalwidth + nondove_armhole_slop*2,
388                       totalheight + 1]);
389               translate([hubeffrad + nondove_armhole_x, 0, -20])
390                 cylinder(r= nondove_armhole_hole/2, h=50, $fn=10);
391             }
392           }
393         }
394       for (ang = [0 : 180/num_arms : 359])
395         rotate([0,0,ang]) rotate([90,0,0]) {
396           translate([0,0,-hublwidth/2])
397             linear_extrude(height=hublwidth)
398             polygon([[xmin,0.05], [xmax,0.05],
399                      [xmax,hublthick-0.2], [xmin, hubaxlelen-0.2]]);
400         }
401     }
402     translate([0,0,-1]) cylinder($fn=60, h=hubaxlelen+2, r=axlerad);
403   }
404 }
405
406 module ArmExtender(){ ////toplevel
407   DoveClipExtender(length=exteffrad-hubeffrad,
408                    ha=doveclipheight,
409                    hb=doveclipheight);
410 }
411
412 module FsAxlePin(){ ////toplevel
413   AxlePin(hubaxlerad, washerrad*2, axlepinrad, axlepintabrad, slop);
414 }
415
416 module Axle(){ ////toplevel
417   pillarswidth = DoveClipPairSane_width(towerclipcount);
418
419   rotate([0,0, -( axleaxlefudgebend + atan(slop/hubaxlelen) ) ])
420   translate([-axlehorizoffset, -axlevertheight, 0]) {
421     rotate([0,0,-axletowerfudgebend])
422     rotate([0,0,-90])
423       DoveClipPairSane(h=towercliph, count=towerclipcount, baseextend=3);
424     translate([0, DoveClip_depth(), 0])
425     rotate([0,0,90])
426       ExtenderPillars(axlevertheight - DoveClip_depth(),
427                       pillarswidth, towercliph,
428                       pillarw=towerpillarw);
429   }
430
431   axleclearlen = hubaxlelen + slop*4 + washerthick*2 + axlepadlen;
432   axlerad = hubaxlerad-slop;
433   bump = axlerad * 0.2;
434   shift = axlerad-bump;
435   joinbelowallow = 3;
436
437   intersection(){
438     translate([0, 0, shift]) {
439       difference() {
440         union(){
441           translate([-1, 0, 0])
442             rotate([0,90,0])
443             cylinder($fn=60,
444                      r = axlerad,
445                      h = 1 + axleclearlen + axlepinrad*2 + 2);
446           mirror([1,0,0]) rotate([0,90,0])
447             cylinder(r = axlerad*1.75, h = 3);
448           intersection(){
449             mirror([1,0,0])
450               translate([axlehorizoffset - pillarswidth/2, 0, 0])
451               rotate([0,90,0])
452               cylinder($fn=60,
453                        r = towercliph - shift,
454                        h = pillarswidth);
455             translate([-50, -joinbelowallow, -50])
456               cube([100, joinbelowallow+50, 100]);
457           }
458         }
459         rotate([90,0,0])
460         translate([axleclearlen + axlepinrad/2, 0, -25])
461           cylinder(r = axlepinrad + slop, h=50);
462       }
463     }
464     translate([-50,-50,0]) cube([100,100,100]);
465   }
466 }
467
468 module washer(thick){
469   Washer(hubaxlerad, washerrad, thick, slop);
470 }
471
472 module AxleWasher(){ ////toplevel
473   washer(thick=washerthick);
474 }
475
476 module AxleThinWasher(){ ////toplevel
477   washer(thick=washerthinthick);
478 }
479
480 module AxleVeryThinWasher(){ ////toplevel
481   washer(thick=washerverythinthick);
482 }
483
484 module AxleFrictionWasher(){ ////toplevel
485   difference(){
486     cylinder(h=washerthick, r=washerrad);
487     translate([0,0,-1]) cylinder(h=washerthick+2, r=hubaxlerad+slop);
488   }
489   frarmr = hubbigrad;
490   frarmw = frictionwasherarmwidth;
491   frarmpawlr = hublwidth;
492   frarmpawlpush = slop*4 + frictionwasherextrapush;
493   for (ang=[0,180]) rotate([0,0,ang]) {
494     translate([washerrad-1, -frarmw/2, 0])
495       cube([frarmr - washerrad + 1, frarmw, washerthick]);
496     intersection(){
497       translate([frarmr - frarmpawlr, -50, 0])
498         cube([frarmpawlr, 100, 50]);
499       rotate([0,90,0])
500         cylinder(h = 50, r = frarmpawlpush, $fn=36);
501     }
502   }
503 }
504
505 module TowerExtender(){ ////toplevel
506   l = totalheightfromtower - axlevertheight;
507   echo("TowerExtender",l);
508   DoveClipExtender(length = l,
509                    ha = towercliph, hb = towercliph,
510                    counta = towerclipcount, countb = towerclipcount,
511                    pillarw = towerpillarw);
512 }
513
514 module FilamentCupPair(){ ////toplevel
515   FilamentCup();
516   translate([cupheight + prongthick*3,
517              cupwidth/2*1.7,
518              0])
519     rotate([0,0,180]) FilamentCup();
520 }
521
522 //----- storarm -----
523
524 storarm_hooklen = 8;
525 storarm_hookheight = 5;
526 storarm_thick = 10;
527 storarm_axleslop = 4;
528
529 storarm_base_w = 30;
530 storarm_base_h = 100;
531 storarm_base_d = 15;
532 storarm_base_mind = 2;
533
534 storarm_cope_hubaxle_mk1 = true;
535
536 storarm_screw_hole = 4;
537 storarm_screw_hole_slop = 0.5;
538 storarm_besides_hole = 4;
539
540 storarm_under_hole = 5;
541 storarm_screw_hole_head = 8.8;
542 storarm_screw_hole_head_slop = 1.5;
543
544 // calculated
545
546 storarm_axlerad = hubaxlerad - storarm_axleslop;
547 storarm_mainlen = hubaxlelen*2 + storarm_axleslop
548   + (storarm_cope_hubaxle_mk1 ? 10 : 0);
549 storarm_totlen = storarm_mainlen + storarm_hooklen;
550
551 storarm_mid_off_y = storarm_axlerad;
552
553 storarm_base_off_y = storarm_mid_off_y + storarm_base_h/2;
554
555 module StorageArmDiagPartSide(xmin, xmax){
556   xsz = xmax-xmin;
557   yuse = storarm_thick/2;
558
559   intersection(){
560     translate([xmin-1, -storarm_axlerad, storarm_thick/2])
561       rotate([0,90,0])
562       cylinder(r=storarm_axlerad, h=xsz+2, $fn=60);
563     translate([xmin, -yuse, 0])
564       cube([xsz, yuse, storarm_thick]);
565   }
566 }
567
568 module StorageArmDiagPart(xmin, xmax, shear, adjbot){
569   hull(){
570     StorageArmDiagPartSide(xmin,xmax);
571
572     multmatrix([[1,0,0,0],
573                 [shear,1,0,0],
574                 [0,0,1,0],
575                 [0,0,0,1]])
576       translate([0, -storarm_axlerad*2 + adjbot, 0])
577       mirror([0,1,0])
578       StorageArmDiagPartSide(xmin,xmax);
579   }
580 }
581
582 module StorageArmBaseTemplate(){
583   square([storarm_base_w, storarm_base_h]);
584 }
585
586 module StorageArmAtMountingHoles(){
587   bes = storarm_besides_hole + storarm_screw_hole;
588
589   x0 = bes;
590   x1 = storarm_base_w-bes;
591   y1 = storarm_base_h - bes;
592   y0 = bes;
593
594   for (pos=[ [x0, y1],
595              [x1, y1],
596              [x1, y0] ]) {
597     rotate([0,90,0])
598       translate([pos[0] - storarm_base_w,
599                  pos[1] - storarm_base_off_y, -storarm_base_d])
600       children();
601   }
602 }
603
604 module StorageArmRight(){ ////toplevel
605   shear = storarm_hookheight / (storarm_mainlen/2);
606
607   StorageArmDiagPart(-1, storarm_mainlen/2+1, shear, 0);
608   StorageArmDiagPart(storarm_mainlen/2-1, storarm_mainlen+1, shear/2,
609                      storarm_hookheight/2);
610
611   translate([0, storarm_hookheight, 0])
612     StorageArmDiagPart(storarm_mainlen, storarm_totlen,
613                        shear/2, -storarm_hookheight/2);
614
615   difference(){
616     union(){
617       hull(){
618         translate([-storarm_base_d, -storarm_base_off_y, storarm_base_w])
619           rotate([0,90,0])
620           linear_extrude(height=storarm_base_mind)
621           StorageArmBaseTemplate();
622         StorageArmDiagPart(-1, 0, shear, 0);
623       }
624       StorageArmAtMountingHoles(){
625         cylinder(r= storarm_screw_hole_head/2,
626                  h=10);
627       }
628     }
629     StorageArmAtMountingHoles(){
630       translate([0,0,-1])
631         cylinder(r= (storarm_screw_hole + storarm_screw_hole_slop)/2 ,
632                  h=20);
633       translate([0,0,storarm_under_hole])
634         cylinder(r= (storarm_screw_hole_head + storarm_screw_hole_head_slop)/2,
635                  h=20);
636     }
637   }
638 }
639
640 module StorageArmLeft(){ ////toplevel
641   mirror([1,0,0]) StorageArmRight();
642 }
643
644 module StorArmHoleTest(){ ////toplevel
645   sz = storarm_screw_hole_head + storarm_besides_hole*2;
646   intersection(){
647     StorageArmRight();
648     translate([-50, -storarm_base_off_y, -1])
649       cube([100, sz, sz+1]);
650   }
651 }
652
653
654 module Demo(){
655   translate([-hubeffrad-30,50,0]) Hub();
656   ArmEnd();
657   translate([0,50,0]) FilamentCup();
658 }
659
660 //ArmEnd();
661 //FilamentCup();
662 //FilamentCupPair();
663 //CupSecuringClip();
664 //Hub();
665 //ArmExtender();
666 //Axle();
667 //AxleWasher();
668 //AxlePin();
669 //AxleFrictionWasher();
670 //StorageArmLeft();
671 //StorArmHoleTest();
672 //Demo();