Untitled
unknown
plain_text
2 months ago
14 kB
32
Indexable
//
// Dog Wheelchair (OpenSCAD) — mm, Customizer-ready (v2025-08-22c)
// - Selectable support rule: add the bar if weight >= threshold (default) or <= threshold.
// - Wheels are aligned to the axle hole of the supports (reuse Part E’s transform chain).
// - all_parts arranged in a grid with mirrored versions and print-friendly orientations.
// - Extra-long through holes for straps/screws.
//
// ------------------------------------------------------------
/* [View Mode] */
part = "wheelchair_sim"; // [wheelchair_sim:Wheelchair Simulation,part_a:Part A,part_b:Part B,part_b2:Part B2,part_c:Part C,part_d:Part D,part_e:Part E,all_parts:All Parts]
/* [Dog - Dimensions (mm)] */
// Body width (side-to-side)
dog_width = 152; // ~6"
// Hind height
dog_height = 203; // ~8"
// Belly to tail
dog_length = 356; // ~14"
/* [Wheels & Hardware (mm)] */
wheel_diameter = 102; // ~4"
screw_diameter = 6.35; // 1/4"
tube_outer_diameter = 19.7; // 0.776" (tube OD)
/* [Frame] */
wheel_angle = 0; // Rear upright tilt (deg): 0..15
wheel_axle_back_offset = 90; // Axle distance behind front crossbar (mm)
clearance_back = 50; // Shorten simulated frame at the back (mm)
ground_clearance_allowance = 25; // Ground clearance allowance (mm)
/* [Support Bar] */
auto_support = true; // enable rule
support_rule = "heavier"; // [heavier:Add bar if weight >= threshold, lighter:Add bar if weight <= threshold]
dog_weight_kg = 5.0;
support_threshold_kg = 4.5;
force_extra_support_bar = false; // force the bar regardless of rule
/* [Joints / Bends] */
fit = 0.25; // tube->socket clearance (mm)
joint_wall = 5; // radial wall thickness (mm)
joint_cyl_length = 25; // straight cylinder length (mm)
bend_radius = 1; // torus path radius (mm)
angle_1 = -30; // lower bend arm (deg)
angle_2 = 60; // upper bend arm (deg)
/* [Quality] */
$fa = 6; // max facet angle
$fs = 0.5; // min facet size
/* [Colors] */
col_parts = "chartreuse";
col_frame = "lightgrey";
col_wheels = "dimgray";
/* [Hidden / Derived] */
tube_radius = tube_outer_diameter/2;
inner_radius = tube_radius + fit; // socket radius for tube
outer_radius = inner_radius + joint_wall;
cyllength = joint_cyl_length;
wheel_radius = wheel_diameter/2;
screw_radius = screw_diameter/2;
// Simulated frame geometry
chair_length = dog_length - clearance_back;
chair_width = dog_width;
chair_height = max(5, dog_height - wheel_radius - ground_clearance_allowance);
ang = wheel_angle; // OpenSCAD uses degrees
// Support rule
bar = force_extra_support_bar ||
(auto_support
? (support_rule == "heavier"
? (dog_weight_kg >= support_threshold_kg)
: (dog_weight_kg <= support_threshold_kg))
: false);
// Axle position along Y (negative is backward)
chairwheeldistance = wheel_axle_back_offset;
// Grid spacing for "all_parts"
grid_dx = 160;
grid_dy = 110;
/* ---------- Utilities ---------- */
module drill_z(r, h, center=false){ cylinder(r=r, h=h, center=center); }
module drill_x(r, h, center=false){ rotate(90, [0,1,0]) cylinder(r=r, h=h, center=center); }
module drill_y(r, h, center=false){ rotate(90, [1,0,0]) cylinder(r=r, h=h, center=center); }
/* ---------- Wheel (disc) ---------- */
module wheel_disc_raw(){ // flat disc without extra transforms
color(col_wheels) scale([1,1,0.25]) sphere(r=wheel_radius);
}
/* ---------- Bends (hex section) ---------- */
module bend(){
difference(){
rotate_extrude(){ translate([bend_radius + outer_radius, 0, 0]) circle(r=outer_radius, $fn=6); }
rotate_extrude(){ translate([bend_radius + outer_radius, 0, 0]) circle(r=inner_radius); }
rotate([0,0,angle_1]) translate([-100,-100,-50]) cube([300,100,100]);
rotate([0,0,angle_2]) translate([-100, 0,-50]) cube([300,100,100]);
}
}
module bend2(){
intersection(){
rotate([0,0,-30]) translate([0,0,-50]) cube([100,100,100]);
difference(){
rotate_extrude(){ translate([bend_radius + outer_radius, 0, 0]) rotate([0,0,90]) circle(r=outer_radius, $fn=6); }
rotate_extrude(){ translate([bend_radius + outer_radius, 0, 0]) circle(r=inner_radius); }
rotate([0,0,angle_1]) translate([-100,-100,-50]) cube([300,100,100]);
rotate([0,0,angle_2]) translate([-100, 0,-50]) cube([300,100,100]);
}
}
}
/* ---------- Strap blocks + through-holes ---------- */
module strapholes(){ translate([-15,33,-50]) drill_z(screw_radius, 200); }
module straps1(){
difference(){
union(){ translate([-25.38,28.9,-10]) cube([20,20,20]); }
union(){
rotate(-30,[1,0,0]) translate([-40,-100,20.926]) cube([200,200,20]);
rotate( 30,[1,0,0]) translate([-40,-100,-43.63]) cube([200,200,22.7]);
translate([-40,39,-20]) cube([200,200,50]);
}
rotate( 10,[1,0,0]) strapholes();
}
}
module straps2(){
difference(){
union(){ translate([-25.38,28.9,-10]) cube([12,20,20]); }
union(){
rotate(-30,[1,0,0]) translate([-40,-100,20.926]) cube([200,200,20]);
rotate( 30,[1,0,0]) translate([-40,-100,-43.63]) cube([200,200,22.7]);
}
translate([-40,39,-20]) cube([200,200,50]);
rotate(90,[0,1,0]) translate([0,33,-50]) drill_z(screw_radius, 400);
}
}
module straps3(){
difference(){
union(){ translate([-25.38,28.9,-10]) cube([20,20,20]); }
union(){
rotate(-30,[1,0,0]) translate([-40,-100,20.926]) cube([200,200,20]);
rotate( 30,[1,0,0]) translate([-40,-100,-43.63]) cube([200,200,22.7]);
translate([-40,39,-20]) cube([200,200,50]);
}
rotate(-10,[1,0,0]) strapholes();
}
}
/* ---------- Printable parts (A..E, B2) ---------- */
module partA(){
color(col_parts)
union(){
rotate([0,0,angle_1]) translate([bend_radius+outer_radius,0.02,0]) rotate([90,90,0])
difference(){ cylinder(r=outer_radius, h=cyllength, $fn=6); translate([0,0,-1]) cylinder(r=inner_radius, h=cyllength+5); }
rotate([0,0,angle_2]) translate([bend_radius+outer_radius,-0.02,0]) rotate([-90,90,0])
difference(){ cylinder(r=outer_radius, h=cyllength, $fn=6); translate([0,0,-1]) cylinder(r=inner_radius, h=cyllength+5); }
bend2();
rotate(-30,[0,0,1]) straps1();
}
}
module partB_common(_use_straps3=false){
color(col_parts)
union(){
rotate(120,[0,0,1])
union(){
rotate([0,0,angle_1]) translate([bend_radius+outer_radius,0.02,0]) rotate([90,0,ang])
difference(){ cylinder(r=outer_radius, h=cyllength, $fn=6); translate([0,0,-10]) cylinder(r=inner_radius, h=cyllength+15); }
rotate([0,0,angle_2]) translate([bend_radius+outer_radius,-38,0]) rotate([-90,0,0])
difference(){ cylinder(r=outer_radius, h=cyllength*1.75, $fn=6); translate([0,0,-1]) cylinder(r=inner_radius, h=cyllength*2+5); }
difference(){
bend();
rotate([0,0,angle_2]) translate([bend_radius+outer_radius,-40,0]) rotate([-90,0,0])
translate([0,0,-1]) cylinder(r=inner_radius, h=cyllength*2+5);
}
}
rotate(90,[0,1,0]) rotate(-90,[0,0,1]) translate([-12.62,-15.95,-15.95]){
if(_use_straps3) straps3(); else straps1();
}
}
}
module partB(){ partB_common(false); }
module partB2(){ mirror([1,0,0]) partB_common(true); }
module partC(){
color(col_parts)
difference(){
rotate(120,[0,0,1])
rotate([0,0,angle_1]) translate([bend_radius+outer_radius,0.02,0]) rotate([90,0,0]) rotate([0,0,90])
difference(){ cylinder(r=outer_radius, h=cyllength-5.4, $fn=6); translate([0,0,-10]) cylinder(r=inner_radius, h=cyllength+60); }
}
translate([25.36,0,0]) straps1();
}
module partD(){
color(col_parts)
difference(){
rotate(120,[0,0,1])
rotate([0,0,angle_1]) translate([bend_radius+outer_radius,0.02,0]) rotate([90,0,0]) rotate([0,0,90])
difference(){ cylinder(r=outer_radius, h=cyllength+20, $fn=6); translate([0,0,10]) cylinder(r=inner_radius, h=cyllength+25); }
}
translate([50.76,0,0]) straps1();
translate([25.36,0,0]) straps2();
}
module partE(){
color(col_parts)
translate([0,0,-tan(ang)*2.2]) rotate(ang,[1,0,0])
difference(){
rotate(120,[0,0,1])
union(){
if(bar){
rotate([0,0,angle_1]) translate([bend_radius+outer_radius,0.02,0]) rotate([90,90,0])
difference(){ cylinder(r=outer_radius, h=cyllength, $fn=6); translate([0,0,-1]) cylinder(r=inner_radius, h=cyllength+5); }
}
rotate([0,0,angle_2]) translate([bend_radius+outer_radius,-43,0]) rotate([-90,90,0])
difference(){
cylinder(r=outer_radius, h=cyllength*1.75 + 25.4, $fn=6);
translate([0,0,-1]) cylinder(r=inner_radius, h=cyllength*2+5);
// axle hole (very long)
translate([0,50,60]) rotate(90,[1,0,0]) drill_z(screw_radius, 400);
}
if(bar){
difference(){
bend2();
rotate([0,0,angle_2]) translate([bend_radius+outer_radius,-40,0]) rotate([-90,0,0])
translate([0,0,-1]) cylinder(r=inner_radius, h=cyllength*2+5);
}
}
}
}
}
/* ---------- Wheels from Part E pose ---------- */
// reproduces the same transforms to the axle, then places the disc
module wheel_from_partE_local(){
translate([0,0,-tan(ang)*2.2])
rotate(ang,[1,0,0])
rotate(120,[0,0,1])
rotate([0,0,angle_2])
translate([bend_radius + outer_radius, -43, 0])
rotate([-90,90,0])
translate([0,50,60])
rotate(90,[1,0,0])
wheel_disc_raw();
}
module wheels_from_partE_pair(){
// right
translate([outer_radius , -chairwheeldistance, -chair_height - outer_radius])
rotate(90,[1,0,0]) wheel_from_partE_local();
// left (mirrored; same chain as the assembly of Part E)
mirror([1,0,0])
translate([-chair_width + outer_radius , -chairwheeldistance, -chair_height - outer_radius])
rotate(90,[1,0,0]) wheel_from_partE_local();
}
/* ---------- Simulated frame ---------- */
module wheelchair(){
union(){
// side rails
translate([ chair_width, 0 ,0]) rotate(90,[1,0,0]) cylinder(r=inner_radius, h=chair_length);
translate([ 0, 0 ,0]) rotate(90,[1,0,0]) cylinder(r=inner_radius, h=chair_length);
// front crossbar
rotate(90,[0,1,0]) cylinder(r=inner_radius, h=chair_width);
// rear uprights (angled)
rotate(ang,[1,0,0]) translate([ 0, -chairwheeldistance , -chair_height]) cylinder(r=inner_radius, h=chair_height);
mirror([1,0,0]) rotate(ang,[1,0,0]) translate([ -chair_width, -chairwheeldistance , -chair_height]) cylinder(r=inner_radius, h=chair_height);
// extra support bar (if enabled)
if(bar){ rotate(90,[0,1,0]) translate([ chair_height, -chairwheeldistance , 0]) cylinder(r=inner_radius, h=chair_width); }
}
// wheels aligned to Part E axle
wheels_from_partE_pair();
}
/* ---------- Print orientations (used by all_parts) ---------- */
module orient_A(){ rotate(-90,[1,0,0]) translate([-80,-30,25]) rotate(120,[0,0,1]) partA(); }
module orient_A_m(){ rotate(-90,[1,0,0]) translate([-80,-30,25]) rotate(120,[0,0,1]) mirror([1,0,0]) partA(); }
module orient_B(){ translate([-90,-20,13]) rotate(180,[1,0,0]) partB(); }
module orient_B2(){ translate([-90,-20,13]) rotate(180,[1,0,0]) partB2(); }
module orient_C(){ translate([-40,10,-3]) rotate(90,[1,0,0]) partC(); }
module orient_C_m(){ translate([-40,10,-3]) rotate(90,[1,0,0]) mirror([1,0,0]) partC(); }
module orient_D(){ translate([30,-35,-3]) rotate(90,[1,0,0]) partD(); }
module orient_D_m(){ translate([30,-35,-3]) rotate(90,[1,0,0]) mirror([1,0,0]) partD(); }
module orient_E(){ translate([-10,-35,29]) rotate(90,[0,0,1]) rotate(-90,[0,1,0]) partE(); }
module orient_E_m(){ translate([-10,-35,29]) rotate(90,[0,0,1]) rotate(-90,[0,1,0]) mirror([1,0,0]) partE(); }
/* ---------- RENDER (selector) ---------- */
print_part();
module print_part(){
if (part == "wheelchair_sim"){
union(){
// part A + mirror
translate([outer_radius,-outer_radius,0]) rotate(120,[0,0,1]) partA();
mirror([1,0,0]) translate([outer_radius - chair_width,-outer_radius,0]) rotate(120,[0,0,1]) partA();
// part B + mirror
translate([0, -chairwheeldistance - outer_radius , -outer_radius]) rotate(90,[0,1,0]) partB();
mirror([1,0,0]) translate([ -chair_width, -chairwheeldistance - outer_radius , -outer_radius]) rotate(90,[0,1,0]) partB();
// part C + mirror
translate([outer_radius , -chairwheeldistance - 80 , 0]) rotate(90,[0,0,1]) partC();
mirror([1,0,0]) translate([-chair_width + outer_radius , -chairwheeldistance - 80 , 0]) rotate(90,[0,0,1]) partC();
// part D + mirror
translate([outer_radius , -chair_length , 0]) rotate(90,[0,0,1]) partD();
mirror([1,0,0]) translate([-chair_width + outer_radius , -chair_length , 0]) rotate(90,[0,0,1]) partD();
// part E + mirror
translate([outer_radius , -chairwheeldistance , -chair_height - outer_radius]) rotate(90,[1,0,0]) partE();
mirror([1,0,0]) translate([ -chair_width + outer_radius , -chairwheeldistance , -chair_height - outer_radius]) rotate(90,[1,0,0]) partE();
// simulated frame
color(col_frame) wheelchair();
}
}
else if (part == "part_a"){ orient_A(); }
else if (part == "part_b"){ orient_B(); }
else if (part == "part_b2"){ orient_B2(); }
else if (part == "part_c"){ orient_C(); }
else if (part == "part_d"){ orient_D(); }
else if (part == "part_e"){ orient_E(); }
else if (part == "all_parts"){
union(){
// row 1
translate([0, 0,0]) orient_A();
translate([grid_dx, 0,0]) orient_A_m();
// row 2
translate([0, -grid_dy,0]) orient_B();
translate([grid_dx, -grid_dy,0]) orient_B2();
// row 3
translate([0, -2*grid_dy,0]) orient_C();
translate([grid_dx, -2*grid_dy,0]) orient_C_m();
// row 4
translate([0, -3*grid_dy,0]) orient_D();
translate([grid_dx, -3*grid_dy,0]) orient_D_m();
// row 5
translate([0, -4*grid_dy,0]) orient_E();
translate([grid_dx, -4*grid_dy,0]) orient_E_m();
}
}
}
Editor is loading...
Leave a Comment