Skip to content

Instantly share code, notes, and snippets.

@graykevinb
Created July 14, 2025 22:21
Show Gist options
  • Select an option

  • Save graykevinb/6603679498bfc61b463d7c785ce02dd5 to your computer and use it in GitHub Desktop.

Select an option

Save graykevinb/6603679498bfc61b463d7c785ce02dd5 to your computer and use it in GitHub Desktop.
// Generated by Grok 4 and edited by graykevinb
// import rpi model
include <misc_boards.scad>;
// Small Robot Frame in OpenSCAD
// Designed for 4 motors with 1.5 inch diameter, Raspberry Pi 3B mount, camera mount, small LiPo battery holder
// Motor mounts are semi-circular cradles with top brackets for bolting
// Added rectangular holes in the base plate above each motor mount to allow motor insertion
// All parts are separate for 3D printing
$fn = 100; // Resolution for cylinders
// Variables
motor_dia = 38.1; // 1.5 inch
motor_rad = motor_dia / 2;
wall_thick = 2;
motor_mount_length = 30; // Length along motor body
base_length = 200; // Overall base length
base_width = 150; // Overall base width
base_thick = 3;
motor_offset = 20; // Offset from edges
// Raspberry Pi 3B dimensions
rpi_length = 85;
rpi_width = 56;
rpi_hole_dist_x = 58;
rpi_hole_dist_y = 49;
standoff_height = 10;
standoff_rad = 3;
// Camera mount (simple platform)
camera_mount_size = 30;
camera_hole_dist = 21; // Approximate for Pi camera
// Battery (small LiPo, e.g., 50x30x10mm)
battery_length = 50;
battery_width = 30;
battery_height = 10;
// Module for motor cradle (semi-circle bottom)
module motor_cradle() {
difference() {
// Outer cylinder
cylinder(h = motor_mount_length, r = motor_rad + wall_thick);
// Inner cylinder for motor
translate([0, 0, -0.1]) cylinder(h = motor_mount_length + 0.2, r = motor_rad);
// Cut top half to make semi-circle
translate([-(motor_rad + wall_thick + 1), 0, -0.1]) cube([2*(motor_rad + wall_thick + 1), motor_rad + wall_thick + 1, motor_mount_length + 0.2]);
}
// Add flanges for bolting
flange_width = 10;
flange_length = 10;
translate([motor_rad + wall_thick, -flange_width/2, 0]) cube([flange_length, flange_width, base_thick]);
translate([-(motor_rad + wall_thick + flange_length), -flange_width/2, 0]) cube([flange_length, flange_width, base_thick]);
// Bolt holes in flanges (M3 example)
translate([motor_rad + wall_thick + flange_length/2, flange_width/2 - 2, -0.1]) cylinder(h = base_thick + 0.2, r = 1.5);
translate([motor_rad + wall_thick + flange_length/2, -(flange_width/2 - 2), -0.1]) cylinder(h = base_thick + 0.2, r = 1.5);
translate([-(motor_rad + wall_thick + flange_length/2), flange_width/2 - 2, -0.1]) cylinder(h = base_thick + 0.2, r = 1.5);
translate([-(motor_rad + wall_thick + flange_length/2), -(flange_width/2 - 2), -0.1]) cylinder(h = base_thick + 0.2, r = 1.5);
}
// Module for motor top bracket (semi-circle cap)
module motor_cap() {
difference() {
// Outer cylinder
cylinder(h = motor_mount_length, r = motor_rad + wall_thick);
// Inner cylinder for motor
translate([0, 0, -0.1]) cylinder(h = motor_mount_length + 0.2, r = motor_rad);
// Cut bottom half to make semi-circle cap
translate([-(motor_rad + wall_thick + 1), -(motor_rad + wall_thick + 1), -0.1]) cube([2*(motor_rad + wall_thick + 1), motor_rad + wall_thick + 1, motor_mount_length + 0.2]);
}
// Add flanges for bolting
flange_width = 10;
flange_length = 10;
translate([motor_rad + wall_thick, -flange_width/2, 0]) cube([flange_length, flange_width, base_thick]);
translate([-(motor_rad + wall_thick + flange_length), -flange_width/2, 0]) cube([flange_length, flange_width, base_thick]);
// Bolt holes in flanges
translate([motor_rad + wall_thick + flange_length/2, flange_width/2 - 2, -0.1]) cylinder(h = base_thick + 0.2, r = 1.5);
translate([motor_rad + wall_thick + flange_length/2, -(flange_width/2 - 2), -0.1]) cylinder(h = base_thick + 0.2, r = 1.5);
translate([-(motor_rad + wall_thick + flange_length/2), flange_width/2 - 2, -0.1]) cylinder(h = base_thick + 0.2, r = 1.5);
translate([-(motor_rad + wall_thick + flange_length/2), -(flange_width/2 - 2), -0.1]) cylinder(h = base_thick + 0.2, r = 1.5);
}
// Module for standoff (for Raspberry Pi)
module standoff() {
difference() {
cylinder(h = standoff_height, r = standoff_rad);
translate([0, 0, -0.1]) cylinder(h = standoff_height + 0.2, r = 1.5); // M3 hole
}
}
// Module for simple camera mount
module camera_mount() {
camera_width = 25;
camera_height = 24;
mount_margin = 3;
mount_thick = 3;
hole_dist_x = 21;
hole_dist_y = 12.5;
hole_dia = 2;
difference() {
cube([camera_height + mount_margin * 2, camera_width + mount_margin * 2, mount_thick]);
// Mounting holes
translate([mount_margin + hole_dist_y/2, mount_margin + hole_dist_x/2, -0.1]) cylinder(h = mount_thick + 0.2, r = hole_dia/2);
translate([mount_margin + hole_dist_y/2, mount_margin - hole_dist_x/2, -0.1]) cylinder(h = mount_thick + 0.2, r = hole_dia/2);
translate([mount_margin - hole_dist_y/2, mount_margin + hole_dist_x/2, -0.1]) cylinder(h = mount_thick + 0.2, r = hole_dia/2);
translate([mount_margin - hole_dist_y/2, mount_margin - hole_dist_x/2, -0.1]) cylinder(h = mount_thick + 0.2, r = hole_dia/2);
// Aperture
translate([mount_margin + camera_height/2, mount_margin + camera_width/2, -0.1]) cylinder(h = mount_thick + 0.2, r = 5); // Simple lens hole
}
}
// Module for battery holder
module battery_holder() {
difference() {
cube([battery_length + wall_thick*2, battery_width + wall_thick*2, battery_height + wall_thick + 5]); // Extra height for lip
translate([wall_thick, wall_thick, wall_thick]) cube([battery_length, battery_width, battery_height + 6]);
}
}
// Base plate with integrated motor cradles and mounts, with holes for motor insertion
module base() {
union() {
difference() {
cube([base_length, base_width, base_thick]);
// Optional lightening holes or wire paths can be added here
// Motor insertion holes
// Front left
fl_y = motor_rad + wall_thick + 20 - motor_mount_length;
translate([motor_dia / 2, fl_y, -0.1]) cube([motor_mount_length, motor_dia, base_thick + 0.2]);
// Front right
fr_y = base_width - (motor_rad + wall_thick) - motor_mount_length;
translate([motor_dia / 2, fr_y, -0.1]) cube([motor_mount_length,motor_dia, base_thick + 0.2]);
// Rear left
rl_x = base_length - motor_offset - motor_mount_length + 20;
translate([rl_x - motor_dia / 2, fl_y, -0.1]) cube([motor_mount_length, motor_dia, base_thick + 0.2]);
// Rear right
translate([rl_x - motor_dia / 2, fr_y, -0.1]) cube([motor_mount_length, motor_dia,base_thick + 0.2]);
}
// Motor cradles (placed at corners, oriented with shaft outward along width)
// Front left
translate([motor_offset, motor_rad + wall_thick + 10, base_thick]) rotate([90,0,90]) motor_cradle();
// Front right
translate([motor_offset, base_width - (motor_rad + wall_thick +10), base_thick]) rotate([90,0,90]) motor_cradle();
// Rear left
translate([base_length - motor_offset - motor_mount_length, motor_rad + wall_thick + 10, base_thick]) rotate([90,0,90]) motor_cradle();
// Rear right
translate([base_length - motor_offset - motor_mount_length, base_width - (motor_rad + wall_thick +10), base_thick]) rotate([90,0,90]) motor_cradle();
// Raspberry Pi standoffs (centered)
translate([(base_length - rpi_length)/2, (base_width - rpi_width)/2, base_thick]) {
translate([0, 0, 0]) standoff();
translate([rpi_hole_dist_x, 0, 0]) standoff();
translate([0, rpi_hole_dist_y, 0]) standoff();
translate([rpi_hole_dist_x, rpi_hole_dist_y, 0]) standoff();
}
translate([rpi_hole_dist_x+61, rpi_hole_dist_y-5.5, 13]) {
rotate([0, 0, 90]) {
board_raspberrypi_3_model_b();
}
}
// Camera mount (front center)
translate([motor_offset / 2, (base_width - camera_mount_size)/2, base_thick]) camera_mount();
// Battery holder (rear center)
translate([base_length - battery_length - wall_thick*2 - motor_offset, (base_width - battery_width - wall_thick*2)/2, base_thick]) battery_holder();
}
}
// Separate motor caps (print 4)
module caps() {
for (i = [0:3]) {
translate([i * (2 * (motor_rad + wall_thick) + 10), 0, 0]) motor_cap();
}
}
// Output parts
// Comment/uncomment to generate specific parts
base(); // The main frame with integrated mounts
// translate([0, base_width + 20, 0]) caps(); // The 4 top brackets
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment