Skip to content

Instantly share code, notes, and snippets.

@SharpCoder
Last active August 29, 2023 00:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SharpCoder/526fa78096ba074c531464f683197736 to your computer and use it in GitHub Desktop.
Save SharpCoder/526fa78096ba074c531464f683197736 to your computer and use it in GitHub Desktop.
A 2D (XY) robotic platform

A 2D (XY) Robotic Platform

Here are the files for my 2d robotic platform. Each file is meant to be fabricated on a 3d printer (except the assembly.scad file, which is really just a visualization for the final build).

include <common.scad>
include <x-base.scad>
include <y-base.scad>
include <spoke.scad>
include <nema17-bracket.scad>
include <circuit-bracket.scad>
SHOW=false;
SHOW_SPOKE=false;
SHOW_BRACKET=false;
x_assembly();
stepper_area()
stepper();
translate([0, 0, STEPPER_DEPTH])
stepper_area()
stepper_bracket();
translate([0, 0, z])
circuit_area()
circuit();
stepper_area()
rotate(-45)
translate([0,0,SERVO_DEPTH])
union() {
translate([0, 0, HUB_DEPTH/1.25])
rotate([0, 180, 0])
spoke_assembly();
translate([SPOKE_WHEEL_SIZE/2, 0, HUB_DEPTH/1.25])
y_assembly();
union() {
rotate([0, 0, 90])
translate([0,-2,SERVO_DEPTH+ABOVE])
rotate([90, 90, 0])
union() {
stepper();
rotate([0, 180, 0])
translate([0, 0, -SERVO_DEPTH - HUB_DEPTH/1.25])
spoke_assembly();
translate([0, 0, SERVO_DEPTH + HUB_DEPTH/1.25])
rotate(180+45)
union() {
circuit_bracket_assembly();
translate([0, -3, 25])
rotate([90,0,0])
prototype();
}
}
}
}
$fn = 200;
tol = 0.3;
MATERIAL_COLOR = "#EAEAEA";
BRACKET_COLOR = "#444";
STEPPER_W_H = 42.3 + tol;
STEPPER_DEPTH = 32.6 + tol;
STEPPER_SHAFT_DIA = 5.0 + tol;
STEPPER_BLADE_DEPTH = 24 + tol;
STEPPER_CABLE_WIDTH = 12.0;
STEPPER_MOUNT_PADDING = 10;
STEPPER_MOUNT_W = 10;
STEPPER_MOUNT_H = STEPPER_W_H+STEPPER_MOUNT_PADDING;
STEPPER_MOUNT_TOL = 1.3;
SERVO_WIDTH = 20.5;
SERVO_HEIGHT = 42;
SERVO_DEPTH = 41;
M3_BORE= 3.0 + tol; // The M3 bore
M3_HEX_BORE = 7.45 + tol; // The hex nut dia
M3_HEX_DEPTH = 3.3 + tol; // The depth of the nut
M4_BORE = 4.0 + tol;
M4_HEX_BORE = 7.7 + tol;
M4_HEX_DEPTH = 3.0 + tol;
M5_SET_SCREW_DIA = 4.8 + tol;
M6_SET_SCREW_DIA = 5.8 + tol;
SERVO_MOUNT_SPACING_X = 10;
SERVO_MOUNT_SPACING_Y = 49;
SERVO_TOTAL_WIDTH = 54;
SPOKE_MOUNT_LENGTH = 25;
SPOKE_WHEEL_SIZE = 45 + SPOKE_MOUNT_LENGTH;
// Mounting blade details
SERVO_BLADE_DEPTH = 4;
SERVO_BLADE_WIDTH = 7;
SERVO_BLADE_LENGTH = SERVO_TOTAL_WIDTH + 4;
module radial_copy(qty) {
for (i = [0:qty]) {
rotate((360 / qty) * i)
children();
}
}
module copy(mirror_params) {
children();
mirror(mirror_params)
children();
}
module stepper() {
color("#222")
linear_extrude(STEPPER_DEPTH)
square([STEPPER_W_H,STEPPER_W_H], center=true);
color("silver")
translate([0,0,STEPPER_DEPTH])
linear_extrude(STEPPER_BLADE_DEPTH)
circle(d=STEPPER_SHAFT_DIA);
color("#666")
rotate(180)
translate([STEPPER_W_H/2+1.5, 0, 0])
linear_extrude(9.4)
square([3,STEPPER_CABLE_WIDTH], center=true);
}
module m4_captive_nut() {
color("red")
linear_extrude(M4_HEX_DEPTH)
union() {
circle(d=M4_HEX_BORE, $fn=6);
translate([M4_HEX_BORE/2, 0, 0])
square([M4_HEX_BORE, M4_HEX_BORE], center=true);
}
}
module servo() {
color("#444")
translate([0, 0, 28])
linear_extrude(4)
difference() {
square([SERVO_WIDTH, SERVO_TOTAL_WIDTH], center=true);
copy([0,1,0])
union() {
translate([SERVO_MOUNT_SPACING_X/2,SERVO_MOUNT_SPACING_Y/2,0])
circle(d=M3_BORE);
translate([-SERVO_MOUNT_SPACING_X/2,SERVO_MOUNT_SPACING_Y/2,0])
circle(d=M3_BORE);
}
}
color("#222")
linear_extrude(SERVO_DEPTH)
square([SERVO_WIDTH, SERVO_HEIGHT], center=true);
translate([0,0,SERVO_DEPTH])
rotate(45)
servo_blade();
}
module servo_blade(px=4) {
p1 = 12;
p2 = 16;
p3 = 20;
bore = M3_BORE;
color("red")
linear_extrude(SERVO_BLADE_DEPTH)
difference() {
square([SERVO_BLADE_LENGTH, SERVO_BLADE_WIDTH], center=true);
copy([1,0,0])
translate([-p1,0,0])
circle(d=bore);
copy([1,0,0])
translate([-p3,0,0])
circle(d=bore);
}
}
module spoke_mount_area() {
copy([1,1,0])
copy([1,0,0])
translate([-SPOKE_MOUNT_LENGTH, 0, 0])
children();
}
module spoke_mount_holes() {
spoke_mount_area()
circle(d=M4_BORE);
}
module circuit_mount(dia=M4_BORE) {
w = 61.97;
h = 34.54;
translate([-w/2, -h/2, 0])
circle(d=dia);
translate([-w/2, h/2, 0])
circle(d=dia);
translate([w/2, -h/2, 0])
circle(d=dia);
translate([w/2, h/2, 0])
circle(d=dia);
}
module circuit() {
z = 2;
color("#800080")
linear_extrude(z)
difference() {
square([73.0, 45.0], center=true);
circuit_mount();
}
}
module prototype() {
w = 50.929;
h = 21.082;
color("#008C4A")
linear_extrude(2)
difference() {
square([w, h], center=true);
translate([w/2-6,0,0])
circle(d=M4_BORE);
}
}
module breadboard() {
w = 56.3;
h = 84.5;
d = 10;
color("#008C4A")
linear_extrude(d)
square([w,h], center=true);
}
include <common.scad>
SHOW_BRACKET=true;
channel = STEPPER_CABLE_WIDTH * 1.5;
module nema17_bracket() {
color(MATERIAL_COLOR)
difference() {
square([
STEPPER_W_H + STEPPER_MOUNT_TOL,
STEPPER_W_H + STEPPER_MOUNT_TOL
], center=true);
// Main hole
circle(d=30);
// NEMA17 Holes
copy([0,1,0])
copy([1,0,0])
translate([31/2, 31/2, 0])
circle(d=M3_BORE);
}
}
module stepper_bracket() {
color(BRACKET_COLOR)
linear_extrude(3)
difference() {
translate([STEPPER_MOUNT_W/2, 0, 0])
square([
STEPPER_W_H + STEPPER_MOUNT_TOL + STEPPER_MOUNT_W + STEPPER_MOUNT_PADDING,
STEPPER_W_H + STEPPER_MOUNT_PADDING
], center=true);
// Main hole
circle(d=30);
// NEMA17 Holes
copy([0,1,0])
copy([1,0,0])
translate([31/2, 31/2, 0])
circle(d=M3_BORE);
translate([(STEPPER_W_H/2)+STEPPER_MOUNT_PADDING, 0, 0])
copy([0,1,0])
translate([0, STEPPER_MOUNT_H/4, 0])
circle(d=M4_BORE);
}
}
if (SHOW_BRACKET) {
stepper_bracket();
}
include <common.scad>
SHOW_SPOKE=true;
SET_SCREW_LENGTH = 6 + tol;
DEPTH = M4_HEX_DEPTH * 1.5;
HUB_DEPTH = DEPTH + 15;
WHEEL_PADDING = 10;
SPOKE_THICKNESS = M4_BORE + 6;
SPOKE_LENGTH = SPOKE_WHEEL_SIZE -WHEEL_PADDING;
module set_screw() {
translate([-10, 0, HUB_DEPTH / 1.5])
rotate([0, 90, 0])
color("red")
linear_extrude(20)
circle(d=M5_SET_SCREW_DIA);
}
module spoke_holes() {
copy([1,0,0])
translate([(SPOKE_LENGTH - M4_BORE - 4)/2, 0, 0])
circle(d=M4_BORE);
}
module spoke() {
color(BRACKET_COLOR)
linear_extrude(DEPTH)
difference() {
radial_copy(4)
translate([-SPOKE_THICKNESS/2, 0, 0])
square([SPOKE_THICKNESS, SPOKE_LENGTH/2]);
spoke_mount_holes();
}
}
module spoke_hex_nuts() {
translate([0, 0, DEPTH - M4_HEX_DEPTH])
linear_extrude(DEPTH)
difference() {
spoke_mount_area()
circle(d=M4_HEX_BORE, $fn=6);
}
}
module wheel() {
difference() {
color(BRACKET_COLOR)
linear_extrude(DEPTH)
union() {
// Create the shell
difference() {
circle(d=SPOKE_WHEEL_SIZE );
circle(d=SPOKE_WHEEL_SIZE -WHEEL_PADDING);
}
}
}
}
module hub() {
// Create the central hub
difference() {
color(BRACKET_COLOR)
linear_extrude(HUB_DEPTH)
difference() {
circle(d=STEPPER_SHAFT_DIA+SET_SCREW_LENGTH);
circle(d=STEPPER_SHAFT_DIA);
}
set_screw();
}
}
module spoke_assembly() {
union() {
wheel();
difference() {
spoke();
spoke_hex_nuts();
}
hub();
}
}
if (SHOW_SPOKE) {
spoke_assembly();
}
include <common.scad>
SHOW = true;
FANCY = false;
h = 140;
z = 5;
module circuit_area() {
translate([0, -h/3+5, 0])
children();
}
module stepper_area() {
translate([0,20,z])
children();
}
module base() {
difference() {
linear_extrude(z)
difference() {
minkowski(){
border_radius = 20;
square([h-border_radius,h-border_radius], center=true);
circle(d=border_radius);
}
stepper_area()
square([STEPPER_W_H/1.25, STEPPER_W_H/1.25], center=true);
circuit_area()
union() {
circuit_mount();
square([20, 20], center=true);
}
}
linear_extrude(M4_HEX_DEPTH)
circuit_area()
circuit_mount(dia=M4_HEX_BORE, $fn=6);
}
}
module stepper_mount() {
channel = STEPPER_CABLE_WIDTH * 1.5;
linear_extrude(STEPPER_DEPTH)
difference() {
square([
STEPPER_W_H + STEPPER_MOUNT_PADDING,
STEPPER_W_H + STEPPER_MOUNT_PADDING
], center=true);
square([STEPPER_W_H + STEPPER_MOUNT_TOL, STEPPER_W_H+STEPPER_MOUNT_TOL], center=true);
square([channel, STEPPER_W_H*2], center=true);
translate([-STEPPER_W_H/2, 0, 0])
rotate(90)
square([channel, STEPPER_W_H*2], center=true);
}
}
module stepper_bracket_mount() {
difference() {
translate([(STEPPER_W_H/2)+STEPPER_MOUNT_PADDING, 0, 0])
linear_extrude(STEPPER_DEPTH)
difference() {
square([STEPPER_MOUNT_W,STEPPER_MOUNT_H], center=true);
copy([0,1,0])
translate([0, STEPPER_MOUNT_H/4, 0])
circle(d=M4_BORE);
}
copy([0,1,0])
translate([(STEPPER_W_H/2)+STEPPER_MOUNT_PADDING, 0, STEPPER_DEPTH-M4_HEX_DEPTH-4])
translate([0, STEPPER_MOUNT_H/4, 0])
m4_captive_nut();
}
}
module x_assembly() {
color(MATERIAL_COLOR)
union() {
base();
stepper_area()
union() {
stepper_mount();
stepper_bracket_mount();
}
}
}
if (SHOW) {
x_assembly();
if (FANCY) {
stepper_area()
stepper();
translate([0, 0, z])
circuit_area()
circuit();
}
}
include <common.scad>
include <nema17-bracket.scad>
SHOW = true;
SHOW_BRACKET = false;
ABOVE = 2;
Y_SPOKE_THICKNESS = 4;
BRACKET_THICKNESS = 4;
module y_assembly() {
color(MATERIAL_COLOR)
union() {
// Nema bracket
translate([0, 0, Y_SPOKE_THICKNESS])
difference() {
union() {
translate([0, 0, ABOVE])
translate([-BRACKET_THICKNESS /2,0,(STEPPER_W_H+STEPPER_MOUNT_TOL)/2])
rotate([0, 90, 0])
union() {
linear_extrude(BRACKET_THICKNESS)
nema17_bracket();
translate([(STEPPER_W_H+STEPPER_MOUNT_TOL)/2, 0, 0])
linear_extrude(BRACKET_THICKNESS)
square([ABOVE+Y_SPOKE_THICKNESS, STEPPER_W_H+STEPPER_MOUNT_TOL], center=true);
}
difference() {
translate([-10+BRACKET_THICKNESS /2,0,-Y_SPOKE_THICKNESS ])
linear_extrude(Y_SPOKE_THICKNESS )
difference() {
square([20, STEPPER_W_H+STEPPER_MOUNT_TOL], center=true);
// This just reiterates the main hole
translate([-SPOKE_WHEEL_SIZE/2, 0, 0])
circle(d=SPOKE_WHEEL_SIZE);
}
}
}
}
// Spoke
translate([-SPOKE_WHEEL_SIZE/2, 0, 0])
linear_extrude(Y_SPOKE_THICKNESS)
difference() {
circle(d=SPOKE_WHEEL_SIZE);
circle(d=40);
spoke_mount_holes();
}
}
}
if (SHOW) {
y_assembly();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment