Skip to content

Commit

Permalink
Add the screws to the BOM for each shelf
Browse files Browse the repository at this point in the history
  • Loading branch information
julianstirling committed Dec 19, 2024
1 parent 5038c27 commit a40d9b4
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 19 deletions.
61 changes: 56 additions & 5 deletions nimble_build_system/cad/fasteners.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ def __init__(
explode_translation:tuple[float, float, float]=(0.0, 0.0, 0.0),
size:str="M3-0.5",
fastener_type:str="iso7380_1",
direction_axis:str="-Z"
direction_axis:str="-Z",
human_name:str=""
):
"""
Generic fastener constructor that sets common attributes for all faster types.
Expand All @@ -32,6 +33,10 @@ def __init__(
self._size = size
self._fastener_type = fastener_type
self._direction_axis = direction_axis
if human_name == "":
self._human_name = self._gen_human_name
else:
self._human_name=human_name

@property
def name(self):
Expand All @@ -47,6 +52,14 @@ def name(self, name):
"""
self._name = name

@property
def human_name(self):
"""
Getter for the human name of the fastener. This is how it
will appear in GitBuilding.
"""
return self._human_name

@property
def position(self):
"""
Expand Down Expand Up @@ -82,6 +95,9 @@ def direction_axis(self):
"""
return self._direction_axis

def _gen_human_name(self):
return f"{self.size} {self.fastener_type}"


class Screw(Fastener):
"""
Expand All @@ -98,7 +114,8 @@ def __init__(
size:str="M3-0.5",
fastener_type:str="iso7380_1",
axis:str="-Z",
length:float=6.0
length:float=6.0,
human_name:str=""
):
"""
Screw constructor that additionally sets the length of the screw.
Expand All @@ -112,7 +129,8 @@ def __init__(
explode_translation=explode_translation,
size=size,
fastener_type=fastener_type,
direction_axis=axis
direction_axis=axis,
human_name=human_name
)

@property
Expand All @@ -122,6 +140,34 @@ def length(self):
"""
return self._length

def _gen_human_name(self):
if self.fastener_type == "iso10642":
fastener = "Countersunk Screw"
elif self.fastener_type == "asme_b_18.6.3":
fastener = "Pan Head Screw"
elif self.fastener_type == "iso7380_1":
fastener = "Button Head Screw"
else:
fastener = self.fastener_type
return f"{self._size_str}x{self.length} {fastener}"

@property
def _size_str(self):
reps = {"M1.6-0.35": "M1.6",
"M2-0.4": "M2",
"M2.5-0.45": "M2.5",
"M3-0.5": "M3",
"M3.5-0.6": "M3.5",
"M4-0.7": "M4",
"M5-0.8": "M5",
"M6-1": "M6",
"M8-1": "M8-fine",
"M8-1.25": "M8",
"M10-1.25": "M10-fine",
"M10-1.5": "M10"}
if self.size in reps:
return reps[self.size]
return self.size

class Ziptie(Fastener):
"""
Expand All @@ -143,7 +189,8 @@ def __init__(self,
size:str,
fastener_type:str,
axis:str,
length:float):
length:float,
human_name:str=""):

self._length = length
self._width = float(size)
Expand All @@ -153,7 +200,8 @@ def __init__(self,
explode_translation=explode_translation,
size=size,
fastener_type=fastener_type,
direction_axis=axis)
direction_axis=axis,
human_name=human_name)


@property
Expand All @@ -178,3 +226,6 @@ def width(self):
Getter for the width of the ziptie.
"""
return self._width

def _gen_human_name(self):
return f"ziptie ({self.width}x{self.length}mm)"
61 changes: 47 additions & 14 deletions nimble_build_system/cad/shelf.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def __init__(self,
self._rack_params = rack_params

self._device = device
self.setup_assembly()
self._setup_assembly()
#Note that "assembled shelf" is the CadOrchestrator AssembledComponent
# object not the full calculation in CadQuery of the physical assembly!
self._assembled_shelf = self._generate_assembled_shelf(assembly_key,
Expand All @@ -146,7 +146,12 @@ def __init__(self,
#Note docs can only be generated after self._assembled_shelf is set
self._assembled_shelf.component.set_documentation(self.generate_docs())

def setup_assembly(self):
def _setup_assembly(self):
"""
This is called during init to set up how the device is assembled and rendered
This must be called before setting the documentation as this uses the renders
and fasteners set here
"""
# Make some sane guesses at the device positioning
if self._device.width is None or self._device.depth is None:
self._device_depth_axis = "X"
Expand Down Expand Up @@ -496,12 +501,14 @@ def generate_assembly_model(self, render_options=None):
fastener_type=fastener.fastener_type,
length=fastener.length,
simple=True).cq_object)
else:
elif fastener.fastener_type == "iso7380_1":
# Create a button head screw model
cur_fastener = cq.Workplane(ButtonHeadScrew(size=fastener.size,
fastener_type=fastener.fastener_type,
length=fastener.length,
simple=True).cq_object)
else:
raise ValueError("Unknown screw type.")


# Allows the proper face to be selected for the extension lines
Expand Down Expand Up @@ -646,6 +653,30 @@ def generate_renders(self, base_path=None):
file_path=file_path,
render_options=cur_render_options)

def _fasteners_for_doc(self):
fastener_dict = {}
for fastener in self._fasteners:
if fastener.human_name() in fastener_dict:
fastener_dict[fastener.human_name()]["qty"] += 1
else:
fastener_dict[fastener.human_name()] = {"qty": 1}
return fastener_dict

@property
def _fastener_str(self):
fasteners = self._fasteners_for_doc()
fastener_strs = []
for name, data in fasteners.items():
qty = data["qty"]
fastener_strs.append(f"{qty} [{name}]"+"{qty:"+str(qty)+"}")
if len(fastener_strs) == 0:
return ""
if len(fastener_strs) == 1:
return fastener_strs[0]
if len(fastener_strs) == 2:
return fastener_strs[0] + " and " + fastener_strs[0]
fastener_strs[-1] = "and " + fastener_strs[-1]
return ", ".join(fastener_strs)

def generate_docs(self):
"""
Expand All @@ -669,13 +700,15 @@ def generate_docs(self):
md += "{{BOM}}\n\n"
md += "## Position the "+self._device.name+" {pagestep}\n\n"
md += "* Take the ["+self.name+"]{make, qty:1, cat:printed} you printed earlier\n"
md += "* Position the ["+self._device.name+"]{qty:1, cat:net} on the shelf\n\n"
fastener_str = self._fastener_str
if fastener_str:
md += "* Position the ["+self._device.name+"]{qty:1, cat:net} on the shelf as shown\n"
md += f"* Fasten it in place using {fastener_str}.\n"
else:
md += "* Push fit the ["+self._device.name+"]{qty:1, cat:net} on the shelf as shown\n"
md += "\n\n"
for render in self.list_render_files():
md += f"![](../build/renders/{render})"
md += "\n"
md += "## Secure the "+self._device.name+" {pagestep}\n\n"
md += ">!! **TODO** \n>!! Need information on how the item is secured to the shelf."
md += f"![](../build/renders/{render})\n"

return md

Expand Down Expand Up @@ -721,7 +754,7 @@ class NUCShelf(Shelf):
Shelf class for an Intel NUC device.
"""

def setup_assembly(self):
def _setup_assembly(self):

# Device location settings
self._device_depth_axis = "Y"
Expand Down Expand Up @@ -790,7 +823,7 @@ class USWFlexShelf(Shelf):
"""


def setup_assembly(self):
def _setup_assembly(self):

# Device location settings
self._device_depth_axis = "X"
Expand Down Expand Up @@ -867,7 +900,7 @@ class USWFlexMiniShelf(Shelf):
Shelf class for a Ubiquiti Flex Mini device.
"""

def setup_assembly(self):
def _setup_assembly(self):

# Device location settings
self._device_depth_axis = "Y"
Expand Down Expand Up @@ -1011,7 +1044,7 @@ class HDD35Shelf(Shelf):
Shelf class for a 3.5" hard drive device.
"""

def setup_assembly(self):
def _setup_assembly(self):

# Device location settings
self._device_depth_axis = "X"
Expand Down Expand Up @@ -1119,7 +1152,7 @@ class DualSSDShelf(Shelf):
Shelf class for two 2.5" solid state drive devices.
"""

def setup_assembly(self):
def _setup_assembly(self):

# Device location settings
self._device_depth_axis = "X"
Expand Down Expand Up @@ -1232,7 +1265,7 @@ class RaspberryPiShelf(Shelf):
"Raspberry_Pi_5": {"description": "A shelf for a Raspberry Pi 5", "step_path": "N/A"},
}

def setup_assembly(self):
def _setup_assembly(self):

# Screw hole parameters
self.screw_dist_x = 49
Expand Down

0 comments on commit a40d9b4

Please sign in to comment.