Initial commit
This commit is contained in:
		
							
								
								
									
										425
									
								
								sumorobot-frame.scad
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										425
									
								
								sumorobot-frame.scad
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,425 @@ | ||||
| /* Error tolerance for cutouts */ | ||||
| T = 0.2; | ||||
|  | ||||
| /* Arc smoothness */ | ||||
| R = 100; | ||||
|  | ||||
| /* PCB dimensions */ | ||||
| PCB_WIDTH = 66.5; | ||||
| PCB_DEPTH = 66.5; | ||||
| PCB_THICKNESS = 1.6; | ||||
| PCB_OFFSET = 6; | ||||
|  | ||||
| /* Robot dimensions */ | ||||
| THICKNESS = 3; | ||||
| WIDTH = 100; | ||||
| HEIGHT = 90; | ||||
| DEPTH = 100; | ||||
| OFFSET = 34; | ||||
| TILT = -8; | ||||
|  | ||||
| /* Ultrasonic sensor parameters */ | ||||
| ULTRASONIC_SENSOR_PLACEMENT = 47; | ||||
| ULTRASONIC_SENSOR_SPAN = 26.5; | ||||
| ULTRASONIC_SENSOR_HOLE = 16; | ||||
|  | ||||
| /* Line sensor parameters */ | ||||
| LINE_SENSOR_PLACEMENT = 13.5; | ||||
| LINE_SENSOR_HOLES = 3; | ||||
| LINE_SENSOR_SPAN = 38; | ||||
|  | ||||
| /* How far from eachother servo mount surfaces are placed */ | ||||
| SERVO_AXLE_LENGTH = 58; | ||||
|  | ||||
| COVER_WIDTH = 70; | ||||
| COVER_HEIGHT = 76; | ||||
|  | ||||
| /* Servo parameters */ | ||||
| SERVO_MOUNT_PLACEMENT = 65; | ||||
| SERVO_MOUNT_OFFSET = 33.5; | ||||
|  | ||||
| /* Magnet parameters */ | ||||
| MAGNET_HEIGHT = 0.8; | ||||
| MAGNET_DIAMETER = 5; | ||||
|  | ||||
| /* Show placeholders for battery, wheels, PCB, etc */ | ||||
| DEBUG = false; | ||||
|  | ||||
| /* Helper function for mirror-copying object */ | ||||
| module mirror_copy() { | ||||
|     children(); | ||||
|     mirror() { | ||||
|         children(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /* Mount holes for servos */ | ||||
| module mount_hole() { | ||||
|     cylinder(h = 100, d = LINE_SENSOR_HOLES + T, $fn = R); | ||||
| } | ||||
|  | ||||
| /* Standard servo cutout helper */ | ||||
| module servo_cutout() { | ||||
|     translate([-34.5, 5, 0]) mount_hole(); | ||||
|     translate([-34.5, -5, 0]) mount_hole(); | ||||
|     translate([15, 5, 0]) mount_hole(); | ||||
|     translate([15, -5, 0]) mount_hole(); | ||||
|     translate([-31, -10, 0]) cube([40 + T * 2 + 2, 20 + T * 2, 100]); | ||||
| } | ||||
|  | ||||
| module face() { | ||||
|     difference() { | ||||
|         union() { | ||||
|             /* Front face */ | ||||
|             cube([WIDTH / 2, HEIGHT * 2, THICKNESS]); | ||||
|  | ||||
|             /* Ultrasonic sensor mount */ | ||||
|             rotate([TILT, 0, 0]) { | ||||
|                 translate([ULTRASONIC_SENSOR_SPAN / 2, ULTRASONIC_SENSOR_PLACEMENT, 0]) { | ||||
|                     cylinder(h = 20, d = ULTRASONIC_SENSOR_HOLE + THICKNESS, $fn = R); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /* Line following sensor mounting holes */ | ||||
|         translate([0, LINE_SENSOR_PLACEMENT, -T]) { | ||||
|             translate([LINE_SENSOR_SPAN, 0, 0]) { | ||||
|                 cylinder(h = THICKNESS + T * 2, d2 = LINE_SENSOR_HOLES + T, d1 = LINE_SENSOR_HOLES * 2 + T, $fn = R); | ||||
|             } | ||||
|             cylinder(h = THICKNESS + T * 2, d2 = LINE_SENSOR_HOLES + T, d1 = LINE_SENSOR_HOLES * 2 + T, $fn = R); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         /* Ultrasonic sensor cutout */ | ||||
|         rotate([TILT, 0, 0]) { | ||||
|             translate([0, ULTRASONIC_SENSOR_PLACEMENT, 0]) { | ||||
|                 translate([ULTRASONIC_SENSOR_SPAN / 2, 0, -1]) { | ||||
|                     cylinder(h = 100, d = ULTRASONIC_SENSOR_HOLE + T, $fn = R); | ||||
|                 } | ||||
|  | ||||
|                 translate([0, 0, 15]) { | ||||
|                     cube([ULTRASONIC_SENSOR_SPAN / 2, ULTRASONIC_SENSOR_SPAN / 2, 30]); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| module frame() { | ||||
|     /* Front face to top face support arcs */ | ||||
|     rotate([0, 90, 0]) { | ||||
|         translate([-90, 0, -WIDTH / 2]) { | ||||
|             difference() { | ||||
|                 cylinder(d = 300, h = T + WIDTH/2 - COVER_WIDTH/2, $fn = R); | ||||
|                 translate([0, 0, -THICKNESS]) | ||||
|                 cylinder(d = 176, h = WIDTH-COVER_WIDTH, $fn = R); | ||||
|  | ||||
|                 /* Clear out line sensor holes */ | ||||
|                 cube([200, 30, 20]); | ||||
|                 translate([-200, -200, -1]) { | ||||
|                     cube([200, 400, 20]); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     difference() { | ||||
|         translate([-COVER_WIDTH / 2, HEIGHT - OFFSET, 0]) { | ||||
|             /* PCB compartment walls */ | ||||
|             cube([THICKNESS, OFFSET, DEPTH]); | ||||
|  | ||||
|             /* PCB rails */ | ||||
|             translate([0, OFFSET - PCB_OFFSET - THICKNESS * 3, 0]) { | ||||
|                 cube([6, PCB_OFFSET + THICKNESS * 3, DEPTH]); | ||||
|  | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /* PCB cutout */ | ||||
|         translate([-PCB_WIDTH / 2, HEIGHT - 9, DEPTH - PCB_DEPTH - THICKNESS + T]) { | ||||
|             cube([PCB_WIDTH + T, PCB_THICKNESS + T, PCB_DEPTH]); | ||||
|             translate([0, -PCB_THICKNESS, -2]) { | ||||
|                 cube([PCB_WIDTH + T, PCB_THICKNESS + T, PCB_DEPTH]); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /* Servo mounting walls */ | ||||
|     translate([-SERVO_AXLE_LENGTH / 2, 0, 0]) { | ||||
|         cube([THICKNESS, HEIGHT - OFFSET, DEPTH]); | ||||
|     } | ||||
|  | ||||
|     rotate([90, 0, 0]) { | ||||
|         /* Bottom face */ | ||||
|         translate([0, 0, -HEIGHT + COVER_HEIGHT]) { | ||||
|             cube([SERVO_AXLE_LENGTH / 2, DEPTH, THICKNESS]); | ||||
|         } | ||||
|  | ||||
|         /* Bottom support columnns */ | ||||
|         translate([SERVO_AXLE_LENGTH / 2 - 12, 0, -HEIGHT + COVER_HEIGHT - 4]) { | ||||
|             cube([10, DEPTH, 18]); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         /* Battery compartment separator */ | ||||
|         translate([0, 0, -HEIGHT + OFFSET]) { | ||||
|             difference() { | ||||
|                 cube([COVER_WIDTH / 2, DEPTH, THICKNESS]); | ||||
|                 translate([0, 0, -T]) { | ||||
|                     cube([SERVO_AXLE_LENGTH / 2, 20, THICKNESS + T * 2]); | ||||
|                     translate([0, 20, 0]) { | ||||
|                         /* Arc to ease 3D printing */ | ||||
|                         cylinder(h = THICKNESS * 2, d = SERVO_AXLE_LENGTH - THICKNESS * 2, $fn = R); | ||||
|                         translate([0, 80, 0]) | ||||
|                         cylinder(h = THICKNESS * 2, d = SERVO_AXLE_LENGTH - THICKNESS * 2, $fn = R); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /* Top face */ | ||||
|     translate([0, HEIGHT - THICKNESS, 0]) { | ||||
|         cube([WIDTH / 2, THICKNESS, DEPTH]); | ||||
|  | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| module half() { | ||||
|     difference() { | ||||
|         union() { | ||||
|             face(); | ||||
|             difference() { | ||||
|                 rotate([TILT, 0, 0]) { | ||||
|                     frame(); | ||||
|                 } | ||||
|  | ||||
|                 /* Line following sensor wires */ | ||||
|                 translate([0, 32, THICKNESS]) { | ||||
|                     rotate([0, -90, 0]) { | ||||
|                         cylinder(d = 26, h = 30, $fn = R); | ||||
|                     } | ||||
|                     rotate([90, 0, 0]) { | ||||
|                         cylinder(d = 26, h = 100, $fn = R); | ||||
|                     } | ||||
|  | ||||
|                 } | ||||
|  | ||||
|                 rotate([TILT]) { | ||||
|                     rotate([0, -90, 0]) { | ||||
|                         /* Bottom arc */ | ||||
|                         translate([50, -86, -50]) { | ||||
|                             cylinder(d = 195, h = 100, $fn = R); | ||||
|                         } | ||||
|  | ||||
|                         /* Servo mount */ | ||||
|                         translate([SERVO_MOUNT_PLACEMENT, SERVO_MOUNT_OFFSET, 0]) { | ||||
|                             servo_cutout(); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /* Front face cutoff */ | ||||
|         translate([-100, -100, -100]) { | ||||
|             cube([200, 300, 100]); | ||||
|         } | ||||
|  | ||||
|         /* Bottom face cutoff */ | ||||
|         translate([-100, -100, -100]) { | ||||
|             cube([300, 100, 300]); | ||||
|         } | ||||
|  | ||||
|         /* Top face cutoff */ | ||||
|         rotate([TILT, 0, 0]) { | ||||
|             translate([-100, HEIGHT, -100]) { | ||||
|                 cube([200, 200, 200]); | ||||
|             } | ||||
|  | ||||
|             translate([-COVER_WIDTH / 2 - T, HEIGHT - COVER_HEIGHT - THICKNESS, DEPTH - THICKNESS]) { | ||||
|                 cube([COVER_WIDTH + T, 200, 200]); | ||||
|             } | ||||
|  | ||||
|  | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| module magnet_hole() { | ||||
|     cylinder(d = MAGNET_DIAMETER + T, h = MAGNET_HEIGHT + T, $fn = R); | ||||
| } | ||||
|  | ||||
| module magnet_holes() { | ||||
|     mirror_copy() { | ||||
|         /* Top holes */ | ||||
|         translate([+COVER_WIDTH / 2 - MAGNET_DIAMETER / 2 - 0.5, HEIGHT - 3, -MAGNET_HEIGHT]) { | ||||
|             magnet_hole(); | ||||
|         } | ||||
|         /* Bottom holes */ | ||||
|         translate([SERVO_AXLE_LENGTH / 2 - MAGNET_DIAMETER / 2 - 0.5, HEIGHT - COVER_HEIGHT + MAGNET_DIAMETER / 2 - THICKNESS + 0.5, -MAGNET_HEIGHT]) { | ||||
|             magnet_hole(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| module sumorobot() { | ||||
|     difference() { | ||||
|         mirror_copy() { | ||||
|             half(); | ||||
|         } | ||||
|         rotate([TILT, 0, 0]) { | ||||
|             translate([0, 0, DEPTH - THICKNESS]) { | ||||
|                 magnet_holes(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| module cover() { | ||||
|     translate([0, 100, 0]) { | ||||
|         difference() { | ||||
|           union() { | ||||
|             translate([-27, COVER_HEIGHT-20, 0]) | ||||
|             cube([35,12,THICKNESS*2]); | ||||
|  | ||||
|             mirror_copy() { | ||||
|                 // Battery/servo compartment cover | ||||
|                 translate([0, 0, 0]) { | ||||
|                     cube([SERVO_AXLE_LENGTH / 2, COVER_HEIGHT, THICKNESS]); | ||||
|                 } | ||||
|  | ||||
|                 // PCB compartment cover | ||||
|                 translate([0, COVER_HEIGHT - OFFSET, 0]) { | ||||
|                     cube([COVER_WIDTH / 2, OFFSET + THICKNESS, THICKNESS]); | ||||
|                 } | ||||
|  | ||||
|                 // PCB locking mechanism | ||||
|                 translate([PCB_WIDTH/2-T-6, COVER_HEIGHT-6, 0]) { | ||||
|                     cube([6, PCB_THICKNESS-T, THICKNESS+3*PCB_THICKNESS]); | ||||
|  | ||||
|                     cube([PCB_THICKNESS, 5, THICKNESS+3*PCB_THICKNESS]); | ||||
|                 } | ||||
|             } | ||||
|           } | ||||
|             translate([0, COVER_HEIGHT - HEIGHT + THICKNESS, THICKNESS]) { | ||||
|                 magnet_holes(); | ||||
|             } | ||||
|             translate([-COVER_WIDTH/2+THICKNESS-0.5, COVER_HEIGHT+THICKNESS-0.5-PCB_THICKNESS, -T]) { | ||||
|                 translate([10.7, -13.1, 0]) { | ||||
|                    cylinder(d2=5, d1=5+THICKNESS, h=THICKNESS+T*2, $fn=R); | ||||
|                    cylinder(d=5, h=10, $fn=R); | ||||
|  | ||||
|                 } | ||||
|                 translate([36.2, -13.1, 0]) cylinder(d=5, h=THICKNESS*3+T*2, $fn=R); | ||||
|                 translate([17.8-T*2, -19.46, 0]) cube([12.1+T*4, 10.5+T*4, 20]); | ||||
|             } | ||||
|  | ||||
|  | ||||
|  | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| module plow_hole() { | ||||
|     translate([0, 0, -T]) | ||||
|     cylinder(d1=LINE_SENSOR_HOLES+T, d2=LINE_SENSOR_HOLES*3, h=THICKNESS+T+T, $fn=R); | ||||
|     translate([0, 0, THICKNESS]) { | ||||
|         cylinder(d=LINE_SENSOR_HOLES*3, h=WIDTH, $fn=R); | ||||
|     } | ||||
| } | ||||
|  | ||||
| module plow() { | ||||
|     translate([0, -40, 0]) { | ||||
|         mirror_copy() { | ||||
|             difference() { | ||||
|                 rotate([TILT, 0, 0]) { | ||||
|                     cube([WIDTH/2, LINE_SENSOR_PLACEMENT*2-6, 50]); | ||||
|                 } | ||||
|  | ||||
|                 rotate([-TILT, 0, 0]) | ||||
|                 translate([-T, LINE_SENSOR_PLACEMENT*2-6, -6]) | ||||
|                 cube([100, 100, 100]); | ||||
|                 translate([-T, 0, -100]) { | ||||
|                     cube([100, 100, 100]); | ||||
|                 } | ||||
|  | ||||
|                 translate([0, LINE_SENSOR_PLACEMENT-3]) { | ||||
|                     translate([LINE_SENSOR_SPAN, 0]) { | ||||
|                         plow_hole(); | ||||
|                     } | ||||
|                     plow_hole(); | ||||
|                 } | ||||
|                 translate([0, -1, 50]) { | ||||
|                     rotate([-90, 0, 0]) { | ||||
|                         cylinder(d=WIDTH-10, h=50, $fn=R); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| sumorobot(); | ||||
| cover(); | ||||
| plow(); | ||||
|  | ||||
| if (DEBUG) { | ||||
|     color([1, 0, 0]) { | ||||
|         rotate([TILT, 0, 0]) { | ||||
|             rotate([90, 0, 0]) { | ||||
|                 /* PCB board mockup */ | ||||
|                 translate([0, 0, -HEIGHT + PCB_OFFSET + T]) { | ||||
|                     translate([-PCB_WIDTH / 2, DEPTH - PCB_DEPTH, 0]) { | ||||
|                         cube([PCB_WIDTH, PCB_DEPTH + 5, 1.6]); | ||||
|                     } | ||||
|  | ||||
|                     translate([-PCB_WIDTH / 2 + 5, DEPTH - PCB_DEPTH, 0]) { | ||||
|                         cube([PCB_WIDTH - 10, PCB_DEPTH - 5, 20]); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 /* Battery mockup */ | ||||
|                 translate([-25, 30, -24]) { | ||||
|                     translate([0, 0, 0]) { | ||||
|                         cube([50, 60, 5.5]); | ||||
|                     } | ||||
|                     translate([10, 0, 0]) { | ||||
|                         cube([30, 50, 10]); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         translate([WIDTH / 2 + 28 / 2, HEIGHT - 47, 0]) { | ||||
|             cylinder(h = 12, d = 15, $fn = R); | ||||
|         } | ||||
|  | ||||
|         /* Wheel mockups */ | ||||
|         rotate([TILT]) { | ||||
|             rotate([0, -90, 0]) { | ||||
|                 translate([SERVO_MOUNT_PLACEMENT, SERVO_MOUNT_OFFSET, SERVO_AXLE_LENGTH/2 + 10]) { | ||||
|                     difference() { | ||||
|                         cylinder(d=70, h=11); | ||||
|                         cylinder(d=3, h=12); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /* Line sensor mockups */ | ||||
|         difference() { | ||||
|             translate([0, LINE_SENSOR_PLACEMENT - 5.2, THICKNESS]) { | ||||
|                 translate([WIDTH / 2 - (+12 + 8.9), 0, 0]) cube([17.8, 15.2, 5.2]); | ||||
|                 translate([-8.9, 0, 0]) cube([17.8, 15.2, 5.2]); | ||||
|                 translate([-WIDTH / 2 + 12 - 8.9, 0, 0]) cube([17.8, 15.2, 5.2]); | ||||
|             } | ||||
|             cylinder(d = 3, h = 20, $fn = R); | ||||
|             translate([38, 0, 0]) cylinder(d = 3, h = 20, $fn = R); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										179
									
								
								sumorobot-remote.scad
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								sumorobot-remote.scad
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,179 @@ | ||||
| WIDTH = 114; | ||||
| HEIGHT = 63; | ||||
| DEPTH = 30; | ||||
|  | ||||
| R = 30; | ||||
| THICKNESS = 2; | ||||
|  | ||||
| BORDER_RADIUS = 4; | ||||
| JOYSTICK_AXIS_DIAMETER = 31; | ||||
| JOYSTICK_TO_BUTTONS = 45.72; | ||||
| BUTTON_DIAMETER = 11.5; | ||||
| T = 0.2; | ||||
| BUTTON_PLACEMENT_DIAMETER = 22.86; | ||||
| BUTTON_PLACEMENT_LEFT = WIDTH / 2 - JOYSTICK_TO_BUTTONS / 2; | ||||
| JOYSTICK_LEFT = WIDTH / 2 + JOYSTICK_TO_BUTTONS / 2; | ||||
| JOYSTICK_TOP = HEIGHT / 2; | ||||
| BUTTON_SINK = 13.5; | ||||
|  | ||||
| TRAY_WIDTH = 35; | ||||
| TRAY_HEIGHT = 52; | ||||
| TRAY_DEPTH = 6; | ||||
| TRAY_THICKNESS = 1; | ||||
|  | ||||
|  | ||||
| SWITCH_POSITION = WIDTH - 27; | ||||
| SWITCH_HEIGHT = 12.7; | ||||
| SWITCH_WIDTH = 19.3; | ||||
|  | ||||
| SCREW_HOLE = 6.3; | ||||
|  | ||||
| STANDOFF_H = 20; | ||||
| STANDOFF_D2 = 4.65; | ||||
| STANDOFF_D = STANDOFF_D2 / 0.866; | ||||
|  | ||||
| module box(width, height, depth, h1 = STANDOFF_D, h2 = STANDOFF_D, hd = STANDOFF_H, hr=6) { | ||||
|     difference() { | ||||
|         translate([0, 0, -THICKNESS]) { | ||||
|             // Bottom | ||||
|             translate([-BORDER_RADIUS, 0, 0]) cube([width + BORDER_RADIUS * 2, HEIGHT, THICKNESS]); | ||||
|             translate([0, -BORDER_RADIUS, 0]) cube([width, height + BORDER_RADIUS * 2, THICKNESS]); | ||||
|  | ||||
|             // Walls | ||||
|             translate([0, -BORDER_RADIUS, 0]) cube([width, THICKNESS, depth + THICKNESS]); | ||||
|             translate([-BORDER_RADIUS, 0, 0]) cube([THICKNESS, height, depth + THICKNESS]); | ||||
|             translate([0, height + BORDER_RADIUS - THICKNESS, 0]) cube([width, THICKNESS, depth + THICKNESS]); | ||||
|             translate([width + BORDER_RADIUS - THICKNESS, 0, 0]) cube([THICKNESS, height, depth + THICKNESS]); | ||||
|  | ||||
|  | ||||
|             // Screw hole cylinders | ||||
|             cylinder(r = BORDER_RADIUS, h = depth + THICKNESS, $fn = R); | ||||
|             translate([WIDTH, 0, 0]) cylinder(r = BORDER_RADIUS, h = depth + THICKNESS, $fn = R); | ||||
|             translate([0, HEIGHT, 0]) cylinder(r = BORDER_RADIUS, h = depth + THICKNESS, $fn = R); | ||||
|             translate([WIDTH, HEIGHT, 0]) cylinder(r = BORDER_RADIUS, h = depth + THICKNESS, $fn = R); | ||||
|         } | ||||
|  | ||||
|         // Screw hole | ||||
|         translate([0, 0, depth - hd - T]) { | ||||
|             cylinder(d1 = h1+T, d2 = h2+T, h = hd+T+T, $fn = hr); | ||||
|             translate([WIDTH, 0, 0]) cylinder(d1 = h1+T, d2 = h2+T, h = hd+T+T, $fn = hr); | ||||
|             translate([0, HEIGHT, 0]) cylinder(d1 = h1+T, d2 = h2+T, h = hd+T+T, $fn = hr); | ||||
|             translate([WIDTH, HEIGHT, 0]) cylinder(d1 = h1+T, d2 = h2+T, h = hd+T+T, $fn = hr); | ||||
|  | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Cover | ||||
| translate([0, -THICKNESS - BORDER_RADIUS * 2, 0]) { | ||||
|     mirror([0, 1, 0]) { | ||||
|         difference() { | ||||
|           box(WIDTH, HEIGHT, 0, h1 = 5.4, h2 = 2.8, hr=R, hd = THICKNESS); | ||||
|           translate([WIDTH/2-5, -BORDER_RADIUS+THICKNESS+T+1, -THICKNESS-T]) | ||||
|           cube([10, 4, 10]); | ||||
|         } | ||||
|  | ||||
|         // Switch fixer | ||||
|         translate([SWITCH_POSITION + T, -BORDER_RADIUS, 0]) { | ||||
|             cube([SWITCH_WIDTH - T - T, BORDER_RADIUS, DEPTH - SWITCH_HEIGHT - T]); | ||||
|         } | ||||
|  | ||||
|         // Charger mount | ||||
|         translate([WIDTH/2-19/2-3, -BORDER_RADIUS+THICKNESS+T, 0]) { | ||||
|             difference() { | ||||
|               cube([19+3+3, 7, DEPTH - SWITCH_HEIGHT - T]); | ||||
|               translate([+3, 0, 0]) | ||||
|               cube([19, 3, 20]); | ||||
|  | ||||
|               translate([7.5, 0, 0]) | ||||
|               cube([10, 5, 20]); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| module screw_hole(dia=SCREW_HOLE) { | ||||
|     difference() { | ||||
|         cylinder(h = 11, d = 8, $fn = R); | ||||
|         translate([0, 0, TRAY_DEPTH]) | ||||
|         cylinder(h = TRAY_DEPTH + T, d = dia, $fn = R); | ||||
|  | ||||
|     } | ||||
| } | ||||
|  | ||||
| module button() { | ||||
|     cylinder(d1 = BUTTON_DIAMETER + THICKNESS * 2 + T, d2 = BUTTON_DIAMETER + T, h = THICKNESS + T * 2, $fn = R); | ||||
| } | ||||
|  | ||||
| module case () { | ||||
|     difference() { | ||||
|         union() { | ||||
|             box(WIDTH, HEIGHT, DEPTH); | ||||
|  | ||||
|  | ||||
|             // Switch holder | ||||
|             translate([SWITCH_POSITION - 5, -BORDER_RADIUS + T + T, 0]) { | ||||
|                 cube([SWITCH_WIDTH + 10, BORDER_RADIUS, DEPTH]); | ||||
|                 translate([-85+6, 0,0 ]) | ||||
|                 cube([85, 5,3.5]); | ||||
|             } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|         } | ||||
|  | ||||
|         // Switch cutout | ||||
|         translate([SWITCH_POSITION, -BORDER_RADIUS - T, 0]) { | ||||
|             cube([SWITCH_WIDTH, THICKNESS, HEIGHT]); | ||||
|             translate([-1, THICKNESS, 0]) | ||||
|             cube([SWITCH_WIDTH + 2, BORDER_RADIUS, HEIGHT]); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         union() { | ||||
|  | ||||
|             translate([JOYSTICK_LEFT, JOYSTICK_TOP, 5]) { | ||||
|                 sphere(JOYSTICK_AXIS_DIAMETER / 2); | ||||
|             } | ||||
|  | ||||
|             translate([BUTTON_PLACEMENT_LEFT, JOYSTICK_TOP, -THICKNESS]) { | ||||
|                 translate([BUTTON_PLACEMENT_DIAMETER / 2, 0, -T]) button(); | ||||
|                 translate([0, BUTTON_PLACEMENT_DIAMETER / 2, -T]) button(); | ||||
|                 translate([-BUTTON_PLACEMENT_DIAMETER / 2, 0, -T]) button(); | ||||
|                 translate([0, -BUTTON_PLACEMENT_DIAMETER / 2, -T]) button(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /* PCB mounting holes */ | ||||
|     translate([BUTTON_PLACEMENT_LEFT, JOYSTICK_TOP, 0]) { | ||||
|         translate([-18.9, BUTTON_PLACEMENT_DIAMETER / 2, 0]) { | ||||
|             screw_hole(1.9); | ||||
|             translate([0, -28, 0]) { | ||||
|                 screw_hole(1.9); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|     translate([BUTTON_PLACEMENT_LEFT + JOYSTICK_TO_BUTTONS, JOYSTICK_TOP, 0]) { | ||||
|  | ||||
|         translate([+12.2 + 1.5, +24.7 + 1.5, 0]) { | ||||
|             screw_hole(1.9); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| case (); | ||||
		Reference in New Issue
	
	Block a user