from dataclasses import dataclass import unittest import cadquery as Cq import nhf.joints @dataclass(frozen=True) class Parameters: """ Thickness of the exoskeleton panel in millimetres """ panel_thickness: float = 25.4 / 16 # Wing root properties """ Radius of the mounting mechanism of the wing root. This is constrained by the size of the harness. """ root_radius: float = 60 """ Heights for various wing joints, where the numbers start from the first joint. """ wing_r1_height = 100 wing_r1_width = 400 wing_r2_height = 100 wing_r3_height = 100 """ The Houjuu-Scarlett joint mechanism at the base of the wing """ hs_joint_base_width = 85 hs_joint_base_thickness = 10 hs_joint_ring_thickness = 10 hs_joint_tooth_height = 10 hs_joint_radius = 30 hs_joint_radius_inner = 20 hs_joint_corner_fillet = 5 hs_joint_corner_cbore_diam = 12 hs_joint_corner_cbore_depth = 12 hs_joint_corner_diam = 15 hs_joint_corner_inset = 15 def print_geometries(self): return [ self.hs_joint_parent() ] def hs_joint_parent(self): """ Parent part of the Houjuu-Scarlett joint, which is composed of a Hirth coupling, a cylindrical base, and a mounting base. """ hirth = nhf.joints.hirth_joint( radius=self.hs_joint_radius, radius_inner=self.hs_joint_radius_inner, tooth_height=self.hs_joint_tooth_height, base_height=self.hs_joint_ring_thickness) hole_rect_width = self.hs_joint_base_width - 2 * self.hs_joint_corner_inset hirth = ( hirth .faces("Z") .workplane() .rect(hole_rect_width, hole_rect_width, forConstruction=True) .vertices() .cboreHole( diameter=self.hs_joint_corner_diam, cboreDiameter=self.hs_joint_corner_cbore_diam, cboreDepth=self.hs_joint_corner_cbore_depth) .faces(">Z") .workplane() .union(hirth.move((0, 0, self.hs_joint_base_thickness)), tol=0.1) .clean() ) return result def wing_r1_profile(self) -> Cq.Sketch: """ Generates the first wing segment profile, with the wing root pointing in the positive x axis. """ # Depression of the wing middle bend = 200 factor = 0.7 result = ( Cq.Sketch() .segment((0, 0), (0, self.wing_r1_height)) .spline([ (0, self.wing_r1_height), (0.5 * self.wing_r1_width, self.wing_r1_height - factor * bend), (self.wing_r1_width, self.wing_r1_height - bend), ]) .segment( (self.wing_r1_width, self.wing_r1_height - bend), (self.wing_r1_width, -bend), ) .spline([ (self.wing_r1_width, - bend), (0.5 * self.wing_r1_width, - factor * bend), (0, 0), ]) .assemble() ) return result def wing_r1(self) -> Cq.Solid: profile = self.wing_r1_profile() result = ( Cq.Workplane("XY") .placeSketch(profile) .extrude(self.panel_thickness) .val() ) return result def wing_root(self, side_width=30, side_height=100) -> Cq.Shape: """ Generate the wing root which contains a Hirth joint at its base and a rectangular opening on its side, with the necessary interfaces. """ result = ( Cq.Workplane("XY") .circle(self.root_radius) .transformed(offset=Cq.Vector(80, 0, 80), rotate=Cq.Vector(0, 45, 0)) .rect(side_width, side_height) .loft() .val() ) return result