""" Electronic components """ from dataclasses import dataclass import cadquery as Cq from nhf.materials import Role from nhf.parts.item import Item from nhf.parts.fasteners import FlatHeadBolt, HexNut @dataclass(frozen=True) class LinearActuator(Item): stroke_length: float shaft_diam: float = 9.04 front_hole_ext: float = 4.41 front_hole_diam: float = 4.41 front_length: float = 9.55 front_width: float = 9.24 front_height: float = 5.98 segment1_length: float = 37.55 segment1_width: float = 15.95 segment1_height: float = 11.94 segment2_length: float = 37.47 segment2_width: float = 20.03 segment2_height: float = 15.03 back_hole_ext: float = 4.58 back_hole_diam: float = 4.18 back_length: float = 9.27 back_width: float = 10.16 back_height: float = 8.12 @property def name(self) -> str: return f"LinearActuator {self.stroke_length}mm" @property def role(self) -> Role: return Role.MOTION @property def conn_length(self): return self.segment1_length + self.segment2_length + self.front_hole_ext + self.back_hole_ext def generate(self, pos: float=0) -> Cq.Assembly: stroke_x = pos * self.stroke_length front = ( Cq.Workplane('XZ') .cylinder( radius=self.front_width / 2, height=self.front_height, centered=True, ) .box( length=self.front_hole_ext, width=self.front_width, height=self.front_height, combine=True, centered=(False, True, True) ) .copyWorkplane(Cq.Workplane('XZ')) .cylinder( radius=self.front_hole_diam / 2, height=self.front_height, centered=True, combine='cut', ) ) if stroke_x > 0: shaft = ( Cq.Workplane('YZ') .cylinder( radius=self.shaft_diam / 2, height=stroke_x, centered=(True, True, False) ) ) else: shaft = None segment1 = ( Cq.Workplane() .box( length=self.segment1_length, height=self.segment1_width, width=self.segment1_height, centered=(False, True, True), ) ) segment2 = ( Cq.Workplane() .box( length=self.segment2_length, height=self.segment2_width, width=self.segment2_height, centered=(False, True, True), ) ) back = ( Cq.Workplane('XZ') .cylinder( radius=self.back_width / 2, height=self.back_height, centered=True, ) .box( length=self.back_hole_ext, width=self.back_width, height=self.back_height, combine=True, centered=(False, True, True) ) .copyWorkplane(Cq.Workplane('XZ')) .cylinder( radius=self.back_hole_diam / 2, height=self.back_height, centered=True, combine='cut', ) ) result = ( Cq.Assembly() .add(front, name="front", loc=Cq.Location((-self.front_hole_ext, 0, 0))) .add(segment1, name="segment1", loc=Cq.Location((stroke_x, 0, 0))) .add(segment2, name="segment2", loc=Cq.Location((stroke_x + self.segment1_length, 0, 0))) .add(back, name="back", loc=Cq.Location((stroke_x + self.segment1_length + self.segment2_length + self.back_hole_ext, 0, 0), (0, 1, 0), 180)) ) if shaft: result.add(shaft, name="shaft") return result LINEAR_ACTUATOR_SHOULDER = LinearActuator( mass=34.0, stroke_length=30, ) LINEAR_ACTUATOR_HEX_NUT = HexNut( mass=0.8, diam_thread=4, pitch=0.7, thickness=4.16, width=6.79, ) LINEAR_ACTUATOR_BOLT = FlatHeadBolt( mass=1.7, diam_head=16.68, height_head=2.98, diam_thread=4.0, height_thread=15.83, )