feat: Hirth Joint for wing root
This commit is contained in:
parent
c8613b5f18
commit
4613247e1b
|
@ -0,0 +1,42 @@
|
||||||
|
import cadquery as Cq
|
||||||
|
|
||||||
|
def tidy_repr(obj):
|
||||||
|
"""Shortens a default repr string"""
|
||||||
|
return repr(obj).split(".")[-1].rstrip(">")
|
||||||
|
|
||||||
|
|
||||||
|
def _ctx_str(self):
|
||||||
|
return (
|
||||||
|
tidy_repr(self)
|
||||||
|
+ ":\n"
|
||||||
|
+ f" pendingWires: {self.pendingWires}\n"
|
||||||
|
+ f" pendingEdges: {self.pendingEdges}\n"
|
||||||
|
+ f" tags: {self.tags}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
Cq.cq.CQContext.__str__ = _ctx_str
|
||||||
|
|
||||||
|
|
||||||
|
def _plane_str(self):
|
||||||
|
return (
|
||||||
|
tidy_repr(self)
|
||||||
|
+ ":\n"
|
||||||
|
+ f" origin: {self.origin.toTuple()}\n"
|
||||||
|
+ f" z direction: {self.zDir.toTuple()}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
Cq.occ_impl.geom.Plane.__str__ = _plane_str
|
||||||
|
|
||||||
|
|
||||||
|
def _wp_str(self):
|
||||||
|
out = tidy_repr(self) + ":\n"
|
||||||
|
out += f" parent: {tidy_repr(self.parent)}\n" if self.parent else " no parent\n"
|
||||||
|
out += f" plane: {self.plane}\n"
|
||||||
|
out += f" objects: {self.objects}\n"
|
||||||
|
out += f" modelling context: {self.ctx}"
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
Cq.Workplane.__str__ = _wp_str
|
|
@ -0,0 +1,106 @@
|
||||||
|
import cadquery as Cq
|
||||||
|
import math
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
def hirth_joint(radius=60,
|
||||||
|
radius_inner=40,
|
||||||
|
radius_centre=30,
|
||||||
|
base_height=20,
|
||||||
|
n_tooth=16,
|
||||||
|
tooth_height=16,
|
||||||
|
tooth_height_inner=2):
|
||||||
|
"""
|
||||||
|
Creates a cylindrical Hirth Joint
|
||||||
|
"""
|
||||||
|
# ensures secant doesn't blow up
|
||||||
|
assert n_tooth >= 5
|
||||||
|
|
||||||
|
# angle of half of a single tooth
|
||||||
|
theta = math.pi / n_tooth
|
||||||
|
|
||||||
|
# Generate a tooth by lofting between two curves
|
||||||
|
|
||||||
|
inner_raise = (tooth_height - tooth_height_inner) / 2
|
||||||
|
# Outer tooth triangle spans a curve of length `2 pi r / n_tooth`. This
|
||||||
|
# creates the side profile (looking radially inwards) of each of the
|
||||||
|
# triangles.
|
||||||
|
outer = [
|
||||||
|
(radius * math.tan(theta), 0),
|
||||||
|
(0, tooth_height),
|
||||||
|
(-radius * math.tan(theta), 0),
|
||||||
|
]
|
||||||
|
inner = [
|
||||||
|
(radius_inner * math.sin(theta), 0),
|
||||||
|
(radius_inner * math.sin(theta), inner_raise - tooth_height_inner / 2),
|
||||||
|
(0, inner_raise + tooth_height_inner / 2),
|
||||||
|
(-radius_inner * math.sin(theta), inner_raise - tooth_height_inner / 2),
|
||||||
|
(-radius_inner * math.sin(theta), 0),
|
||||||
|
]
|
||||||
|
tooth = (
|
||||||
|
Cq.Workplane('YZ')
|
||||||
|
.polyline(inner)
|
||||||
|
.close()
|
||||||
|
.workplane(offset=radius - radius_inner)
|
||||||
|
.polyline(outer)
|
||||||
|
.close()
|
||||||
|
.loft(combine=True)
|
||||||
|
.val()
|
||||||
|
)
|
||||||
|
tooth_centre_radius = radius_inner * math.cos(theta)
|
||||||
|
teeth = (
|
||||||
|
Cq.Workplane('XY')
|
||||||
|
.polarArray(radius=radius_inner, startAngle=0, angle=360, count=n_tooth)
|
||||||
|
.eachpoint(lambda loc: tooth.located(loc))
|
||||||
|
.intersect(Cq.Solid.makeCylinder(
|
||||||
|
height=base_height + tooth_height,
|
||||||
|
radius=radius,
|
||||||
|
))
|
||||||
|
)
|
||||||
|
base = (
|
||||||
|
Cq.Workplane('XY')
|
||||||
|
.cylinder(
|
||||||
|
height=base_height,
|
||||||
|
radius=radius,
|
||||||
|
centered=(True, True, False))
|
||||||
|
.faces(">Z").tag("bore")
|
||||||
|
.union(teeth.val().move(Cq.Location((0,0,base_height))))
|
||||||
|
.clean()
|
||||||
|
)
|
||||||
|
#base.workplane(offset=tooth_height/2).circle(radius=radius,forConstruction=True).tag("mate")
|
||||||
|
base.polyline([(0, 0, 0), (0, 0, 1)], forConstruction=True).tag("mate")
|
||||||
|
return base
|
||||||
|
|
||||||
|
def hirth_assembly():
|
||||||
|
"""
|
||||||
|
Example assembly of two Hirth joints
|
||||||
|
"""
|
||||||
|
rotate = 180 / 16
|
||||||
|
obj1 = hirth_joint().faces(tag="bore").cboreHole(
|
||||||
|
diameter=10,
|
||||||
|
cboreDiameter=20,
|
||||||
|
cboreDepth=3)
|
||||||
|
obj2 = (
|
||||||
|
hirth_joint()
|
||||||
|
.rotate(
|
||||||
|
axisStartPoint=(0,0,0),
|
||||||
|
axisEndPoint=(0,0,1),
|
||||||
|
angleDegrees=rotate
|
||||||
|
)
|
||||||
|
)
|
||||||
|
result = (
|
||||||
|
Cq.Assembly()
|
||||||
|
.add(obj1, name="obj1", color=Cq.Color(0.8,0.8,0.5,0.3))
|
||||||
|
.add(obj2, name="obj2", color=Cq.Color(0.5,0.5,0.5,0.3), loc=Cq.Location((0,0,80)))
|
||||||
|
.constrain("obj1?mate", "obj2?mate", "Axis")
|
||||||
|
.solve()
|
||||||
|
)
|
||||||
|
return result
|
||||||
|
|
||||||
|
class TestJoints(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_hirth_assembly(self):
|
||||||
|
print(Cq.__version__)
|
||||||
|
hirth_assembly()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
|
@ -0,0 +1,14 @@
|
||||||
|
#+title: Cosplay: Houjuu Nue
|
||||||
|
|
||||||
|
* Controller
|
||||||
|
|
||||||
|
This part describes the electrical connections and the microcontroller code.
|
||||||
|
|
||||||
|
* Structure
|
||||||
|
|
||||||
|
This part describes the 3d printed and laser cut structures. ~structure.blend~
|
||||||
|
is an overall sketch of the shapes and looks of the wing.
|
||||||
|
|
||||||
|
* Pattern
|
||||||
|
|
||||||
|
This part describes the sewing patterns.
|
|
@ -0,0 +1,17 @@
|
||||||
|
import cadquery as Cq
|
||||||
|
|
||||||
|
def mystery():
|
||||||
|
return (
|
||||||
|
Cq.Workplane()
|
||||||
|
.box(1, 1, 1)
|
||||||
|
.tag("base")
|
||||||
|
.wires(">Z")
|
||||||
|
.toPending()
|
||||||
|
.translate((0.1, 0.1, 1.0))
|
||||||
|
.toPending()
|
||||||
|
.loft()
|
||||||
|
.faces(">>X", tag="base")
|
||||||
|
.workplane(centerOption="CenterOfMass")
|
||||||
|
.circle(0.2)
|
||||||
|
.extrude(3)
|
||||||
|
)
|
|
@ -0,0 +1,68 @@
|
||||||
|
#include <FastLED.h>
|
||||||
|
|
||||||
|
// Main LED strip setup
|
||||||
|
#define LED_PIN 5
|
||||||
|
#define NUM_LEDS 100
|
||||||
|
#define LED_PART 50
|
||||||
|
#define BRIGHTNESS 250
|
||||||
|
#define LED_TYPE WS2811
|
||||||
|
CRGB leds[NUM_LEDS];
|
||||||
|
|
||||||
|
CRGB color_red;
|
||||||
|
CRGB color_blue;
|
||||||
|
CRGB color_green;
|
||||||
|
|
||||||
|
#define DIAG_PIN 6
|
||||||
|
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
// Calculate colors
|
||||||
|
hsv2rgb_spectrum(CHSV(4, 255, 100), color_red);
|
||||||
|
hsv2rgb_spectrum(CHSV(170, 255, 100), color_blue);
|
||||||
|
hsv2rgb_spectrum(CHSV(90, 255, 100), color_green);
|
||||||
|
pinMode(LED_BUILTIN, OUTPUT);
|
||||||
|
pinMode(LED_PIN, OUTPUT);
|
||||||
|
pinMode(DIAG_PIN, OUTPUT);
|
||||||
|
|
||||||
|
// Main LED strip
|
||||||
|
FastLED.addLeds<LED_TYPE, LED_PIN, RGB>(leds, NUM_LEDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
fill_segmented(CRGB::Green, CRGB::Orange);
|
||||||
|
delay(500);
|
||||||
|
|
||||||
|
flash(leds, NUM_LEDS, color_red, 10, 20);
|
||||||
|
delay(500);
|
||||||
|
flash(leds, NUM_LEDS, color_blue, 10, 20);
|
||||||
|
delay(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fill_segmented(CRGB c1, CRGB c2)
|
||||||
|
{
|
||||||
|
//fill_solid(leds, LED_PART, c1);
|
||||||
|
fill_gradient_RGB(leds, LED_PART, CRGB::Black ,c1);
|
||||||
|
fill_gradient_RGB(leds + LED_PART, NUM_LEDS - LED_PART, CRGB::Black, c2);
|
||||||
|
FastLED.show();
|
||||||
|
}
|
||||||
|
void flash(CRGB *ptr, uint16_t num, CRGB const& lead, int steps, int step_time)
|
||||||
|
{
|
||||||
|
digitalWrite(LED_BUILTIN, LOW);
|
||||||
|
|
||||||
|
//fill_solid(leds, NUM_LEDS, CRGB::Black);
|
||||||
|
for (int i = 0; i < steps; ++i)
|
||||||
|
{
|
||||||
|
uint8_t factor = 255 * i / steps;
|
||||||
|
analogWrite(DIAG_PIN, factor);
|
||||||
|
CRGB tail = blend(lead, CRGB::Black, factor);
|
||||||
|
uint16_t front = factor * (int) num / 255;
|
||||||
|
fill_solid(ptr, front, tail);
|
||||||
|
//fill_gradient_RGB(ptr, front, tail, lead);
|
||||||
|
//fill_solid(leds + front, NUM_LEDS - front, CRGB::Black);
|
||||||
|
FastLED.show();
|
||||||
|
delay(step_time);
|
||||||
|
}
|
||||||
|
fill_gradient_RGB(ptr, num, CRGB::Black, lead);
|
||||||
|
FastLED.show();
|
||||||
|
analogWrite(DIAG_PIN, LOW);
|
||||||
|
}
|
Loading…
Reference in New Issue