A lot more work on the Microcar design. I'm not yet at all satisfied with this.

This commit is contained in:
Simon Brooke 2026-09-10 22:25:49 +01:00
parent 0e97b3b267
commit 8e0e6adacb
6 changed files with 184 additions and 64 deletions

20
microcar/microcar.scad Normal file
View file

@ -0,0 +1,20 @@
/**
* microcar.scad
*
* First sketch of a microcar.
*/
include <BOSL2/std.scad>
include <suspension.scad>
include <tub.scad>
tub(fl=1100);
translate([-900,0,130])
suspension();
translate([1100,0,130])
suspension();

View file

@ -0,0 +1,40 @@
/**
* shockabsorber.scad
*
* First sketch of a microcar spring/shock absorber unit. Ideally I
* would want to use linked hydropneumatic units, but that would be
* *absurdly* over expensive for a one off prototype. Air or conventional
* spring units would be far more pragmatic.
*/
include <BOSL2/std.scad>
eye_inner_diameter = 25/3; // to make it the same as pivot_radius defined
// in suspension.scad
module eye( eid=eye_inner_diameter) {
rotate([0, 90, 0]) {
difference() {
cylinder( h=eid, r=eid, center=true);
cylinder( h=2*eid, d=eid, center=true);
}
}
}
module shockabsorber( length=150, eid=eye_inner_diameter, coil_over=true) {
short_length=length-(eid*4);
translate([0,0,eid]) {
// cylinder
cylinder(h=short_length/2, r=short_length/16);
// rod
cylinder(h=short_length, r=short_length/32);
translate([0,0,0-eid]) {
eye(eid);
}
translate([0,0, short_length+eid]) {
eye(eid);
}
}
}

View file

@ -5,36 +5,45 @@
* *
* The purpose of the subframe is sumply to carry the inner ends of the * The purpose of the subframe is sumply to carry the inner ends of the
* wishbones, so it is simply the minimum size required to do that. * wishbones, so it is simply the minimum size required to do that.
*
* TODO: this does not yet consider caster, camber, anti-dive geometry,
* or other such niceties.
*/ */
// assumes we're building out of square section aluminium tobe; include <BOSL2/std.scad>
// the section width of that tube. include <shockabsorber.scad>
stock_section = 25; include <wheel.scad>
lug_thickness = stock_section/6; // assumes we're building out of square section aluminium tobe;
// the section width of that tube.
stock_section = 25;
// radius of suspension pivots lug_thickness = stock_section/6;
pivot_radius = stock_section/3; //for now
module lug() { // radius of suspension pivots
pivot_radius = stock_section/3; //for now
module lug() {
difference() { difference() {
union() { union() {
translate([0, stock_section/2, 0]){ translate([0, stock_section/2, 0]){
cube([ stock_section, stock_section, lug_thickness], center=true); cube([ stock_section, stock_section, lug_thickness],
center=true);
} }
cylinder( r=stock_section/2, h=stock_section/4, center=true); cylinder( r=stock_section/2, h=stock_section/4,
center=true);
} }
cylinder( r=pivot_radius, h=stock_section, center=true); cylinder( r=pivot_radius, h=stock_section, center=true);
} }
} }
module wishbone(l, w) { module wishbone(l, w, is_upper = true) {
ssd2 = stock_section/2; ssd2 = stock_section/2;
ssm2 = stock_section * 2; ssm2 = stock_section * 2;
ssm3 = stock_section * 3; ssm3 = stock_section * 3;
// wishbone inboard pivot lugs
translate([ (l - lug_thickness)/2, stock_section, ssd2]) translate([ (l - lug_thickness)/2, stock_section, ssd2])
rotate([180,90,0]) rotate([180,90,0])
lug(); lug();
@ -42,12 +51,30 @@
rotate([180,90,0]) rotate([180,90,0])
lug(); lug();
// shock absorber end lugs
if (is_upper) {
translate([ ssd2, ssm2, ssd2])
rotate([180,90,0])
lug();
translate([ -ssd2, ssm2, ssd2])
rotate([180,90,0])
lug();
} else {
translate([ ssd2, w-ssm3, ssd2])
rotate([180,90,180])
lug();
translate([ -ssd2, w-ssm3, ssd2])
rotate([180,90,180])
lug();
}
color("silver") color("silver")
union() { union() {
intersection(){ intersection(){
linear_extrude(stock_section) linear_extrude(stock_section)
polygon( points=[[0-(l/2), ssd2], [l/2, ssd2], polygon( points=[[0-(l/2), ssd2], [l/2, ssd2],
[3*ssd2, w-(3*ssd2)], [0-(3*ssd2), w-(3*ssd2)], [3*ssd2, w-(3*ssd2)],
[0-(3*ssd2), w-(3*ssd2)],
// hole in the middle // hole in the middle
[0-(l/2 - 3*ssd2), 3*ssd2], [0-(l/2 - 3*ssd2), 3*ssd2],
[l/2 - 3*ssd2, 3*ssd2], [l/2 - 3*ssd2, 3*ssd2],
@ -83,27 +110,45 @@
} }
} }
module suspension( l = 300, w = 300, h = 300, module suspension( l = 300, w = 300, h = 300,
track = 1400, hub_width = 135, wheel_diameter=600) { track = 1400, hub_width = 135, wheel_diameter=600) {
subframe(l,w,h); subframe(l,w,h);
wishbone_length = 500; // TODO: calculate
// Upper wishbones // Upper wishbones
translate([0, w/2, (h/2) - stock_section]) translate([0, w/2, (h/2) - stock_section])
wishbone( l, 500); wishbone( l, wishbone_length);
mirror([0,1, 0]) { mirror([0,1, 0]) {
translate([0, w/2, (h/2) - stock_section]) translate([0, w/2, (h/2) - stock_section])
wishbone( l, 500); wishbone( l, wishbone_length);
} }
shock_extent = wishbone_length - (5.5 * stock_section);
shock_angle = atan(shock_extent/(h-stock_section));
shock_length = shock_extent * tan(shock_angle);
// lower wishbones // lower wishbones
translate([0, w/2, 0 -(h/2)]) translate([0, w/2, 0 -(h/2)]) {
wishbone( l, 500); wishbone( l, wishbone_length, false);
translate([0, wishbone_length + 75, stock_section])
wheel();
translate([0, (stock_section*2), h-(stock_section/2)])
rotate([shock_angle +180, 0, 0])
shockabsorber(length=shock_length,eid=stock_section/2);
}
mirror([0,1, 0]) { mirror([0,1, 0]) {
translate([0, w/2, 0 -(h/2)]) translate([0, w/2, 0 -(h/2)]) {
wishbone( l, 500); wishbone( l, wishbone_length, false);
translate([0, wishbone_length + 75, stock_section])
wheel();
translate([0, (stock_section*2), h-(stock_section/2)])
rotate([shock_angle +180, 0, 0])
shockabsorber(length=shock_length,
eid=stock_section/2);
} }
} }
}
lug();
suspension(); // suspension();

View file

@ -1,3 +1,11 @@
/**
* tub.scad
*
* The tub of a microcar.
*/
include <BOSL2/std.scad>
$fn = $preview ? 32 : 256; $fn = $preview ? 32 : 256;
a_pillar_y = -400; // y location of face of 'A' pillar a_pillar_y = -400; // y location of face of 'A' pillar
@ -28,7 +36,7 @@ floor_width = 1500;
// angle of the front bulkhead to vertical // angle of the front bulkhead to vertical
layback_angle_f = 30; layback_angle_f = 30;
// angle of the rear bulkhead to vertical // angle of the rear bulkhead to vertical
layback_angle_r = 45; layback_angle_r = 50;
sheet_thickness = 8; sheet_thickness = 8;
sill_max_height = bb_height; sill_max_height = bb_height;
@ -100,17 +108,23 @@ module front_bulkhead() {
module rear_bulkhead() { module rear_bulkhead() {
} }
module tub(fl=floor_length, fw=floor_width, st=sheet_thickness,
cube([floor_length, floor_width, sheet_thickness], sw=sill_width) {
cube([fl, fw, st],
center=true); center=true);
battery_box(); battery_box();
translate([0, ( floor_width/2) + (sill_width/2), 0]) translate([0, ( fw/2) + (sw/2), 0])
sill(); sill();
mirror([0, 1, 0]) mirror([0, 1, 0])
translate([0, translate([0,
( floor_width/2) + (sill_width/2), 0]) ( fw/2) + (sw/2), 0])
sill(); sill();
front_bulkhead(); front_bulkhead();
rear_bulkhead();
}
// tub();

1
microcar/wheel.scad Symbolic link
View file

@ -0,0 +1 @@
../model/wheel.scad

View file

@ -63,4 +63,4 @@ module hull() {
} }
} }
// hull(); hull();