File size: 3,770 Bytes
6de1b61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
from __future__ import annotations

from typing import Literal

from pydantic import BaseModel, Field


MaterialName = Literal["aluminum_6061", "aluminum_7075", "pla", "petg", "steel_1018"]
FeatureType = Literal[
    "rib",
    "lightening_hole",
    "boss",
    "fillet_marker",
    "hook_curve",
    "clamp_jaw",
    "stator_ring",
    "stator_tooth",
    "seat_panel",
    "chair_leg",
    "chair_back",
    "chair_crossbar",
    "decorative_curve",
    "generic_panel",
    "support_tube",
    "curved_tube",
    "flat_foot",
    "armrest",
    "headrest",
    "tabletop",
    "table_leg",
]


class Feature(BaseModel):
    type: FeatureType
    x: float = 0.0
    y: float = 0.0
    x2: float = 0.0
    y2: float = 0.0
    width: float = 0.0
    height: float = 0.0
    radius: float = 0.0
    note: str = ""


class Hole(BaseModel):
    x: float
    y: float
    radius: float


class Design(BaseModel):
    title: str = "Untitled design"
    rationale: str = ""
    material: MaterialName = "aluminum_6061"
    load_newtons: float = 120.0
    load_point_x_mm: float = 90.0
    load_point_y_mm: float = 0.0
    base_length_mm: float = 105.0
    base_width_mm: float = 44.0
    base_thickness_mm: float = 4.0
    fixed_holes: list[Hole] = Field(default_factory=list)
    features: list[Feature] = Field(default_factory=list)
    expected_failure_mode: str = ""
    action_plan: list[str] = Field(default_factory=list)


class ToolAction(BaseModel):
    tool: str
    params: dict = Field(default_factory=dict)


class Material(BaseModel):
    density_g_cm3: float
    yield_mpa: float
    young_mpa: float
    thermal_w_mk: float
    poisson: float = 0.33


MATERIALS: dict[str, Material] = {
    "aluminum_6061": Material(density_g_cm3=2.70, yield_mpa=276, young_mpa=69000, thermal_w_mk=167),
    "aluminum_7075": Material(density_g_cm3=2.81, yield_mpa=503, young_mpa=71700, thermal_w_mk=130),
    "pla": Material(density_g_cm3=1.24, yield_mpa=55, young_mpa=3500, thermal_w_mk=0.13),
    "petg": Material(density_g_cm3=1.27, yield_mpa=50, young_mpa=2100, thermal_w_mk=0.20),
    "steel_1018": Material(density_g_cm3=7.87, yield_mpa=370, young_mpa=200000, thermal_w_mk=51),
}


def sample_design() -> Design:
    return Design(
        title="Two-rib lightweight cantilever bracket",
        rationale=(
            "A broad thin base keeps bolt spacing stable, two diagonal ribs move material "
            "toward the bending load path, and small lightening holes reduce mass away "
            "from the fixed edge."
        ),
        material="aluminum_6061",
        load_newtons=120,
        load_point_x_mm=90,
        load_point_y_mm=0,
        base_length_mm=105,
        base_width_mm=44,
        base_thickness_mm=4,
        fixed_holes=[Hole(x=12, y=-13, radius=3), Hole(x=12, y=13, radius=3)],
        features=[
            Feature(type="rib", x=16, y=-14, x2=88, y2=-4, width=5, height=18, note="lower diagonal rib"),
            Feature(type="rib", x=16, y=14, x2=88, y2=4, width=5, height=18, note="upper diagonal rib"),
            Feature(type="rib", x=18, y=0, x2=96, y2=0, width=4, height=12, note="center spine rib"),
            Feature(type="lightening_hole", x=52, y=-13, radius=4, note="low-stress pocket"),
            Feature(type="lightening_hole", x=52, y=13, radius=4, note="low-stress pocket"),
            Feature(type="boss", x=92, y=0, height=7, radius=6, note="load application boss"),
        ],
        expected_failure_mode="Bending stress at the fixed edge and rib roots.",
        action_plan=[
            "Search the load path",
            "Add ribs along tension/compression lines",
            "Remove material from low-stress regions",
            "Run simulation",
            "Iterate dimensions",
        ],
    )