Initial commit
This commit is contained in:
commit
6cc0cc496c
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 ();
|
Loading…
Reference in New Issue
Block a user