Read time: 10.7 minutes (1074 words)
Wing Design¶
I decided to make this wing fairly simple. Basically it uses a constant chord with rounded tips. The wing uses a conventional flat center section, with the tips raised to provide the needed stability. Here is the general layout:
The center section is a simple rectangular structure with a constant chord. The span of this section is a design decision. Setting this dimension will have an effect on the span of the tips, since the total projected wing span is fixed by the rule constraints. I decoded to set up the dimensions for the center section in a data file that will be placed in a wing subdirectory under the main design directory
1//#####################################
2// wing.data
3// (c) 2021 by Roie R. Black
4//=====================================
5include <../constraints.scad>
6
7// center section dimensions
8center_span = 12;
9spar_size = 1/16;
10rib_chord = max_wing_chord - 2 * spar_size;
11rib_camber = 4;
12num_center_ribs = 5;
13
14// tip section dimensions
15tip_dihedral = 1.75;
16tip_radius = 2;
17a = tip_dihedral;
18b = (max_projected_wing_span - center_span)/2;
19tip_span = sqrt(a*a + b*b);
20tip_dihedral_angle = atan2(a,b);
21tip_le_span = tip_span - tip_radius;
22tip_rib_chord = max_wing_chord - tip_radius - spar_size;
Notice that we include the constraints.data file so we can refer to constants defined there. The path to that file shows that it is in the directory above the wing directory (the main design directory).
For reference, here are the named constants we are using and the symbols from the figure above:
constant |
figure |
---|---|
center_span |
\(2 * y_t\) |
chord |
\(c\) |
tip_radius |
\(r_t\) |
Wing Ribs¶
I decided to use a simple circular arc airfoil for this design. The arc is defined by specifying the camber as a percentage of the chord. Figuring out the actual arc radius involves a bit of math, byyt a nice Python tool called SymPy makes this pretty easy (see the appendix for details). The formula for the arc is given below:
Where \(c\) is the airfoil chord, and \(t\) is the thickness. This last value is simply calculated form the chord and camber (\(T\)):
There are two ways to build this rib. One way involves bending a strip of wood over a form to produce the rib. The second way uses a template to cut the rib out of sheet stock. In the first case, there is a problem you might not notice in building a real airplane. Suppose you want to make the front and rear spars out of simple square stock, and you want to mage the rib using the same size as the spars. If you slice off the arc at the leading and trailing edges, the height of the rib at both points is actually larger than the spar sizes. This is easy to see using OpenSCAD, which led me to use the template approach.
If you use a template, the arc is used to make a first cut, then the template is slid down by the spar size and a second cut produces a rib with exactly the right height on both ends. The problem is finding a way to create this rib using OpenSCAD code.
Template Rib Library Module¶
I ended up using the linear extrude feature of OpenSCAD to create a general rib shape. This OpenSCAD module is our first library module. The parameters of this module allow us to create ribs as needed for any design.
The outline of the rib is a 2D figure produced using the above formulas to calculate the radius of the arc we need. The outline is formed by creating two circles, shifted by the height of the rib. These circles are trimmed using 2D square shapes. Finally the outline is extruded to generate the 3D rib.
1//####################################
2// rib.scad - circle template rib
3// (c) 2021 by Roie R. Black
4//====================================
5$fn=360;
6module circle_template_rib(chord,camber,height,thickness) {
7
8 // calculate the radius for this arc
9 camber = chord * camber / 100;
10 radius = (chord * chord) / (8 * camber) + camber/2;
11 // generate the rib
12 translate([0,thickness/2,0])
13 rotate([90,0,0])
14 linear_extrude(height = thickness) {
15 intersection() {
16 difference() {
17 square([chord,1]);
18 translate([chord/2, -radius + camber]) circle(r=radius);
19 }
20 translate([chord/2, -radius + camber + height]) circle(r=radius);
21 }
22 }
23}
24//====================================
25// display this shape
26
27circle_template_rib(5,4,1/16,1/32);
28
29
This is a bit scary on first look, but line by line it should make sense. The OpenSCAD module is a reusable chunk of code we will need when generating our actual ribs. The parameters we need to supply are these:
chord - the trimmed length of the rib (not including the spars)
camber - the thickness as a percentage of the chord
height - basically the height of the leading and trailing edge spars
thickness - the thickness of the sheet we will use to form the ribs
Notice that there is code after the module8 definition that serves to display the shape if we load this *library module file in OpenSCAD. This code will not be run when we generate actual ribs using this module. This technique is handy when debugging code.
It is important to note the position of the rib in the coordinate system. The origin of this system is sitting in the center of the leading edge, with the bottom of thr rib sitting on the X-Y plane. The rib is oriented so the Z is “up”. The Z axis runs through the center of the rib. We will need this information when we place ribs in the actual design.
Generating Wing Ribs¶
Now, we can create a rib module for wing ribs. All we need to do here is set the correct values for the parameters:
1//###################################################
2// rib.scad
3// (c) 2021 - Roie R. Black
4//***************************************************
5include <../../wing_data.scad>
6
7use <MMlib/circle_template_rib.scad>
8
9module rib() {
10 circle_template_rib(rib_chord, rib_camber, spar_size, spar_size);
11}
12
13rib();
14
We will use five of these ribs, each properly positioned to form the wing center section.
Here is the basic rib shape, ready for placement in the wing:
Leading and Trailing Edges¶
The leading and trailing edge spars are something of a letdown! They are simple square spars of a defined length. Again, it is handy to generate a library module for a basic square spar.
1//####################################
2// square_spar.scad
3// (c) 2021 by Roie R. Black
4//====================================
5
6
7module square_spar(length=6,size=1/16) {
8 translate([size/2, 0, size/2])
9 cube([size,length,size], center=true);
10}
11
12square_spar(6,1/16);
The spars created using this module are centered along the Y axis, again sitting on the X-Y plane. This will be convenient for assembling the wing center section.
Assembling the Center Section¶
We have defined the parts needed to build the center section frame. All we need to do is place the parts in the right positions. We will let OpenSCAD do the calculations needed for this step.
We need to decide how to organize these parts before building this section. WHile it is possible to do this all in one file, doing the analytical work to predict the weight and balance data will be more difficult if we do that. Instead, I decided to create directories for each part, and set up placement data files that control where each part sits in the final model. Although this creates a lot of directories, it keeps things more organized as we generate additional files during the analysis phase.
For the wing center section, we will need eight new direcroties, five for the ribs, one each for leading and trailing edges, and a final one for the covering.
The ribs and spars are created using our library modulae. We will add a placement data file in each part directoriy that defines exactly where the part sits in the assembly we are creating.
Note
This plaement is not where the part sits in the final model. We will move assemblies into place as we build the final model.
Let’s look at the rib at the left side (pilot’s view”) of the center section.
1//#####################################
2// center.scad
3// (c) 2021 by Roie R. Black
4//=====================================
5include <colors.scad>
6include <./center_pos.scad>
7
8use <MMlib/position.scad>
9use <./spar/spar.scad>
10use <./rib/rib.scad>
11use <./covering/covering.scad>
12
13module center() {
14 color(WOOD_Balsa) {
15 align(le_pos) spar();
16 align(rib1_pos) rib();
17 align(rib2_pos) rib();
18 align(rib3_pos) rib();
19 align(rib4_pos) rib();
20 align(rib5_pos) rib();
21 align(te_pos) spar();
22 }
23 align(covering_pos) covering();
24}
25
26
27//====================================
28// display this shape
29center();
Note
This code is set up to color the material. The colors.scad file containg a number of useful color definitions was found on the Internet, and I added a color for Balsa. The eliminates the ugly green color that is generated by default when OpenSCAD creates images.