Fix (UI): Corrected console outputs for UBOM.

This commit is contained in:
2025-05-30 10:49:42 +01:00
parent 3ae48a8c90
commit e8869552fc
21 changed files with 353 additions and 7 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
env_scad/
env_scad/*

32
config.py Normal file
View File

@@ -0,0 +1,32 @@
from models.dimensions_3d import Dimensions_3D
from pydantic import BaseModel
from typing import ClassVar
class Config(BaseModel):
D_AXLE_FRONT: ClassVar[float] = 42
D_AXLE_REAR: ClassVar[float] = 27
D_WASHER_AXLE_REAR_WHEEL_POSITIONING: ClassVar[float] = 50
D_WASHER_BOLT_REAR_WHEEL_POSITIONING: ClassVar[float] = 30
D_WHEEL: ClassVar[float] = 400
D_WHEEL_BONE: ClassVar[float] = 25
L_BOLT_EXTENSION: ClassVar[float] = 10
# M_TOTAL: ClassVar[float] = 160
R_BED: ClassVar[Dimensions_3D] = Dimensions_3D(x=400, y=1200, z=18)
SIZE_BOLT: ClassVar[float] = 25
SIZE_BOLT_REAR_WHEEL_POSITIONING: ClassVar[float] = 10
SPACING_WASHER_AXLE_REAR_WHEEL_POSITIONING: ClassVar[float] = 1
SPACING_XY_BED_BORDER: ClassVar[float] = 10
T_CLAMP: ClassVar[float] = 20
T_PLATE: ClassVar[float] = 8
T_WASHER_AXLE_REAR_WHEEL_POSITIONING: ClassVar[float] = 4
T_WASHER_BOLT_REAR_WHEEL_POSITIONING: ClassVar[float] = 1.5
T_WHEEL: ClassVar[float] = 100
Z_OVERLAP_TEE_CLAMP_ROUND: ClassVar[float] = 80
Z_OFFSET_WHEEL_TO_BED_BASE: ClassVar[float] = 5
X_POSITION_WHEEL_CENTRE: float
Y_POSITION_AXLE_FRONT: float
Y_POSITION_AXLE_REAR: float
Z_OFFSET_BED_TO_AXLE: float

View File

@@ -45,7 +45,7 @@ X_POS_AXLE_LEG_REAR = min(X_POS_WHEEL_CENTRE - T_WHEEL / 2 - SPACING_WASHER_AXLE
// THICKNESS_SHELL_BRAKE_BEAM = 5;
// L_BEAM_BRAKE_BELT_TENSION_FIXING = 150;
D_BEAM_BRAKE = 40;
T_BEAM_BRAKE = 5;
T_BEAM_BRAKE = 3;
D_BRAKE_BALLSCREW_AXLE = 16; // M16 pitch 1.5
L_BRAKE_BALLSCREW_AXLE = 450;
D_BRAKE_BALLSCREW_POWER_WHEEL = 120;

View File

@@ -1 +0,0 @@
,teddy,lord-T-1024,20.02.2025 13:01,file:///home/teddy/.config/libreoffice/4;

Binary file not shown.

0
models/__init__.py Normal file
View File

69
models/base_3d_object.py Normal file
View File

@@ -0,0 +1,69 @@
from coordinates_3d import Coordinates_3D
from dimensions_3d import Dimensions_3D
from material import Material
from abc import ABC
from pydantic import BaseModel
import openpyscad as ops
# from solid import OpenSCADObject
from typing import Optional
class Base_3D_Object(BaseModel, ABC):
colour: str = ''
dimensions_enclosing_cube: Dimensions_3D
__mass: float
material: Material
object: ops.base.BaseObject
parent: 'Base_3D_Object' = None
position_centre_local_assembly: Coordinates_3D = Coordinates_3D(x = 0, y = 0, z = 0)
rotation: Coordinates_3D = Coordinates_3D(x = 0, y = 0, z = 0)
__volume_solid: float
"""
@classmethod
def make_local_object(cls, colour: str, dimensions_enclosing_cube: Dimensions_3D, material: Material, position_centre_local_assembly: Coordinates_3D, rotation: Coordinates_3D) -> 'Base_3D_Object':
return cls(
colour=colour,
dimensions_enclosing_cube=dimensions_enclosing_cube,
mass=material.density * dimensions_enclosing_cube.x * dimensions_enclosing_cube.y * dimensions_enclosing_cube.z,
material=material,
position_centre_local_assembly=position_centre_local_assembly,
position_centre_major_assembly=position_centre_local_assembly,
rotation=rotation,
volume_solid=dimensions_enclosing_cube.x * dimensions_enclosing_cube.y * dimensions_enclosing_cube.z
)
"""
@classmethod
def from_dimensions_and_material_and_parent(cls, dimensions_enclosing_cube: Dimensions_3D, material: Material, parent: Optional['Base_3D_Object']) -> 'Base_3D_Object':
return cls(
dimensions_enclosing_cube = dimensions_enclosing_cube,
material = material,
colour = material.colour,
parent = parent,
)
def get_position_centre_major_assembly(self) -> Coordinates_3D:
if self.parent is None:
return self.position_centre_local_assembly
else:
position_centre_parent_major_assembly = self.parent.get_position_centre_major_assembly()
return Coordinates_3D(
x=self.position_centre_local_assembly.x + position_centre_parent_major_assembly.x,
y=self.position_centre_local_assembly.y + position_centre_parent_major_assembly.y,
z=self.position_centre_local_assembly.z + position_centre_parent_major_assembly.z
)
def get_mass(self) -> float:
if self.__mass is None:
self.__mass = self.material.density * self.volume_solid
return self.__mass
def get_volume_solid(self) -> float:
if self.__volume_solid is None:
self.__volume_solid = self.dimensions_enclosing_cube.x * self.dimensions_enclosing_cube.y * self.dimensions_enclosing_cube.z
return self.__volume_solid

0
models/bed/__init__.py Normal file
View File

View File

@@ -0,0 +1,10 @@
from models.base_3d_object import Base_3D_Object
import models.fixings.tube_clamp_round_base_plate_132
"""
import solid
import solid.utils
"""
class Bed_Assembly(Base_3D_Object):

View File

@@ -0,0 +1,43 @@
from models.base_3d_object import Base_3D_Object
from models.dimensions_3d import Dimensions_3D
from models.material import Material
from pydantic import Field
class Metric_Bolt(Base_3D_Object):
head_diameter: float = Field(gt = 0)
head_length: float = Field(gt = 0)
length: float = Field(gt = 0)
shaft_length: float = Field(gt = 0)
size: float = Field(gt = 0)
@classmethod
def from_size_and_length_and_material(cls, size: float, length: float, material: Material) -> 'Metric_Bolt':
head_diameter = cls.get_head_diameter(size = size)
bolt = Metric_Bolt.from_dimensions_and_material(
dimensions_enclosing_cube = Dimensions_3D(
x = head_diameter,
y = head_diameter,
z = length
),
material = material
)
bolt.size = size
bolt.length = length
bolt.head_diameter = head_diameter
bolt.head_length = cls.get_head_length(size = size)
bolt.shaft_length = bolt.length - bolt.head_length
@classmethod
def get_head_diameter(cls, size: float) -> float:
return size * 2
@classmethod
def get_head_length(cls, size: float) -> float:
return size
@classmethod
def get_washer_diameter_safe_working_clearance(cls, size: float) -> float:
return size * 4 if size < 20 else size * 3

7
models/coordinates_3d.py Normal file
View File

@@ -0,0 +1,7 @@
from pydantic import BaseModel, Field
class Coordinates_3D(BaseModel):
x: float
y: float
z: float

7
models/dimensions_3d.py Normal file
View File

@@ -0,0 +1,7 @@
from pydantic import BaseModel, Field
class Dimensions_3D(BaseModel):
x: float = Field(ge = 0)
y: float = Field(ge = 0)
z: float = Field(ge = 0)

View File

@@ -0,0 +1,17 @@
from models.base_3d_object import Base_3D_Object
from models.material import Material
from abc import abstractmethod
from typing import ClassVar
class Base_Tube_Clamp(Base_3D_Object):
MATERIAL_DEFAULT: ClassVar[Material] = Material(
name = 'Steel',
density = 7.85,
colour = 'LightGrey'
)
@abstractmethod
def from_tube_diameter(cls, tube_diameter: float) -> 'Base_Tube_Clamp':
pass

View File

@@ -31,7 +31,7 @@ module tube_clamp_round_3_way_outlet_tee_176(tube_diameter) {
rotate([90, 0, 0]) cylinder(L_shaft_long, tube_diameter / 2, tube_diameter / 2, center = true);
}
// Shopping
echo("Round 3-way outlet tee 176: Tube clamp - x1");
echo(str("Round 3-way outlet tee 176: Tube clamp Φ", tube_diameter, "mm - x1"));
}
// test output

View File

@@ -19,7 +19,7 @@ module tube_clamp_round_3_way_through_116(tube_diameter) {
translate([0, L_shaft_long / 2, 0]) rotate([90, 0, 0]) cylinder(L_shaft_long, tube_diameter / 2, tube_diameter / 2, center = true);
}
// Shopping
echo("Round 3-way through 116: Tube clamp - x1");
echo(str("Round 3-way through 116: Tube clamp Φ", tube_diameter, "mm - x1"));
}
// test output

View File

@@ -0,0 +1,150 @@
from models.base_3d_object import Base_3D_Object
from models.fixings.base_tube_clamp import Base_Tube_Clamp
from models.dimensions_3d import Dimensions_3D
from models.material import Material
from pydantic import Field
# import solid
import openpyscad as ops
class Tube_Clamp_Round_Base_Plate_132(Base_Tube_Clamp):
@classmethod
def from_tube_diameter_and_parent(cls, tube_diameter: float, parent: Base_3D_Object) -> 'Tube_Clamp_Round_Base_Plate_132':
L_shaft_with_base_plate = cls.get_L_shaft_with_base_plate(tube_diameter = tube_diameter)
R_plate = cls.get_R_plate(tube_diameter = tube_diameter)
y_offset_hole = cls.get_offset_hole_y(tube_diameter = tube_diameter)
diameter_hole_bolt = cls.get_diameter_hole(tube_diameter = tube_diameter)
tube_clamp = cls.from_dimensions_and_material_and_parent(
dimensions_enclosing_cube = Dimensions_3D(
x = R_plate.x,
y = R_plate.y,
z = L_shaft_with_base_plate
),
material = cls.MATERIAL_DEFAULT,
parent = parent,
)
clamp_shaft = cls.__make_shaft_object(
tube_diameter = tube_diameter,
L_shaft_with_base_plate = L_shaft_with_base_plate,
R_plate = R_plate,
)
clamp_shaft.translate([0, 0, L_shaft_with_base_plate / 2])
base_plate = cls.__make_base_plate_object(
R_plate = R_plate,
y_offset_hole = y_offset_hole,
diameter_hole_bolt = diameter_hole_bolt,
)
base_plate.translate([0, 0, R_plate.z / 2])
tube_clamp.object = ops.Union()
tube_clamp.object.append(base_plate)
tube_clamp.object.append(clamp_shaft)
tube_clamp.object.color(cls.MATERIAL_DEFAULT.colour)
return tube_clamp
@classmethod
def __make_shaft_object(cls, tube_diameter: float, L_shaft_with_base_plate: float, R_plate: tuple[float, float, float]) -> ops.base.BaseObject:
clamp_shaft = ops.Difference()
clamp_shaft.append(
ops.Cylinder(
h = L_shaft_with_base_plate,
r = tube_diameter / 2 + R_plate.z,
)
)
clamp_shaft.append(
ops.Cylinder(
h = L_shaft_with_base_plate,
r = tube_diameter / 2,
)
)
return clamp_shaft
@classmethod
def __make_base_plate_object(cls, R_plate: Dimensions_3D, y_offset_hole: float, diameter_hole_bolt: float) -> ops.base.BaseObject:
base_plate = ops.Difference()
base_plate.append(
ops.Cube(
v = [R_plate.x, R_plate.y, R_plate.z],
center = True,
)
)
base_plate.append(
ops.Cylinder(
h = R_plate.z,
r = diameter_hole_bolt / 2,
center = True,
).translate([0, y_offset_hole, 0])
)
base_plate.append(
ops.Cylinder(
h = R_plate.z,
r = diameter_hole_bolt / 2,
center = True,
).translate([0, -y_offset_hole, 0])
)
return base_plate
@classmethod
def get_L_shaft_with_base_plate(cls, tube_diameter: float) -> float:
L_shaft = 25
if tube_diameter == 27:
L_shaft = 85
elif tube_diameter == 42:
L_shaft = 122
return L_shaft
@classmethod
def get_R_plate(cls, tube_diameter: float) -> Dimensions_3D:
R_plate = Dimensions_3D(
x = 10,
y = 20,
z = 1
)
if tube_diameter == 27:
R_plate = Dimensions_3D(
x = 64,
y = 114,
z = 7
)
elif tube_diameter == 42:
R_plate = Dimensions_3D(
x = 80,
y = 140,
z = 10
)
else:
raise ValueError(f"Unsupported tube diameter: {tube_diameter}")
return R_plate
@classmethod
def get_offset_hole_y(cls, tube_diameter: float) -> float:
y_offset = 10
if tube_diameter == 27:
y_offset = 38
elif tube_diameter == 42:
y_offset = 50
else:
raise ValueError(f"Unsupported tube diameter: {tube_diameter}")
return y_offset
@classmethod
def get_diameter_hole(cls, tube_diameter: float) -> float:
return 10
@classmethod
def get_mass(cls, tube_diameter: float) -> float:
mass = 0
if tube_diameter == 27:
mass = 0.5
elif tube_diameter == 42:
mass = 1.06
else:
raise ValueError(f"Unsupported tube diameter: {tube_diameter}")
return mass

View File

@@ -21,7 +21,7 @@ module tube_clamp_round_base_plate_132(tube_diameter) {
}
}
// Shopping
echo("Round base plate 132: Tube clamp - x1");
echo(str("Round base plate 132: Tube clamp Φ", tube_diameter, "mm - x1"));
}
// test output

View File

@@ -16,7 +16,7 @@ module tube_clamp_round_tee_long_104(tube_diameter) {
translate([L_shaft_short / 2, 0, 0]) rotate([0, 90, 0]) cylinder(L_shaft_short, tube_diameter / 2, tube_diameter / 2, center = true);
}
// Shopping
echo("Round tee long 104: Tube clamp - x1");
echo(str("Round tee long 104: Tube clamp Φ", tube_diameter, "mm - x1"));
}
// test output

View File

@@ -21,7 +21,7 @@ module tube_clamp_square_base_plate_132(beam_width) {
}
}
// Shopping
echo("Square base plate 132: Tube clamp - x1");
echo(str("Square base plate 132: Tube clamp Φ", beam_width, "mm - x1"));
}
// test output

7
models/material.py Normal file
View File

@@ -0,0 +1,7 @@
from pydantic import BaseModel, Field
class Material(BaseModel):
colour: str
density: float = Field(gt = 0)
name: str

3
requirements.txt Normal file
View File

@@ -0,0 +1,3 @@
openpyscad
pydantic
# solid