made B node on BH a little fatter

made B node on BH a little fatter

// $URL: svn+ssh://mrwhat@ssh.boim.com/home/mrwhat/svn/Walker/trunk/Jansen.scad $
// $Id: Jansen.scad 427 2014-08-23 20:42:39Z mrwhat $

// Define PART to one of the following values to generate model for desired part.
//       HipA, HipB, FootA, FootB, CH, CD, EF, BH, AC, pulley, mainBar, drivePulley
// For a 2-leg (half-trotter) :  print (2) CH, CD ; (4) EF, BH ; (1) of the others
// For a production robot, glue a rectangular support/spacer between BH pairs for stiffness

// PART="motor" to show motor-mount assembly

// *** DEPRICATED
// Combined parts with pads, optimized for RepRap :
// Hip, Feet, crankLinks, EFs, BHs    : main, pulley, drivePulley as above (brace)
//
// standoffs also DEPRICATED
hingeStyle = "spacer"; //6standoff";  // spacer or standoff
// *****

PART="FootA";
echo(str("PART=",PART));

HoleFuzz = 0.1;  // extra radius (mm) to add to holes to account for printer slop
dHoleFuzz = 0.2;  // extra radius (mm) to add to d-shaft holes.  Sometimes not the same as HoleFuzz since it is harder to clean D-shaft holes

// measured diameter of '3/16"' spacer was 4.74 to 4.76, not 4.7625 as expected.
// Current design:  3/16" axles at B
//                  3/16" long 1/4"  OD standoffs at D, E, F
//                  1/2"  long 3/16" OD standoffs at H, A, C
Bdiam = 4.7625;  // larger brass tube rdiameter, measured on 3/16" tube
Adiam = 4.76;
Hdiam = Adiam;
//Ddiam = 6.35;  // 1/4" OD standoffs
Ddiam = Adiam;  // 3/16" OD standoffs/spacers
diam4 = 2.76;  // diameter of #4-40 screw, OD of thread

// on spacer tests:
//    Brad +.125 mm was snug, but not quite free rotating
//         +.05     turned, but not freely
//         -.025    still turned,  was very close
//    Arad +.125    turned free (good for main, crankLinks)
//         +.05     was press-to-fit (good for crankArm)
//    rad4 + 0.2    allowed a screw to go through snugly but freely
//         +.125    only threaded through
//  1/4"OD + 0.2    was a snug fit, no turn.  almost press-to-fit
//         + 0.275  snug, free turn... good for hinges on standoff

Brad = Bdiam/2 + HoleFuzz/2;    // 4.76mm diam brass tube -- critical fit
Arad = Adiam/2 + HoleFuzz/2.3;  // 3.18mm diam brass tube -- critical fit
rad4 = diam4/2 + HoleFuzz;  // good for screw pass-through
Hrad = Hdiam/2 + HoleFuzz*1.35;  // standoff holes for freely-moving hinges
Drad = Ddiam/2 + HoleFuzz;
AradFree = Adiam/2 + .25;  // loose fit on spindle

BradTight = Brad-0.05;
BradFree  = Brad+0.05;

Frad = 7;  // radius of beefed-up "knee"

LinkRad=3;
BarHeight=3;
//NodeHeight=5.8;  // gives a little room for 6.35 mm (.25 inch) standoffs
layer1bias=0.4;  // shift up for 1 layer of brim/raft

// 9/16" spacer height 14.37mm, not 14.287 as expected
// 3/16" spacer height  4.79mm, not 4.7625 as expected (*3=14.37)
// 1/4" Al standoffs were pretty close, and 3x was 19.02mm high, not 19.05 as expected, pretty close
//TrueNodeHeight = (hingeStyle == "spacer") ? 4.79-.2 : 6.35;
TrueNodeHeight = 4.79-.2;
NodeHeight = TrueNodeHeight - 0.3;  // a little room for hinges
//NodeHeight3 = 25.4*((hingeStyle == "spacer") ? 9/16 : 3/4) - 0.3;
// moving to slightly thinner 1/2" standoffs at H
NodeHeight3 = 25.4/2 - 0.3;

// Forks should be 1 node thick for standoffs...  short screws go into variable length standoff.
// they should be 2 nodes thick for spacers, extra long so that ALL hinges are 5 nodes wide.
//ForkHeight = (hingeStyle == "spacer") ? 2*NodeHeight : NodeHeight;
ForkHeight = NodeHeight;

// definitions of linkage lengths: AC;Ay;Bx;BH;EF;CD;CH;BD;BE;DE;FG;FH;GH
// derived quantities: DEleft;FGleft;DEperp;FGperp
include <JansenDefs.scad>;

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//       define some standard part dimensions for re-use in groups, etc.
acH0 = NodeHeight-.2;
acH1 = acH0+1.5;
acOR = Arad+3;
acIR = rad4;
pulleyR = 17;
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

module nodeCyl(nodeHeight,nodeRad)
{ cylinder(h=nodeHeight,r1=nodeRad+.3,r2=nodeRad-.3,$fn=64); }  // set to 20+ for production quality

module drillHole(holeRad) { translate([0,0,-.03])
   cylinder(h=22,r=holeRad,$fn=80); } // set to 80 for production run

module footpad(r) { // pad to help a part stick to plate for 3D printer
   color("Cyan") cylinder(h=layer1bias,r1=r,r2=r-.3,$fn=11); }

// place a point, usually inside a linkage bar, to use in a hull
// with a part connected to a linkage bar
module barAnchor(dx) {
   translate([dx,0,0]) cylinder(h=BarHeight,r1=.8,r2=.6,$fn=6);
}

use <pulley.scad>;

include <JansenMain.scad>
include <JansenFoot.scad>

module monoBracedLinkage(len) {
lro = Drad+1.8;  // outisde link radius
difference() { union() { //------------------------ EF
    difference() { hull() {  // main bar
      translate([ 0 ,0,0])   nodeCyl(BarHeight,Frad);
      translate([len,0,0])   nodeCyl(BarHeight,lro*.5);
      }
      hull() { translate([0,0,-1.5]) { nodeCyl(BarHeight,Frad-1.5);
               translate([len,0 ,0])   nodeCyl(BarHeight,1); }}
    }

    // non-braced (BED side) reinforcement
    translate(  [len,0,0]) { nodeCyl(BarHeight,lro);
       hull() { translate([0,0,BarHeight-1])
          cylinder(h=ForkHeight-BarHeight+1,r1=lro-.8,r2=rad4+1.2,$fn=64);
          cylinder(h=NodeHeight-1,r1=lro+.1,r2=rad4+1.2,$fn=16);
          //barAnchor(-1.5*lro);
          translate([-2*lro,0,2]) sphere(r=.4,$fn=12);
       }
    }
    hull() { translate([1.3*Frad,0,1.5]) scale([1,1,1]) sphere(r=1,$fn=16);
        translate([0,0,BarHeight-1])
          cylinder(h=ForkHeight-BarHeight+1,r1=Frad-.6,r2=rad4+1.6,$fn=64); }
    cylinder(h=BarHeight-1,r1=rad4+2.2,r2=rad4+3.3,$fn=32);

    hull() { // out-of-plane ridge/brace
        translate([ 0 ,0,2.2]) scale([1,1,2]) sphere(r=1,$fn=16);
        translate([len,0,2.2]) scale([1,1,2]) sphere(r=1,$fn=16); }
    }
    drillHole(rad4);
    translate([len,0,0]) drillHole(rad4);
}}

//------------------------------------------------------------ crankLink
// linkage with thin, wide connection for crank side, full node height on other
module crankLink(len,dFlat,rHole) {
// changing crank spindle to a 3/16 spacer instead of the 1/8" brass tube
radA = AradFree;  // free spinning on 3/16 OD standoff
echo(str("rHole=",rHole));
difference() { union() {
   hull() { cylinder(h=NodeHeight/2,r1=radA+3,r2=radA+2.8,$fn=48);
      translate([dFlat+4,0,0]) cylinder(h=NodeHeight/2,r1=1.2,r2=1,$fn=6); }
   translate([len,0,0]) { hull() {
      cylinder(h=NodeHeight,r1=rHole+2.2,r2=rHole+2,$fn=48);
         translate([-rHole-4,0,0]) cylinder(h=BarHeight,r1=1.2,r2=1,$fn=6); }}
   hull() {                  cylinder(h=NodeHeight/2,r1=LinkRad+.4,r2=LinkRad,$fn=6);
      translate([len/2,0,0]) cylinder(h=NodeHeight/2,r1=LinkRad+.4,r2=LinkRad,$fn=6); }
   hull() { translate([dFlat-2,0,0]) cylinder(h=BarHeight,r1=LinkRad+.4,r2=LinkRad-.2,$fn=6);
            translate([len-2  ,0,0]) cylinder(h=BarHeight,r1=LinkRad+.4,r2=LinkRad-.2,$fn=6); }
   hull() {
      translate([dFlat+2  ,0,BarHeight-1]) scale([1,1,1.5]) sphere(r=1,$fn=12);
      translate([len-rHole,0,BarHeight-1]) scale([1,1,1.5]) sphere(r=1,$fn=12);
      translate([len*0.65 ,0,BarHeight+.5]){scale([0.6,0.6,1.7]) sphere(r=1,$fn=12);
         translate([0,0,-2]) scale([2,2,1]) sphere(r=1,$fn=12);}
      translate([dFlat+15 ,0,BarHeight+.5]){scale([0.6,0.6,1.7]) sphere(r=1,$fn=12);
         translate([0,0,-2]) scale([2,2,1]) sphere(r=1,$fn=12);}
      }
   }
   drillHole(radA);  // a little extra to move freely
   translate([len,0,0]) drillHole(rHole);
}}

module linkage1(len,h0,r0,d0,h1,r1,d1) { difference() { union() {
   hull() { barAnchor(1.5*r0);
      cylinder(h=h0,r1=r0+.2,r2=r0-0.2,$fn=48); }
   translate([len,0,0]) { hull() { barAnchor(-1.5*r1);
      cylinder(h=h1,r1=r1,r2=0.4*r1+0.6*d1,$fn=48); }}
   hull() {                cylinder(h=BarHeight,r1=LinkRad+.2,r2=LinkRad-.2,$fn=6);
      translate([len,0,0]) cylinder(h=BarHeight,r1=LinkRad+.2,r2=LinkRad-.2,$fn=6); }
   hull() {                   cylinder(h=h0-0.5,r1=2,r2=.6,$fn=6);
      translate([len-d1,0,0]) cylinder(h=h1-0.5,r1=2,r2=.6,$fn=6); }
   }
   drillHole(d0);
   translate([len,0,0]) drillHole(d1);
}}

module linkage(len,h0,r0,d0,h1,r1,d1) { difference() { union() {
echo(str("linkage:",len,",",h0,",",r0,",",d0,",",h1,",",r1,",",d1));
   hull() { barAnchor(2.5*r0);
      cylinder(h=h0,r1=r0+.1,r2=r0-0.2,$fn=48); }
   translate([len,0,0]) { hull() { barAnchor(-2.5*r1);
      cylinder(h=h1,r1=r1+.1,r2=r1-.2,$fn=48); }}
   hull() {                cylinder(h=BarHeight,r1=LinkRad+.2,r2=LinkRad-.2,$fn=6);
      translate([len,0,0]) cylinder(h=BarHeight,r1=LinkRad+.2,r2=LinkRad-.2,$fn=6); }
   hull() {                   cylinder(h=h0-0.5,r1=2,r2=.6,$fn=6);
      translate([len-d1,0,0]) cylinder(h=h1-0.5,r1=2,r2=.6,$fn=6); }
   }
   drillHole(d0);
   translate([len,0,0]) drillHole(d1);
}}

// beefier version of a simple linkage, with same ends on both sides
module brace(len,h0,r0) {
r1=r0+1.7;
difference() { union() {
   difference() { hull() { cylinder(h=3,r1=r1+.1,r2=r1-.1,$fn=48);
      translate([len,0,0]) cylinder(h=3,r1=r1+.1,r2=r1-.1,$fn=48); }
      translate([1.5,0,-1.5]) hull() { cylinder(h=3,r1=r1-1.6,r2=r1-1.4,$fn=6);
             translate([len-1.5,0,0])  cylinder(h=3,r1=r1-1.6,r2=r1-1.4,$fn=6); }}

   translate([len,0,0])
   hull() { cylinder(h=h0,r1=r1+.2,r2=r1-.1,$fn=48);
      translate([-r1-4,0,2]) sphere(r=1,$fn=12); }
   hull() { cylinder(h=h0,r1=r1+.2,r2=r1-.1,$fn=48);
      translate([ r1+4,0,2]) sphere(r=1,$fn=12); }

   translate([0,0,h0/2]) hull() { scale([1,1,h0/2]) sphere(r=1,$fn=12);
            translate([len,0,0])  scale([1,1,h0/2]) sphere(r=1,$fn=12); }

   }
   drillHole(r0);
   translate([len,0,0]) drillHole(r0);
}}

module crankArm(len,h0,r0,d0,h1,r1,d1) { difference() {
  linkage(len,h0,r0,d0,h1,r1,d1);

  //// add little hole for "cotter-wire" on crank arm
  //translate([0,0,h0/2]) rotate(a=[90,0,0])
  //   cylinder(h=3*r0,r=.8,$fn=80,center=true);

  // for change to using standoffs as axle, counter sink axle screw
  translate([0,0,h0-1.5]) cylinder(h=2+.2,r1=rad4,r2=3.3,$fn=24);

  // try another countersink for spindle screw.
  translate([len,0,-1]) cylinder(h=2.2,r1=3.3,r2=rad4,$fn=24);
}}

include <JansenBED.scad>;

//---------------------
module BED(dLeft,dBase,dPerp) { union() { rotate([0,0,50]) {
   translate([dBase*0.2,-3*Drad,0]) rotate([0,0,180]) mirror([1,0,0])
   BED_pad(dLeft,dBase,dPerp);
   BED_pad(dLeft,dBase,dPerp);
}}}
module feet(dLeft,dBase,dPerp) { union() {
   translate([dBase*0.15,-0.5*dPerp,0]) rotate([0,0,190]) mirror([1,0,0])
   bracedFoot_pad(dLeft,dBase,dPerp);
   bracedFoot_pad(dLeft,dBase,dPerp);
}}

module mainPulley() {
ph=5;  // pulley thickness
sr=25.4 * 3/16/2 + 1.5*HoleFuzz;  // standoff countersink radius

  difference() {
    union() {
      pulley2(AC+5.5,ph,sr,0);  // make with radius for standoff
      translate([0,0,0.1])
        cylinder(r=sr+1,h=ph-0.7,$fn=12);  // fill back in for rod hole
    }

    translate([0,0,-1]) cylinder(r=rad4,h=ph+4,$fn=17); // drill hole for central rod
    for (y=[-1,1]) translate([0,AC*y,-1])
      cylinder(r=3,h=ph,$fn=36);  // screw pass-through for crank arm
  }

/*
sd=.8; // standoff countersink distance

  // countersink main pulley for standoffs a bit.
  difference() {
    union() {
      pulley(18,ph,rad4,0);
      // pulley hub was 1.3 mm higher than outher thickness.  a little more for countersink
      cylinder(r1=5,r2=4,h=ph+1.5,$fn=36);  // give pulley a wider hub
    }

    translate([0,0,-1]) {
      cylinder(r=rad4,h=ph+3,$fn=17); // main threaded rod hole
      //cylinder(r=sr,h=1+sd+.2,$fn=28); // a little extra on bridged standoff depth
    }
    translate([0,0,ph+1.5-sd-.5]) cylinder(r=sr,h=3,$fn=28);
  }
*/

}

//module motorPulley() pulley(10,4,1.5+dHoleFuzz,1+dHoleFuzz);
module motorPulley() pulley2(8,4,1.5+dHoleFuzz,1+dHoleFuzz);

use <motorMount.scad>
module motorMountDemo() {
po=8;  // main pulley offset
  translate([0,-Ay,0]) mainBar(Bx,Ay);
  translate([0,-Ay,22]) rotate([0,180,0]) mainBar(Bx,Ay);
  translate([0,-Ay-5.4,4]) rotate([0,180,0]) motorMount();
  translate([0,0,po]) mainPulley();
  #translate([0,0,po-12.7  ]) cylinder(r=25.4*3/16/2,h=25.4/2,$fn=18);
  #translate([0,0,po+6.6-.6]) cylinder(r=25.4*3/16/2,h=25.4/2,$fn=18);
  translate([0,-38.5,8]) motorPulley();
  translate([0,0,26.7]) rotate([0,0,90]) crankArmAC();
}

module crankArmAC() crankArm(AC,acH0,acOR,acIR,acH1,acOR,acIR);

//=====================================================
use <spacers.scad>;

if      (PART=="BED"  ) {                   BED(DEleft,DE,DEperp); }
//else if (PART=="BEDa" ) {                 imBED(DEleft,DE,DEperp); }
//else if (PART=="BEDb" ) { mirror([1,0,0]) imBED(DEleft,DE,DEperp); }
else if (PART=="HipA" ) {                 BED1(DEleft,DE,DEperp); }
else if (PART=="HipB" ) { mirror([1,0,0]) BED1(DEleft,DE,DEperp); }
else if (PART=="jHipA" ) { imBEDj(DEleft,DE,DEperp); }
else if (PART=="jHipB" ) { mirror([1,0,0]) imBEDj(DEleft,DE,DEperp); }
else if (PART=="Feet" )                         feet(FGleft,FG,FGperp);
else if (PART=="FootA")
//difference() {
                  bracedFoot(FGleft,FG,FGperp);
  //  translate([0,0,18]) cube([200,200,20],center=true); }
else if (PART=="FootB") { mirror([1,0,0]) bracedFoot(FGleft,FG,FGperp); }
else if (PART=="CH"   ) crankLink(CH,15,Hrad); // build 2
else if (PART=="CD"   ) crankLink(CD,15,Drad); // build 2
else if (PART=="EF"   ) monoBracedLinkage(EF); // build 4
else if (PART=="BH"   ) linkage1(BH,2.5*NodeHeight,Brad+2.5,BradFree+.2,3,Hrad+2.5,rad4);
else if (PART=="AC"   ) crankArmAC();
else if (PART=="pulley") {  mainPulley(); }
else if (PART=="drivePulley") { motorPulley(); }
else if (PART=="mainBar") {  mainBar(Bx,Ay); }
else if (PART=="braceBar") {  brace(2*Bx,8,Brad+.1); }
else if (PART=="spacers") { union(){ spacers(NodeHeight/2,Bhole+3,Brad);
   translate([0,-7.5*LinkRad*1.414+1,0]) spacers(NodeHeight/2,LinkRad,rad4); }}
else if (PART=="motor") { motorMountDemo(); }
//else if (PART=="demo") { //show all unique parts
else {
   mainBar(Bx,Ay);
   %translate([0,Ay,20]) mainPulley();
   translate([0,-50,0])  motorPulley();
   translate([ 50, 30,0]) BED1(DEleft,DE,DEperp);//imBED(DEleft,DE,DEperp);
   translate([-26, 44,0]) rotate([0,0,180]) bracedFoot(FGleft,FG,FGperp);
   translate([-12,-16,0]) crankLink(CD,15,Drad);
   translate([-36,-28,0]) crankLink(CH,15,Hrad);
   translate([-73,-15,0]) monoBracedLinkage(EF);
   translate([-60, 15,0]) crankArmAC();

   translate([ 25, 15,0]) linkage1(BH,2.5*NodeHeight,Brad+1.8,BradFree,ForkHeight,Hrad+2,rad4);
   translate([40,-42,0]) rotate([0,0,50]) brace(2*Bx,8,Brad);
}

//else if (PART=="halfPulley") { union() { color("Cyan") footpad(pulleyR+7); translate([0,0,.2]) halfPulley(pulleyR,2.5,AradTight,-1); }}
//else if (PART=="halfDrivePulley") { union() { color("Cyan") footpad(15);  translate([0,0,.1]) halfPulley(8,2.5,1.5+.3,1+.3); }}

// $URL: svn+ssh://mrwhat@ssh.boim.com/home/mrwhat/svn/Walker/trunk/Jansen.scad $
// $Id: Jansen.scad 427 2014-08-23 20:42:39Z mrwhat $

// Define PART to one of the following values to generate model for desired part.
//       HipA, HipB, FootA, FootB, CH, CD, EF, BH, AC, pulley, mainBar, drivePulley
// For a 2-leg (half-trotter) :  print (2) CH, CD ; (4) EF, BH ; (1) of the others
// For a production robot, glue a rectangular support/spacer between BH pairs for stiffness

// PART="motor" to show motor-mount assembly

// *** DEPRICATED
// Combined parts with pads, optimized for RepRap :
// Hip, Feet, crankLinks, EFs, BHs    : main, pulley, drivePulley as above (brace)
//
// standoffs also DEPRICATED
hingeStyle = "spacer"; //6standoff";  // spacer or standoff
// *****

PART="mainBar";
echo(str("PART=",PART));

HoleFuzz = 0.1;  // extra radius (mm) to add to holes to account for printer slop
dHoleFuzz = 0.2;  // extra radius (mm) to add to d-shaft holes.  Sometimes not the same as HoleFuzz since it is harder to clean D-shaft holes

// measured diameter of '3/16"' spacer was 4.74 to 4.76, not 4.7625 as expected.
// Current design:  3/16" axles at B
//                  3/16" long 1/4"  OD standoffs at D, E, F
//                  1/2"  long 3/16" OD standoffs at H, A, C
Bdiam = 4.7625;  // larger brass tube rdiameter, measured on 3/16" tube
Adiam = 4.76;
Hdiam = Adiam;
//Ddiam = 6.35;  // 1/4" OD standoffs
Ddiam = Adiam;  // 3/16" OD standoffs/spacers
diam4 = 2.76;  // diameter of #4-40 screw, OD of thread

// on spacer tests:
//    Brad +.125 mm was snug, but not quite free rotating
//         +.05     turned, but not freely
//         -.025    still turned,  was very close
//    Arad +.125    turned free (good for main, crankLinks)
//         +.05     was press-to-fit (good for crankArm)
//    rad4 + 0.2    allowed a screw to go through snugly but freely
//         +.125    only threaded through
//  1/4"OD + 0.2    was a snug fit, no turn.  almost press-to-fit
//         + 0.275  snug, free turn... good for hinges on standoff

Brad = Bdiam/2 + HoleFuzz/2;    // 4.76mm diam brass tube -- critical fit
Arad = Adiam/2 + HoleFuzz/2.3;  // 3.18mm diam brass tube -- critical fit
rad4 = diam4/2 + HoleFuzz;  // good for screw pass-through
Hrad = Hdiam/2 + HoleFuzz*1.35;  // standoff holes for freely-moving hinges
Drad = Ddiam/2 + HoleFuzz;
AradFree = Adiam/2 + .25;  // loose fit on spindle

BradTight = Brad-0.05;
BradFree  = Brad+0.05;

Frad = 7;  // radius of beefed-up "knee"

LinkRad=3;
BarHeight=3;
//NodeHeight=5.8;  // gives a little room for 6.35 mm (.25 inch) standoffs
layer1bias=0.4;  // shift up for 1 layer of brim/raft

// 9/16" spacer height 14.37mm, not 14.287 as expected
// 3/16" spacer height  4.79mm, not 4.7625 as expected (*3=14.37)
// 1/4" Al standoffs were pretty close, and 3x was 19.02mm high, not 19.05 as expected, pretty close
//TrueNodeHeight = (hingeStyle == "spacer") ? 4.79-.2 : 6.35;
TrueNodeHeight = 4.79-.2;
NodeHeight = TrueNodeHeight - 0.3;  // a little room for hinges
//NodeHeight3 = 25.4*((hingeStyle == "spacer") ? 9/16 : 3/4) - 0.3;
// moving to slightly thinner 1/2" standoffs at H
NodeHeight3 = 25.4/2 - 0.3;

// Forks should be 1 node thick for standoffs...  short screws go into variable length standoff.
// they should be 2 nodes thick for spacers, extra long so that ALL hinges are 5 nodes wide.
//ForkHeight = (hingeStyle == "spacer") ? 2*NodeHeight : NodeHeight;
ForkHeight = NodeHeight;

// definitions of linkage lengths: AC;Ay;Bx;BH;EF;CD;CH;BD;BE;DE;FG;FH;GH
// derived quantities: DEleft;FGleft;DEperp;FGperp
include <JansenDefs.scad>;

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//       define some standard part dimensions for re-use in groups, etc.
acH0 = NodeHeight-.2;
acH1 = acH0+1.5;
acOR = Arad+3;
acIR = rad4;
pulleyR = 17;
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

module nodeCyl(nodeHeight,nodeRad)
{ cylinder(h=nodeHeight,r1=nodeRad+.3,r2=nodeRad-.3,$fn=64); }  // set to 20+ for production quality

module drillHole(holeRad) { translate([0,0,-.03])
   cylinder(h=22,r=holeRad,$fn=80); } // set to 80 for production run

module footpad(r) { // pad to help a part stick to plate for 3D printer
   color("Cyan") cylinder(h=layer1bias,r1=r,r2=r-.3,$fn=11); }

// place a point, usually inside a linkage bar, to use in a hull
// with a part connected to a linkage bar
module barAnchor(dx) {
   translate([dx,0,0]) cylinder(h=BarHeight,r1=.8,r2=.6,$fn=6);
}

use <pulley.scad>;

include <JansenMain.scad>
include <JansenFoot.scad>

module monoBracedLinkage(len) {
lro = Drad+1.8;  // outisde link radius
difference() { union() { //------------------------ EF
    difference() { hull() {  // main bar
      translate([ 0 ,0,0])   nodeCyl(BarHeight,Frad);
      translate([len,0,0])   nodeCyl(BarHeight,lro*.5);
      }
      hull() { translate([0,0,-1.5]) { nodeCyl(BarHeight,Frad-1.5);
               translate([len,0 ,0])   nodeCyl(BarHeight,1); }}
    }

    // non-braced (BED side) reinforcement
    translate(  [len,0,0]) { nodeCyl(BarHeight,lro);
       hull() { translate([0,0,BarHeight-1])
          cylinder(h=ForkHeight-BarHeight+1,r1=lro-.8,r2=rad4+1.2,$fn=64);
          cylinder(h=NodeHeight-1,r1=lro+.1,r2=rad4+1.2,$fn=16);
          //barAnchor(-1.5*lro);
          translate([-2*lro,0,2]) sphere(r=.4,$fn=12);
       }
    }
    hull() { translate([1.3*Frad,0,1.5]) scale([1,1,1]) sphere(r=1,$fn=16);
        translate([0,0,BarHeight-1])
          cylinder(h=ForkHeight-BarHeight+1,r1=Frad-.6,r2=rad4+1.6,$fn=64); }
    cylinder(h=BarHeight-1,r1=rad4+2.2,r2=rad4+3.3,$fn=32);

    hull() { // out-of-plane ridge/brace
        translate([ 0 ,0,2.2]) scale([1,1,2]) sphere(r=1,$fn=16);
        translate([len,0,2.2]) scale([1,1,2]) sphere(r=1,$fn=16); }
    }
    drillHole(rad4);
    translate([len,0,0]) drillHole(rad4);
}}

//------------------------------------------------------------ crankLink
// linkage with thin, wide connection for crank side, full node height on other
module crankLink(len,dFlat,rHole) {
// changing crank spindle to a 3/16 spacer instead of the 1/8" brass tube
radA = AradFree;  // free spinning on 3/16 OD standoff
echo(str("rHole=",rHole));
difference() { union() {
   hull() { cylinder(h=NodeHeight/2,r1=radA+3,r2=radA+2.8,$fn=48);
      translate([dFlat+4,0,0]) cylinder(h=NodeHeight/2,r1=1.2,r2=1,$fn=6); }
   translate([len,0,0]) { hull() {
      cylinder(h=NodeHeight,r1=rHole+2.2,r2=rHole+2,$fn=48);
         translate([-rHole-4,0,0]) cylinder(h=BarHeight,r1=1.2,r2=1,$fn=6); }}
   hull() {                  cylinder(h=NodeHeight/2,r1=LinkRad+.4,r2=LinkRad,$fn=6);
      translate([len/2,0,0]) cylinder(h=NodeHeight/2,r1=LinkRad+.4,r2=LinkRad,$fn=6); }
   hull() { translate([dFlat-2,0,0]) cylinder(h=BarHeight,r1=LinkRad+.4,r2=LinkRad-.2,$fn=6);
            translate([len-2  ,0,0]) cylinder(h=BarHeight,r1=LinkRad+.4,r2=LinkRad-.2,$fn=6); }
   hull() {
      translate([dFlat+2  ,0,BarHeight-1]) scale([1,1,1.5]) sphere(r=1,$fn=12);
      translate([len-rHole,0,BarHeight-1]) scale([1,1,1.5]) sphere(r=1,$fn=12);
      translate([len*0.65 ,0,BarHeight+.5]){scale([0.6,0.6,1.7]) sphere(r=1,$fn=12);
         translate([0,0,-2]) scale([2,2,1]) sphere(r=1,$fn=12);}
      translate([dFlat+15 ,0,BarHeight+.5]){scale([0.6,0.6,1.7]) sphere(r=1,$fn=12);
         translate([0,0,-2]) scale([2,2,1]) sphere(r=1,$fn=12);}
      }
   }
   drillHole(radA);  // a little extra to move freely
   translate([len,0,0]) drillHole(rHole);
}}

module linkage1(len,h0,r0,d0,h1,r1,d1) { difference() { union() {
   hull() { barAnchor(1.5*r0);
      cylinder(h=h0,r1=r0+.2,r2=r0-0.2,$fn=48); }
   translate([len,0,0]) { hull() { barAnchor(-1.5*r1);
      cylinder(h=h1,r1=r1,r2=0.4*r1+0.6*d1,$fn=48); }}
   hull() {                cylinder(h=BarHeight,r1=LinkRad+.2,r2=LinkRad-.2,$fn=6);
      translate([len,0,0]) cylinder(h=BarHeight,r1=LinkRad+.2,r2=LinkRad-.2,$fn=6); }
   hull() {                   cylinder(h=h0-0.5,r1=2,r2=.6,$fn=6);
      translate([len-d1,0,0]) cylinder(h=h1-0.5,r1=2,r2=.6,$fn=6); }
   }
   drillHole(d0);
   translate([len,0,0]) drillHole(d1);
}}

module linkage(len,h0,r0,d0,h1,r1,d1) { difference() { union() {
echo(str("linkage:",len,",",h0,",",r0,",",d0,",",h1,",",r1,",",d1));
   hull() { barAnchor(2.5*r0);
      cylinder(h=h0,r1=r0+.1,r2=r0-0.2,$fn=48); }
   translate([len,0,0]) { hull() { barAnchor(-2.5*r1);
      cylinder(h=h1,r1=r1+.1,r2=r1-.2,$fn=48); }}
   hull() {                cylinder(h=BarHeight,r1=LinkRad+.2,r2=LinkRad-.2,$fn=6);
      translate([len,0,0]) cylinder(h=BarHeight,r1=LinkRad+.2,r2=LinkRad-.2,$fn=6); }
   hull() {                   cylinder(h=h0-0.5,r1=2,r2=.6,$fn=6);
      translate([len-d1,0,0]) cylinder(h=h1-0.5,r1=2,r2=.6,$fn=6); }
   }
   drillHole(d0);
   translate([len,0,0]) drillHole(d1);
}}

// beefier version of a simple linkage, with same ends on both sides
module brace(len,h0,r0) {
r1=r0+1.7;
difference() { union() {
   difference() { hull() { cylinder(h=3,r1=r1+.1,r2=r1-.1,$fn=48);
      translate([len,0,0]) cylinder(h=3,r1=r1+.1,r2=r1-.1,$fn=48); }
      translate([1.5,0,-1.5]) hull() { cylinder(h=3,r1=r1-1.6,r2=r1-1.4,$fn=6);
             translate([len-1.5,0,0])  cylinder(h=3,r1=r1-1.6,r2=r1-1.4,$fn=6); }}

   translate([len,0,0])
   hull() { cylinder(h=h0,r1=r1+.2,r2=r1-.1,$fn=48);
      translate([-r1-4,0,2]) sphere(r=1,$fn=12); }
   hull() { cylinder(h=h0,r1=r1+.2,r2=r1-.1,$fn=48);
      translate([ r1+4,0,2]) sphere(r=1,$fn=12); }

   translate([0,0,h0/2]) hull() { scale([1,1,h0/2]) sphere(r=1,$fn=12);
            translate([len,0,0])  scale([1,1,h0/2]) sphere(r=1,$fn=12); }

   }
   drillHole(r0);
   translate([len,0,0]) drillHole(r0);
}}

module crankArm(len,h0,r0,d0,h1,r1,d1) { difference() {
  linkage(len,h0,r0,d0,h1,r1,d1);

  //// add little hole for "cotter-wire" on crank arm
  //translate([0,0,h0/2]) rotate(a=[90,0,0])
  //   cylinder(h=3*r0,r=.8,$fn=80,center=true);

  // for change to using standoffs as axle, counter sink axle screw
  translate([0,0,h0-1.5]) cylinder(h=2+.2,r1=rad4,r2=3.3,$fn=24);

  // try another countersink for spindle screw.
  translate([len,0,-1]) cylinder(h=2.2,r1=3.3,r2=rad4,$fn=24);
}}

include <JansenBED.scad>;

//---------------------
module BED(dLeft,dBase,dPerp) { union() { rotate([0,0,50]) {
   translate([dBase*0.2,-3*Drad,0]) rotate([0,0,180]) mirror([1,0,0])
   BED_pad(dLeft,dBase,dPerp);
   BED_pad(dLeft,dBase,dPerp);
}}}
module feet(dLeft,dBase,dPerp) { union() {
   translate([dBase*0.15,-0.5*dPerp,0]) rotate([0,0,190]) mirror([1,0,0])
   bracedFoot_pad(dLeft,dBase,dPerp);
   bracedFoot_pad(dLeft,dBase,dPerp);
}}

module mainPulley() {
ph=5;  // pulley thickness
sr=25.4 * 3/16/2 + 1.5*HoleFuzz;  // standoff countersink radius

  difference() {
    union() {
      pulley2(AC+5.5,ph,sr,0);  // make with radius for standoff
      translate([0,0,0.1])
        cylinder(r=sr+1,h=ph-0.7,$fn=12);  // fill back in for rod hole
    }

    translate([0,0,-1]) cylinder(r=rad4,h=ph+4,$fn=17); // drill hole for central rod
    for (y=[-1,1]) translate([0,AC*y,-1])
      cylinder(r=3,h=ph,$fn=36);  // screw pass-through for crank arm
  }

/*
sd=.8; // standoff countersink distance

  // countersink main pulley for standoffs a bit.
  difference() {
    union() {
      pulley(18,ph,rad4,0);
      // pulley hub was 1.3 mm higher than outher thickness.  a little more for countersink
      cylinder(r1=5,r2=4,h=ph+1.5,$fn=36);  // give pulley a wider hub
    }

    translate([0,0,-1]) {
      cylinder(r=rad4,h=ph+3,$fn=17); // main threaded rod hole
      //cylinder(r=sr,h=1+sd+.2,$fn=28); // a little extra on bridged standoff depth
    }
    translate([0,0,ph+1.5-sd-.5]) cylinder(r=sr,h=3,$fn=28);
  }
*/

}

//module motorPulley() pulley(10,4,1.5+dHoleFuzz,1+dHoleFuzz);
module motorPulley() pulley2(8,4,1.5+dHoleFuzz,1+dHoleFuzz);

use <motorMount.scad>
module motorMountDemo() {
po=8;  // main pulley offset
  translate([0,-Ay,0]) mainBar(Bx,Ay);
  translate([0,-Ay,22]) rotate([0,180,0]) mainBar(Bx,Ay);
  translate([0,-Ay-5.4,4]) rotate([0,180,0]) motorMount();
  translate([0,0,po]) mainPulley();
  #translate([0,0,po-12.7  ]) cylinder(r=25.4*3/16/2,h=25.4/2,$fn=18);
  #translate([0,0,po+6.6-.6]) cylinder(r=25.4*3/16/2,h=25.4/2,$fn=18);
  translate([0,-38.5,8]) motorPulley();
  translate([0,0,26.7]) rotate([0,0,90]) crankArmAC();
}

module crankArmAC() crankArm(AC,acH0,acOR,acIR,acH1,acOR,acIR);

//=====================================================
use <spacers.scad>;

if      (PART=="BED"  ) {                   BED(DEleft,DE,DEperp); }
//else if (PART=="BEDa" ) {                 imBED(DEleft,DE,DEperp); }
//else if (PART=="BEDb" ) { mirror([1,0,0]) imBED(DEleft,DE,DEperp); }
else if (PART=="HipA" ) {                 BED1(DEleft,DE,DEperp); }
else if (PART=="HipB" ) { mirror([1,0,0]) BED1(DEleft,DE,DEperp); }
else if (PART=="jHipA" ) { imBEDj(DEleft,DE,DEperp); }
else if (PART=="jHipB" ) { mirror([1,0,0]) imBEDj(DEleft,DE,DEperp); }
else if (PART=="Feet" )                         feet(FGleft,FG,FGperp);
else if (PART=="FootA")
//difference() {
                  bracedFoot(FGleft,FG,FGperp);
  //  translate([0,0,18]) cube([200,200,20],center=true); }
else if (PART=="FootB") { mirror([1,0,0]) bracedFoot(FGleft,FG,FGperp); }
else if (PART=="CH"   ) crankLink(CH,15,Hrad); // build 2
else if (PART=="CD"   ) crankLink(CD,15,Drad); // build 2
else if (PART=="EF"   ) monoBracedLinkage(EF); // build 4
else if (PART=="BH"   ) linkage1(BH,2.5*NodeHeight,Brad+2,BradFree+.2,3,Hrad+2.5,rad4);
else if (PART=="AC"   ) crankArmAC();
else if (PART=="pulley") {  mainPulley(); }
else if (PART=="drivePulley") { motorPulley(); }
else if (PART=="mainBar") {  mainBar(Bx,Ay); }
else if (PART=="braceBar") {  brace(2*Bx,8,Brad+.1); }
else if (PART=="spacers") { union(){ spacers(NodeHeight/2,Bhole+3,Brad);
   translate([0,-7.5*LinkRad*1.414+1,0]) spacers(NodeHeight/2,LinkRad,rad4); }}
else if (PART=="motor") { motorMountDemo(); }
//else if (PART=="demo") { //show all unique parts
else {
   mainBar(Bx,Ay);
   %translate([0,Ay,20]) mainPulley();
   translate([0,-50,0])  motorPulley();
   translate([ 50, 30,0]) BED1(DEleft,DE,DEperp);//imBED(DEleft,DE,DEperp);
   translate([-26, 44,0]) rotate([0,0,180]) bracedFoot(FGleft,FG,FGperp);
   translate([-12,-16,0]) crankLink(CD,15,Drad);
   translate([-36,-28,0]) crankLink(CH,15,Hrad);
   translate([-73,-15,0]) monoBracedLinkage(EF);
   translate([-60, 15,0]) crankArmAC();

   translate([ 25, 15,0]) linkage1(BH,2.5*NodeHeight,Brad+1.8,BradFree,ForkHeight,Hrad+2,rad4);
   translate([40,-42,0]) rotate([0,0,50]) brace(2*Bx,8,Brad);
}

//else if (PART=="halfPulley") { union() { color("Cyan") footpad(pulleyR+7); translate([0,0,.2]) halfPulley(pulleyR,2.5,AradTight,-1); }}
//else if (PART=="halfDrivePulley") { union() { color("Cyan") footpad(15);  translate([0,0,.1]) halfPulley(8,2.5,1.5+.3,1+.3); }}


fixed cuts' span

fixed cuts' span

// closing nails' parameters
nail_thickness = 1;
nail_head      = 3.5;
nail_span      = 43;
nail_outstand  = 3;

module cut(height, length, span_up, span_down)
{
  up_offset = (span_down-span_up)/2;
  polyhedron(
    points = [
               [ 0,                 0,       0],      // 0
               [ up_offset,         length,  0],      // 1
               [ up_offset+span_up, length,  0],      // 2
               [ span_down,         0,       0],      // 3
               [ 0,                 0,       height], // 4
               [ up_offset,         length,  height], // 5
               [ up_offset+span_up, length,  height], // 6
               [ span_down,         0,       height]  // 7
             ],
    faces = [
              // bottom
              [4,5,7],
              [5,6,7],
              // top
              [2,1,0],
              [0,3,2],
              // upper wall
              [1,2,5],
              [6,5,2],
              // lower wall
              [4,3,0],
              [3,4,7],
              // left wall
              [0,1,4],
              [5,4,1],
              // right wall
              [2,3,7],
              [7,6,2]
            ]
  );
}

spacing = 2;
top     = 1.5*nail_thickness;
bottom  = 2*nail_head;
cut_h   = (nail_head - nail_thickness)*8;
h       = cut_h + 2*spacing;
l       = nail_span + bottom/2*2 + 2*spacing;
thick   = nail_outstand/2;

difference()
{
  cube([l, h, thick]);
  for(dx = [spacing, l-spacing-bottom])
    translate([dx, (h-cut_h)/2, 0])
      cut(thick, cut_h, top, bottom);
}

// closing nails' parameters
nail_thickness = 1;
nail_head      = 3.5;
nail_span      = 43;
nail_outstand  = 3;

module cut(height, length, span_up, span_down)
{
  up_offset = (span_down-span_up)/2;
  polyhedron(
    points = [
               [ 0,                 0,       0],      // 0
               [ up_offset,         length,  0],      // 1
               [ up_offset+span_up, length,  0],      // 2
               [ span_down,         0,       0],      // 3
               [ 0,                 0,       height], // 4
               [ up_offset,         length,  height], // 5
               [ up_offset+span_up, length,  height], // 6
               [ span_down,         0,       height]  // 7
             ],
    faces = [
              // bottom
              [4,5,7],
              [5,6,7],
              // top
              [2,1,0],
              [0,3,2],
              // upper wall
              [1,2,5],
              [6,5,2],
              // lower wall
              [4,3,0],
              [3,4,7],
              // left wall
              [0,1,4],
              [5,4,1],
              // right wall
              [2,3,7],
              [7,6,2]
            ]
  );
}

spacing = 2;
top     = 1.5*nail_thickness;
bottom  = 2*nail_head;
cut_h   = (nail_head-nail_thickness)*8;
h       = cut_h + 2*spacing;
l       = nail_span + bottom/2*2 + 2*5;
thick   = nail_outstand/2;

difference()
{
  cube([l, h, thick]);
  for(dx = [spacing, l-spacing-bottom])
    translate([dx, (h-cut_h)/2, 0])
      cut(thick, cut_h, top, bottom);
}