Nike Ajax CAD Model Build

Discussion in 'Scale' started by vcp, Apr 28, 2019.

Help Support The Rocketry Forum by donating:

  1. Apr 28, 2019 #1

    vcp

    vcp

    vcp

    Well-Known Member

    Joined:
    Jan 28, 2009
    Messages:
    908
    Likes Received:
    83
    Location:
    Boise, ID
    Yes, I never have finished my Nike Hercule CAD Model Build, but I'm easily sidetracked. Had an urge to look at the Nike Ajax, and I'm pretty happy with how it's going so far...

    Nike_Ajax 16.jpg
    Nike_Ajax_16.JPG

    I'll be able to re-use much of the Nike motor that I had finished for the Hercules.

    Really pleased with the way the tunnels came out. The only complex item left to do is the interstage. It was interesting to find out, that according to the Bennett drawing, the tunnels are different sizes.
     
    Last edited: Apr 28, 2019
  2. Apr 28, 2019 #2

    vcp

    vcp

    vcp

    Well-Known Member

    Joined:
    Jan 28, 2009
    Messages:
    908
    Likes Received:
    83
    Location:
    Boise, ID
  3. Apr 29, 2019 #3

    vcp

    vcp

    vcp

    Well-Known Member

    Joined:
    Jan 28, 2009
    Messages:
    908
    Likes Received:
    83
    Location:
    Boise, ID
    Only the interstage left to do, plus the bolt heads and rivets and whatever other (usually invisible) details I want to add. Ah, and the scale launch lugs.

    Nike_Ajax2.JPG
     
  4. Apr 29, 2019 #4

    Bruiser

    Bruiser

    Bruiser

    Well-Known Member

    Joined:
    Jun 7, 2018
    Messages:
    578
    Likes Received:
    97
    This is interesting. What size is it? Is it being designed as a two stage?

    -Bob
     
  5. Apr 29, 2019 #5

    vcp

    vcp

    vcp

    Well-Known Member

    Joined:
    Jan 28, 2009
    Messages:
    908
    Likes Received:
    83
    Location:
    Boise, ID
    Not many actual dimensions for the interstage, so it's largely photo interpretation, but it looks about right. A little trimming to do, and still those launch lugs.
    interstage.JPG
     
  6. Apr 29, 2019 #6

    vcp

    vcp

    vcp

    Well-Known Member

    Joined:
    Jan 28, 2009
    Messages:
    908
    Likes Received:
    83
    Location:
    Boise, ID
    Right now it's just being done as an exact scale model, with no consideration for internal requirements for flight. I can slice that out later as required. It's being drawn as 1mm = 1in, so that's 1/25.4, but it can easily be scaled to anything. My thoughts at the moment are to print the booster fin unit, use a BT60 for the Nike tube, making it 1/10 scale, and then print the upper stage entirely. The problem of any Nike-Ajax model is the fragility of the interstage, which makes 2-stage even more of a problem. The interstage is rarely done with much fidelity, but for a practical model, it almost certainly needs to be beefed up. I'll eventually get around to printing to see what it's like.
     
  7. Apr 29, 2019 #7

    Bruiser

    Bruiser

    Bruiser

    Well-Known Member

    Joined:
    Jun 7, 2018
    Messages:
    578
    Likes Received:
    97
    BT60 for the booster would make it 1/10th scale which is the scale I am trying to stick to. I'll be following along with your build with great interest. I'd love to get a printed fin can. This is a rocket I am going to model one day. I have a couple of single stage Nike rockets. For two stage rockets my Nike-Tomahawk and Nike-Nike Smoke are being build now. They are on hold while I figure out how I'm going to stage them. I also have the basic parts to build the kit for a Terrier-Nike. The Ajax and Hercules are on my to do list.

    -Bob
     
  8. Apr 29, 2019 #8

    Leo

    Leo

    Leo

    Well-Known Member

    Joined:
    Aug 19, 2009
    Messages:
    1,761
    Likes Received:
    41
    Gender:
    Male
    Location:
    Germany
    Looking good Gary. This would be a great rocket made with a 3D printer.
     
  9. Apr 29, 2019 #9

    aerostadt

    aerostadt

    aerostadt

    Lifetime Supporter TRF Lifetime Supporter

    Joined:
    Oct 27, 2009
    Messages:
    2,855
    Likes Received:
    73
    Gender:
    Male
    Location:
    Brigham City, UT
    I still have The Launch Pad Nike-Ajax. I haven't flown it in many years, but it is still flyable. It is only one-stage using a cluster of three D12-3's. I believe it was Chuck Brandt the owner of the The Launch Pad made a non-production two-stage version years ago.
     
  10. Apr 30, 2019 #10

    vcp

    vcp

    vcp

    Well-Known Member

    Joined:
    Jan 28, 2009
    Messages:
    908
    Likes Received:
    83
    Location:
    Boise, ID
    I've often mentioned that to my eternal shame, I haven't been using a 'real' CAD system, but rather the freeware OpenSCAD. It's just been something that I've always turned to. For some people, the logic of 'programming' an object in code just seems to click. Maybe it's just me. Perhaps to explain the madness, I thought I'd go through an example of how I create an object in OpenSCAD code. If you want to follow along, you should be able to take the code segments below, and drop them into the OpenSCAD editor window. OpenSCAD is available here, and is trivially simple to install. Pressing F5 (preview) should get a view that looks like the pictures below. (Be sure and get the axes pointed around as I have them, so that x extends to the left.)

    Notice that a command line is always terminated by a semicolon. A command line can consist of a series of commands that extend over more than one line on the page. Anything on a line following a '//' is a comment that does not affect the code.

    The following dimensions are first defined in the code. All are taken from the section of the Bennett Nike-Ajax drawing below, or from the Alway drawing. I try to identify the source of all the dimensions used. (TLAR = That Looks About Right - sometimes we have to take a best guess.) Note that the basic measurement unit in OpenSCAD is mm, and all of the following dimensions are in inches. I don't bother to convert, but rather just enter the inch dimensions, which gives me a drawing that is actually 1/25.4 scale. It's not a problem, I can easily scale it to whatever I need later.

    Body_Diameter = 12; // Bennett
    Main_Fin_Span = 18.95; // not including aileron - Bennett 18 61/64
    Main_Fin_Root = 70.234; // not including aileron - Bennett 70 15/64
    Main_Fin_Edge_Diameter = 0.679; // Bennett
    Center_Panel_Thickness = 1.929; // Bennett
    Aileron_Width = 1.5; // Alway
    Aileron_TE_Diameter = 0.25; // TLAR
    Aileron_Body_Standoff = 0.34; // TLAR
    Rear_Panel_Root = 15.188; // Bennett 15 3/16
    Rear_Mid_Panel_Root = 30.938; // Bennett 30 15/16
    Center_Panel_Root = Rear_Mid_Panel_Root - Rear_Panel_Root;
    Front_Panel_Root = Main_Fin_Root - Rear_Mid_Panel_Root;

    Bennett - Main Fin.JPG


    Starting really simple, I'll place a sphere at the origin. It's the diameter of the edge of the fin. The $fn factor just sets the coarseness of the sphere:

    sphere (d = Main_Fin_Edge_Diameter, $fn = 20);

    Now, I don't want that exactly on the origin, because I want the trailing edge of the fin to just touch the z-axis, so I'll move it (translate) one-half of its diameter to the left - in the x-direction. I'll be building the fin with its root on the x-axis. The translate command takes the form of: translate ([x, y, z]) It translates the object that follows it in the command line.

    translate ([Main_Fin_Edge_Diameter/2 , 0, 0])
    sphere (d = Main_Fin_Edge_Diameter, $fn = 20);

    Then I'll do the same thing, placing a sphere at the trailing edge tip of the fin, so that the trailing edge will be on the z-axis

    translate ([Main_Fin_Edge_Diameter/2 , 0, Main_Fin_Span - Main_Fin_Edge_Diameter/2])
    sphere (d = Main_Fin_Edge_Diameter, $fn = 20);

    Same deal, another sphere at the forward tip of the fin:

    translate ([Main_Fin_Root - Main_Fin_Edge_Diameter/2, 0, 0])
    sphere (d = Main_Fin_Edge_Diameter, $fn = 20);

    So with the three spheres placed, it looks like this:

    spheres.JPG

    And now, the magic of the hull command. I use hull a lot, probably more than I should. Yes, you could define the fin with a polygon, but, at least in OpenSCAD, it's so easy to just translate the points around and then hull them. The hull command just acts upon everything that follows it within curly brackets {...}, and creates a surface connecting all the objects.

    hull () {
    translate ([Main_Fin_Edge_Diameter/2 , 0, 0])
    sphere (d = Main_Fin_Edge_Diameter, $fn = 20);
    translate ([Main_Fin_Edge_Diameter/2 , 0, Main_Fin_Span - Main_Fin_Edge_Diameter/2])
    sphere (d = Main_Fin_Edge_Diameter, $fn = 20);
    translate ([Main_Fin_Root - Main_Fin_Edge_Diameter/2, 0, 0])
    sphere (d = Main_Fin_Edge_Diameter, $fn = 20);
    } // end hull

    ...and you get a fin:

    flat fin.JPG

    But it's a flat fin, just the thickness of the edge. The Ajax fin has a center panel that is thicker. To fix that, we'll add another object, this time a cylinder. A cylinder is just defined by its height and diameter, h and d. The cylinder command alone would give a cylinder standing vertically at the origin. I'll use the rotate command to rotate it 90 degrees left around the y-axis, so that it's laying horizontally on the x-axis. Then use the translate command to move it along the x-axis, to where the center panel is, and move it on the y-axis so that it is at the thickness of the panel.

    translate ([Rear_Panel_Root, (Center_Panel_Thickness - Main_Fin_Edge_Diameter)/2, 0])
    rotate (a = [0, 90, 0])
    cylinder (h = Center_Panel_Root, d = Main_Fin_Edge_Diameter, $fn = 20);

    Which looks like this:

    flat center.JPG

    I'll add a similar cylinder to the other side, and place them both within the hull command so that now all of the code is:

    hull () { // Main Fin
    // center root panel
    translate ([Rear_Panel_Root, (Center_Panel_Thickness - Main_Fin_Edge_Diameter)/2, 0])
    rotate (a = [0, 90, 0])
    cylinder (h = Center_Panel_Root, d = Main_Fin_Edge_Diameter, $fn = 20);
    translate ([Rear_Panel_Root, -(Center_Panel_Thickness - Main_Fin_Edge_Diameter)/2, 0])
    rotate (a = [0, 90, 0])
    cylinder (h = Center_Panel_Root, d = Main_Fin_Edge_Diameter, $fn = 20);

    // forward tip
    translate ([Main_Fin_Root - Main_Fin_Edge_Diameter/2, 0, 0])
    sphere (d = Main_Fin_Edge_Diameter, $fn = 20);

    // trailing edge
    translate ([Main_Fin_Edge_Diameter/2 , 0, Main_Fin_Span - Main_Fin_Edge_Diameter/2])
    sphere (d = Main_Fin_Edge_Diameter, $fn = 20);
    translate ([Main_Fin_Edge_Diameter/2 , 0, 0])
    sphere (d = Main_Fin_Edge_Diameter, $fn = 20);
    } // end hull

    And we have a 3-D fin:

    3d fin.JPG

    In the same manner, I'm going to use four spheres to define the aileron on the trailing edge. It tapers in thickness, so I'm using two different sizes of spheres. The root of the aileron is spaced off the body a bit so the root spheres are translated a small bit upwards.

    hull () { // aileron
    // leading edge
    translate ([-Main_Fin_Edge_Diameter/2 , 0, Aileron_Body_Standoff])
    sphere (d = Main_Fin_Edge_Diameter, $fn = 20);
    translate ([-Main_Fin_Edge_Diameter/2 , 0, Main_Fin_Span - Main_Fin_Edge_Diameter/2 + 0.1])
    sphere (d = Main_Fin_Edge_Diameter, $fn = 20);

    // trailing edge
    translate ([-Main_Fin_Edge_Diameter/2 - Aileron_Width, 0, -0.16 + Aileron_Body_Standoff])
    sphere (d = Aileron_TE_Diameter, $fn = 20);
    translate ([-Main_Fin_Edge_Diameter/2 - Aileron_Width, 0, Main_Fin_Span - Main_Fin_Edge_Diameter/2 + 0.7])
    sphere (d = Aileron_TE_Diameter, $fn = 20);
    } // end hull

    If you look closely at that you'll notice the unexplained numbers: 0.1 , -0.16 , 0.7 . Yes, you caught me. Those are fudge factors. The 0.7 translates one sphere upwards so that the edge of the aileron is in line with the leading edge of the main fin. This is undimensioned on the drawings, so I've placed it by eye, nudging the sphere into place. The other numbers adjust the bottom edge of the aileron.

    continued...

     

    Attached Files:

  11. Apr 30, 2019 #11

    vcp

    vcp

    vcp

    Well-Known Member

    Joined:
    Jan 28, 2009
    Messages:
    908
    Likes Received:
    83
    Location:
    Boise, ID
    ...continued from previous post

    There's only one major thing left to do. The root edge of the fin is not flat - it extends below the horizontal plane by half the diameter of the spheres and cylinders that were used to define it. We'd like to slice it off flat, or better, make it curved to match the body that it will mate with. Enter the difference command. We want to subract away all of the fin that extends into where the missile body will be.

    The difference command takes the first object, in this case, everything within the hull command, and subtracts every object that follows. The object being subtracted is a cylinder that is the diameter of the rocket body, rotated so that it lays along the x-axis, and translated downwards by half its diameter so that the surface of the tube is right along the root edge of the fin.

    difference() {
    hull () { // Main Fin


    //*** all of the stuff above ***

    } // end hull

    translate ([0, 0, -Body_Diameter/2]) rotate (a = [0, 90, 0])
    #cylinder (h = 3*Main_Fin_Root, d = Body_Diameter, $fn = 120);

    } // end difference


    The '#' in front of the cylinder command makes that object visible - since it's an object being subtracted, i.e., a 'negative object', it would otherwise not be visible.

    subtract tube.JPG

    So here is the entirety of the code, all together. You'll notice the addition of 'module' in the first line. This makes everything that follows it in curly brackets a single code module, that can be called in later blocks of code. I'll later want to place four of these fins, and move them around as necessary, so I can do that just by calling this module. I've made that module call in the last line of the code below, which was necessary to get the fin to display once, during this development. You can take the code below, drop it into the OpenSCAD editor window, press F5 to get a preview, and it should display the fin. I encourage you do give it a try and play with it a bit - the easiest way to learn.

    module Main_Fin () {
    Body_Diameter = 12; // Bennett
    Main_Fin_Span = 18.95; // not including aileron - Bennett 18 61/64
    Main_Fin_Root = 70.234; // not including aileron - Bennett 70 15/64
    Main_Fin_Edge_Diameter = 0.679; // Bennett
    Center_Panel_Thickness = 1.929; // Bennett
    Aileron_Width = 1.5; // Alway
    Aileron_TE_Diameter = 0.25; // TLAR
    Aileron_Body_Standoff = 0.34; // TLAR
    Rear_Panel_Root = 15.188; // Bennett 15 3/16
    Rear_Mid_Panel_Root = 30.938; // Bennett 30 15/16
    Center_Panel_Root = Rear_Mid_Panel_Root - Rear_Panel_Root;
    Front_Panel_Root = Main_Fin_Root - Rear_Mid_Panel_Root;

    difference() {
    hull () { // Main Fin
    // center root panel
    translate ([Rear_Panel_Root, (Center_Panel_Thickness - Main_Fin_Edge_Diameter)/2, 0])
    rotate (a = [0, 90, 0])
    cylinder (h = Center_Panel_Root, d = Main_Fin_Edge_Diameter, $fn = 20);
    translate ([Rear_Panel_Root, -(Center_Panel_Thickness - Main_Fin_Edge_Diameter)/2, 0])
    rotate (a = [0, 90, 0])
    cylinder (h = Center_Panel_Root, d = Main_Fin_Edge_Diameter, $fn = 20);

    // forward tip
    translate ([Main_Fin_Root - Main_Fin_Edge_Diameter/2, 0, 0])
    sphere (d = Main_Fin_Edge_Diameter, $fn = 20);

    // trailing edge
    translate ([Main_Fin_Edge_Diameter/2 , 0, Main_Fin_Span - Main_Fin_Edge_Diameter/2])
    sphere (d = Main_Fin_Edge_Diameter, $fn = 20);
    translate ([Main_Fin_Edge_Diameter/2 , 0, 0])
    sphere (d = Main_Fin_Edge_Diameter, $fn = 20);
    } // hull
    #translate ([0, 0, -Body_Diameter/2]) rotate (a = [0, 90, 0])
    cylinder (h = 2*Main_Fin_Root, d = Body_Diameter, $fn = 120);
    } // difference

    hull () { // aileron
    // leading edge
    translate ([-Main_Fin_Edge_Diameter/2 , 0, Aileron_Body_Standoff])
    sphere (d = Main_Fin_Edge_Diameter, $fn = 20);
    translate ([-Main_Fin_Edge_Diameter/2 , 0, Main_Fin_Span - Main_Fin_Edge_Diameter/2 +0.1])
    sphere (d = Main_Fin_Edge_Diameter, $fn = 20);

    // trailing edge
    translate ([-Main_Fin_Edge_Diameter/2 - Aileron_Width, 0, -0.16 + Aileron_Body_Standoff])
    sphere (d = Aileron_TE_Diameter, $fn = 20);
    translate ([-Main_Fin_Edge_Diameter/2 - Aileron_Width, 0, Main_Fin_Span - Main_Fin_Edge_Diameter/2 + 0.7])
    sphere (d = Aileron_TE_Diameter, $fn = 20);
    }
    } // end module Main Fin

    Main_Fin (); // module call


    Just delete the '#' in the code above and you will see the final trimmed fin:
    final fin.JPG

    Any questions? Do you want to know more...?

    edit: Dang, TRF posting removed all of the indentations that would have helped make the above code readable, oh well.
     
    Last edited: Apr 30, 2019
  12. Apr 30, 2019 #12

    manixFan

    manixFan

    manixFan

    Well-Known Member

    Joined:
    Feb 15, 2009
    Messages:
    1,137
    Likes Received:
    198
    Wow, great post - tons of great OpenSCAD info here. Just so you know, when I clicked the reply button on your post, all the formatting is still there, it’s just not being displayed (here's a sample);

    Code:
    difference() {
         hull () { // Main Fin
    
              //*** all of the stuff above ***
    
         } // end hull
    
         translate ([0, 0, -Body_Diameter/2]) rotate (a = [0, 90, 0])
              #cylinder (h = 3*Main_Fin_Root, d = Body_Diameter, $fn = 120);
    
    } // end difference 
    To keep the formatting in a post, try using the 'insert code' option (the insert button is to the left of camera button). It keeps all the indenting. All I did above is simply copy a sample of your prior post and paste it into the code dialog box. Maybe you can ask a mod for permission to edit your prior posts and you can quickly fix the formatting by just copying and pasting into code boxes.

    Thanks for all the great code, keep it coming!


    Tony
     
    Last edited: Apr 30, 2019
  13. Apr 30, 2019 #13

    caveduck

    caveduck

    caveduck

    semi old rocketeer

    Joined:
    Jun 6, 2011
    Messages:
    1,189
    Likes Received:
    54
    Nice stuff Gary!! I think 3D modeling is the likely future of scale model documentation.
     
  14. Apr 30, 2019 #14

    Glasspack

    Glasspack

    Glasspack

    Lifetime Supporter TRF Lifetime Supporter

    Joined:
    Oct 2, 2011
    Messages:
    431
    Likes Received:
    47
    Gary,

    I happen to live right down the street from a Nike Ajax in the Air and Space museum...…..



    . 20170826_155757.jpg

    Be happy to help.... if you need anything measured or pictures let me know..... Its my favorite missile.
    Always have plans to build a model of one day ! Maybe start my "Launch Pad" kit soon....

    Paul
     
  15. Apr 30, 2019 #15

    vcp

    vcp

    vcp

    Well-Known Member

    Joined:
    Jan 28, 2009
    Messages:
    908
    Likes Received:
    83
    Location:
    Boise, ID
    That's the South Dakota museum right? I was stationed at Ellsworth in the '70's. I was asleep a block and a half away from the total washout of the Rapid City flood.

    That's a beautiful example of an Ajax. Might take you up on that offer. I recall that there's an AGM-28 Hound Dog there too that looks really nice. That's always been tempting. BTW I've scraped your picture for my collection.

    All of my Nike Ajax data is here, in a dropbox folder. No guarantees that link won't change, I'm still organizing things there. Any additions are welcome.
     
  16. Apr 30, 2019 #16

    vcp

    vcp

    vcp

    Well-Known Member

    Joined:
    Jan 28, 2009
    Messages:
    908
    Likes Received:
    83
    Location:
    Boise, ID
    Oh wow, I see that now. I would have never guessed that's what it was. Thanks.
     
  17. Apr 30, 2019 #17

    vcp

    vcp

    vcp

    Well-Known Member

    Joined:
    Jan 28, 2009
    Messages:
    908
    Likes Received:
    83
    Location:
    Boise, ID
    Ok, neet. Let's continue with the Ajax sustainer body. I'll leave the nose cone for later. The body consists of three parts: an aft cone, a cylindrical body, and a forward cone. This is easily done with the cylinder and translate commands that I used before.

    First, some dimensions:
    Code:
    Forward_Cone_Forward_Diameter = 5.8;
    Body_Diameter = 12;
    Tail_Diameter = 9; // Alway
    
    Nose_Cone_Length = 14; // Alway
    Forward_Cone_Length = 75.781 - 14.00; // Alway
    Main_Body_Length = 232.625 - 75.781;
    Tail_Cone_Length = 251.00 - 232.625; // Alway
    
    Bottom_Main_Body = Tail_Cone_Length;
    Bottom_Forward_Cone = Bottom_Main_Body + Main_Body_Length;
    Bottom_Nose_Cone = Bottom_Forward_Cone + Forward_Cone_Length;
    
    smooth = 120;
    Two things about those dimensions. First, they are general dimensions that will be used for things other than just the body, so I want them to be global. That means that these variable names will be available in any code module. In the previous Main_Fin module, all of the variables were within the module, so they were local, and available for use only within that module. The second item is the smooth variable. It will be used globally to dictate the smoothness used for most surfaces (the $fn= factor). The time to generate a model is often related to the smoothness selected (especially on a steam-powered computer like mine). Using a lower value of smoothness can speed things up for development, then changing it to a higher value for the final render to make it pretty.

    After those dimensions, we'll make a Main_Body () module, and start with the aft cone:
    Code:
    module Main_Body () {
    
        // aft cone
        cylinder (h = Tail_Cone_Length, d1 = Tail_Diameter, d2 = Body_Diameter, $fn = smooth);
    
    } // end module Main Body
    
    Main_Body ();
    This is the same cylinder command used before, with two differences. First, we want the end of the body model to be sitting vertically at the axis origin, so it's not going to be translated anywhere. Secondly, you'll note a difference with the diameter variable(s). There are two: d1, and d2. Previously, with only one diameter, the command defined a true cylinder. Here with two, it's actually a cone (or a frustum of a cone, to be pedantic). d1 is the bottom diameter, and d2 is the top diameter. Remember also that the last line [ Main_Body (); ], is necessary to call the module and display it (I always forget that). The above stuff will look like this:

    tail cone.JPG

    The rest is simple. Just a translated cylinder for the central body, and a translated cylinder (cone) for the forward cone. The translations this time are in the z-axis, to stack the parts on top of one another. So I'll just finish with the full block of code:
    Code:
    Forward_Cone_Forward_Diameter = 5.8;
    Body_Diameter = 12;
    Tail_Diameter = 9; // Alway
    
    Nose_Cone_Length = 14; // Alway
    Forward_Cone_Length = 75.781 - 14.00; // Alway
    Main_Body_Length = 232.625 - 75.781;
    Tail_Cone_Length = 251.00 - 232.625; // Alway
    
    Bottom_Main_Body = Tail_Cone_Length;
    Bottom_Forward_Cone = Bottom_Main_Body + Main_Body_Length;
    Bottom_Nose_Cone = Bottom_Forward_Cone + Forward_Cone_Length;
    
    smooth = 120;
    
    module Main_Body () {
    
        // tail cone
        cylinder (h = Tail_Cone_Length, d1 = Tail_Diameter, d2 = Body_Diameter, $fn = smooth);
    
        // main body
        translate ([0, 0, Bottom_Main_Body])
            cylinder (h = Main_Body_Length, d = Body_Diameter, $fn = smooth);
    
        // forward cone
        translate ([0, 0, Bottom_Forward_Cone])
            cylinder (h = Forward_Cone_Length, d1 = Body_Diameter, d2 = Forward_Cone_Forward_Diameter, $fn = smooth);
    
    } // end module Main Body
    
    Main_Body ();
    main body.JPG

    Next, we'll place the fins on that body.
     
  18. Apr 30, 2019 #18

    vcp

    vcp

    vcp

    Well-Known Member

    Joined:
    Jan 28, 2009
    Messages:
    908
    Likes Received:
    83
    Location:
    Boise, ID
    Simple navigation in the OpenSCAD drawing window:

    mouse left button hold and drag to rotate around axes
    mouse right button hold and drag to translate
    scroll wheel to zoom in and out

    If you lose track of something, in the View menu, there are handy commands to view top/bottom/left/right/front/back/diagonal/center/all.
     
    Last edited: Apr 30, 2019
  19. Apr 30, 2019 #19

    vcp

    vcp

    vcp

    Well-Known Member

    Joined:
    Jan 28, 2009
    Messages:
    908
    Likes Received:
    83
    Location:
    Boise, ID
    Placing the main fins on the Nike-Ajax body.

    First I'm going to make a new module, for the entire Nike-Ajax second stage, and in it, I'm going to call the module for the main fin that we made earlier:
    Code:
    module Nike_Ajax_Sustainer () {
      
        rotate (a = [0, -90, 0]) Main_Fin ();
    
    } // end module Nike Ajax Sustainer
    
    Nike_Ajax_Sustainer ();

    This block of code is placed in the OpenSCAD editor window, in addition to the modules Main_Fin () and Main_Body () and the global variables that we created earlier. You'll notice that it adds a rotate () command that operates on the Main_Fin () module. This rotates the fin 90 degrees around the y-axis, so that the fin is in the same orientation as the body. (Yes, I could have created the fin in this orientation, but at the time I was thinking in the same orientation as the drawing.)

    fin rotated.JPG

    Next, I'll add three things to the module. First is a local variable, Main_Fin_Position, which is the position of the fin measured from the hinge line of the fin to the bottom of the sustainer body. Next is a call to display the Main_Body (). And finally, a translate command to place the rotated fin in its position. Notice that I'm translating in two axes at once; one to move it up, and one to move it out on the x-axis by half the body diameter, so that it's placed on the surface of the body.
    Code:
    module Nike_Ajax_Sustainer () {
        Main_Fin_Position = 252 - 195; // Alway
    
        Main_Body ();
       
        translate ([-Body_Diameter/2, 0, Main_Fin_Position])
            rotate (a = [0, -90, 0]) Main_Fin ();
    
    } // end module Nike Ajax Sustainer
    
    Nike_Ajax_Sustainer ();
    fin and body.JPG

    Almost there, we just need more fins. I'll just call the Main_Fin () module three more times. But I also need to place them radially around the body, so I add another rotate command to do the rotation of each fin around the z-axis. I've rotated all fins an extra 45 degrees so that the zero-degree location can be the upper side of the missile as it sits on the launcher.
    Code:
    module Nike_Ajax_Sustainer () {
        Main_Fin_Position = 252 - 195; // Alway
    
        Main_Body ();
       
        rotate (a = [0, 0, 45]) translate ([-Body_Diameter/2, 0, Main_Fin_Position])
            rotate (a = [0, -90, 0]) Main_Fin ();
        rotate (a = [0, 0, 135]) translate ([-Body_Diameter/2, 0, Main_Fin_Position])
            rotate (a = [0, -90, 0]) Main_Fin ();  
        rotate (a = [0, 0, 225]) translate ([-Body_Diameter/2, 0, Main_Fin_Position])
            rotate (a = [0, -90, 0]) Main_Fin ();  
        rotate (a = [0, 0, 315]) translate ([-Body_Diameter/2, 0, Main_Fin_Position])
            rotate (a = [0, -90, 0]) Main_Fin ();  
    
    } // end module Nike Ajax Sustainer
    
    color ("White") Nike_Ajax_Sustainer ();
    four fins.JPG

    I snuck in one last addition in that final code block. Since the entire Nike-Ajax sustainer is usually white, I added a color command that operates on the whole sustainer module.

    Next, a recap and a shortcut.
     
  20. Apr 30, 2019 #20

    vcp

    vcp

    vcp

    Well-Known Member

    Joined:
    Jan 28, 2009
    Messages:
    908
    Likes Received:
    83
    Location:
    Boise, ID
    Here is the full code as it now stands, with one change that I'll explain below:
    Code:
    // Nike-Ajax model
    
    Forward_Cone_Forward_Diameter = 5.8;
    Body_Diameter = 12;
    Tail_Diameter = 9; // Alway
    
    Nose_Cone_Length = 14; // Alway
    Forward_Cone_Length = 75.781 - 14.00; // Alway
    Main_Body_Length = 232.625 - 75.781;
    Tail_Cone_Length = 251.00 - 232.625; // Alway
    
    Bottom_Main_Body = Tail_Cone_Length;
    Bottom_Forward_Cone = Bottom_Main_Body + Main_Body_Length;
    Bottom_Nose_Cone = Bottom_Forward_Cone + Forward_Cone_Length;
    
    smooth = 120;
    
    module Main_Body () {
    
        // tail cone
        cylinder (h = Tail_Cone_Length, d1 = Tail_Diameter, d2 = Body_Diameter, $fn = smooth);
    
        // main body
        translate ([0, 0, Bottom_Main_Body])
            cylinder (h = Main_Body_Length, d = Body_Diameter, $fn = smooth);
    
        // forward cone  
        translate ([0, 0, Bottom_Forward_Cone])
            cylinder (h = Forward_Cone_Length, d1 = Body_Diameter, d2 = Forward_Cone_Forward_Diameter, $fn = smooth);
    
    } // end module Main Body
    
    //Main_Body ();
    
    
    module Main_Fin () {
        Main_Fin_Span = 18.95; // not including aileron - Bennett 18 61/64
        Main_Fin_Root = 70.234; // not including aileron - Bennett 70 15/64
        Main_Fin_Edge_Diameter = 0.679; // Bennett
        Center_Panel_Thickness = 1.929; // Bennett
        Aileron_Width = 1.5; // Alway
        Aileron_TE_Diameter = 0.25;   // TLAR
        Aileron_Body_Standoff = 0.34; // TLAR
        Rear_Panel_Root = 15.188; // Bennett 15 3/16
        Rear_Mid_Panel_Root = 30.938; // Bennett 30 15/16
        Center_Panel_Root = Rear_Mid_Panel_Root - Rear_Panel_Root;
        Front_Panel_Root = Main_Fin_Root - Rear_Mid_Panel_Root;
    
        difference() {
            hull () { // main fin
                // center root panel
                translate ([Rear_Panel_Root, (Center_Panel_Thickness - Main_Fin_Edge_Diameter)/2, 0])
                    rotate (a = [0, 90, 0])
                    cylinder (h = Center_Panel_Root, d = Main_Fin_Edge_Diameter, $fn = 20);
                translate ([Rear_Panel_Root, -(Center_Panel_Thickness - Main_Fin_Edge_Diameter)/2, 0])
                    rotate (a = [0, 90, 0])
                    cylinder (h = Center_Panel_Root, d = Main_Fin_Edge_Diameter, $fn = 20);
                   
                // forward tip  
                translate ([Main_Fin_Root - Main_Fin_Edge_Diameter/2, 0, 0])
                    sphere (d = Main_Fin_Edge_Diameter, $fn = 20);
                   
                // trailing edge
                translate ([Main_Fin_Edge_Diameter/2 - 0.08, 0, Main_Fin_Span - Main_Fin_Edge_Diameter/2])
                    sphere (d = Main_Fin_Edge_Diameter, $fn = 20);
                translate ([Main_Fin_Edge_Diameter/2 - 0.08, 0, 0])
                    sphere (d = Main_Fin_Edge_Diameter, $fn = 20);
            }
            translate ([0, 0, -Body_Diameter/2]) rotate (a = [0, 90, 0])
                cylinder (h = 3*Main_Fin_Root, d = Body_Diameter, center = true, $fn = smooth);
        }  
               
        hull () { // aileron
            // leading edge
            translate ([-Main_Fin_Edge_Diameter/2 + 0.08, 0, Aileron_Body_Standoff])
                sphere (d = Main_Fin_Edge_Diameter, $fn = 20);
            translate ([-Main_Fin_Edge_Diameter/2 + 0.08, 0, Main_Fin_Span - Main_Fin_Edge_Diameter/2 +0.1])
                sphere (d = Main_Fin_Edge_Diameter, $fn = 20);
               
            // trailing edge
            translate ([-Main_Fin_Edge_Diameter/2 - Aileron_Width, 0, -0.16 + Aileron_Body_Standoff])
                sphere (d = Aileron_TE_Diameter, $fn = 20);
            translate ([-Main_Fin_Edge_Diameter/2 - Aileron_Width, 0, Main_Fin_Span - Main_Fin_Edge_Diameter/2 + 0.7])
                sphere (d = Aileron_TE_Diameter, $fn = 20);
        }
    } // end module main fin  
    
    
    module Nike_Ajax_Sustainer () {
        Main_Fin_Position = 252 - 195; // Alway
    
        Main_Body ();
       
        for ( fin_angle = [45, 135, 225, 315]) {  
            rotate (a = [0, 0, fin_angle]) translate ([-Body_Diameter/2, 0, Main_Fin_Position])
                rotate (a = [0, -90, 0]) Main_Fin ();  
        } // end for
       
    } // end module Nike Ajax Sustainer
    
    color ("White") Nike_Ajax_Sustainer ();
    In the last module, instead of calling Main_Fin () four separate times as I did before, I've condensed that a bit by using a for loop command. There are several ways to use a for, but in this case, it just assigns the variable fin_angle sequentially to the values in brackets [45, 135, 225, 315] and then runs the code in the following curly brackets once for each value. So the fin_angle is changed for each call to Main_Fin ().
     
  21. May 9, 2019 #21

    vcp

    vcp

    vcp

    Well-Known Member

    Joined:
    Jan 28, 2009
    Messages:
    908
    Likes Received:
    83
    Location:
    Boise, ID
    Let's get back to it with a simple little detail. The main body has a number of body panel splits that are pretty easy to add. At most scales, they would be invisible and probably not noticeable in a small print, but I like to have them there anyway.

    First, add the station locatons of the splits to the header of the main file:
    Code:
    // Main Body Panel Breaks
        Panel_Break_1 = 251 - 108.656;
        Panel_Break_2 = 251 - 149.510;
        Panel_Break_3 = 251 - 152.510;
        Panel_Break_4 = 251 - 167.990;
        Panel_Break_5 = 251 - 171.590;
        Panel_Break_6 = 251 - 187.268;
        Panel_Break_7 = 251 - 198.625;
    
    Panel_Gap_Depth = 0.1; // depth of panel gaps - estimated panel gap.
    Panel_Gap_Width = 0.1; // width of panel gaps
    This includes a variable for the panel gap width and depth as well.

    Now I'm going to change the module for the Main Body, as follows:
    Code:
    module Main_Body () {
        // forward cone
        translate ([0, 0, Bottom_Forward_Cone])
            cylinder (h = 75.781 - 14, d1 = Body_Diameter, d2 = Forward_Cone_Forward_Diameter, $fn = smooth);  // 6.377 TBD
        // main body
        difference() {
            translate ([0, 0, Bottom_Main_Body])
                cylinder (h = Main_Body_Length, d = Body_Diameter, $fn = smooth);
               
            translate ([0, 0, Panel_Break_1]) cylinder (d = Body_Diameter + 2, h = Panel_Gap_Width, center = true, $fn = 8);
            translate ([0, 0, Panel_Break_2]) cylinder (d = Body_Diameter + 2, h = Panel_Gap_Width, center = true, $fn = 8);  
            translate ([0, 0, Panel_Break_3]) cylinder (d = Body_Diameter + 2, h = Panel_Gap_Width, center = true, $fn = 8);
            translate ([0, 0, Panel_Break_4]) cylinder (d = Body_Diameter + 2, h = Panel_Gap_Width, center = true, $fn = 8);  
            translate ([0, 0, Panel_Break_5]) cylinder (d = Body_Diameter + 2, h = Panel_Gap_Width, center = true, $fn = 8);
            translate ([0, 0, Panel_Break_6]) cylinder (d = Body_Diameter + 2, h = Panel_Gap_Width, center = true, $fn = 8);  
            translate ([0, 0, Panel_Break_7]) cylinder (d = Body_Diameter + 2, h = Panel_Gap_Width, center = true, $fn = 8);
        }  
        translate ([0, 0, Bottom_Main_Body])
            cylinder (h = Main_Body_Length, d = Body_Diameter - 2*Panel_Gap_Depth, $fn = smooth);  
    
        // tail cone
        cylinder (h = Tail_Cone_Length, d1 = Tail_Diameter, d2 = Body_Diameter, $fn = smooth);
    } // module Main Body
    I've made the main body cylinder to be the first item of a difference statement, and following that, I've subtracted cylinders the height of the gap_width at each station location where there is a panel seam. So now the body is sliced into eight separate cylinders. But I'll glue them back together by placing a new cylinder in place, same length as the body, but just smaller in diameter by two times the gap depth. So now we have a single body again, but with 'groves' at the appropriate station locations.
     
  22. May 9, 2019 #22

    vcp

    vcp

    vcp

    Well-Known Member

    Joined:
    Jan 28, 2009
    Messages:
    908
    Likes Received:
    83
    Location:
    Boise, ID
    Showing the panel breaks:
    body panael breaks.JPG
     
  23. May 9, 2019 #23

    vcp

    vcp

    vcp

    Well-Known Member

    Joined:
    Jan 28, 2009
    Messages:
    908
    Likes Received:
    83
    Location:
    Boise, ID
    I'm going to skip to the booster fins, because the other Ajax fins are a bit more complex. The booster fins will ease into things a bit slower.

    NA Booster Fins Bennett.JPG NA - Booster Fins Alway.JPG

    So I've got two sources for the booster fin dimensions, Bennett and Alway. There's really not much disagreement between the two. The one thing that Bennett adds is the small 'drop' to the forward end of the root. The booster tail shroud is a sheet metal cylinder that fits around the end of the Nike booster, but the fins extend forward of this shroud. So the root is not straight; the forward part of the root extends down a little bit more so that it contacts the Nike body forward of the shroud I finally found a photo that shows this well (note that the shroud itself is missing here):

    NA Booster Fin Root.JPG

    So first I'm going to do the basic fin, without that root extension. Like before, I'm going to place spheres at each corner, and use the hull command to create a surface between them. I've again corrected the sphere positions by subtracting 1/2 the diameter of the sphere so that the sphere is right on the edge. I haven't yet done this spanwise, however. The booster fin is another module:

    Code:
    module Booster_Fin () {
        Main_Span = 34.688;     // Bennett
        Root_Chord = 37.125;    //
        Tip_Chord = 10.50;      //
        Edge_Diameter = 0.25;   // Est.
        Root_Thickness = 2.297; //
        Tip_Thickness = 0.706;  //
      
        // unextended root
        hull () {
            // forward root edge
            translate ([Edge_Diameter/2, 0, 0]) sphere (d = Edge_Diameter, $fn = 20);
            // aft root edge
            translate ([Root_Chord - Edge_Diameter/2, 0, 0]) sphere (d = Edge_Diameter, $fn = 20);
            // aft tip edge
            translate ([Root_Chord/2 + Tip_Chord/2 - Edge_Diameter/2, 0, Main_Span]) sphere (d = Edge_Diameter, $fn = 20);
            // forward tip edge
            translate ([Root_Chord/2 - Tip_Chord/2 + Edge_Diameter/2, 0, Main_Span]) sphere (d = Edge_Diameter, $fn = 20);
            // root center
            translate ([Root_Chord/2, Root_Thickness/2 - Edge_Diameter/2, 0]) sphere (d = Edge_Diameter, $fn = 20);
            translate ([Root_Chord/2, -Root_Thickness/2 + Edge_Diameter/2, 0]) sphere (d = Edge_Diameter, $fn = 20);   
            // tip center
            translate ([Root_Chord/2, Tip_Thickness/2 - Edge_Diameter/2, Main_Span]) 
                sphere (d = Edge_Diameter, $fn = 20);
            translate ([Root_Chord/2, -Tip_Thickness/2 + Edge_Diameter/2, Main_Span]) 
                sphere (d = Edge_Diameter, $fn = 20);   
        } // end hull
    }  // end module Booster_Fin
    
    Booster_Fin ();
    Which then looks like this:

    Booster Fin 1.JPG

    Next, I'll fix that root.
     
    Last edited: May 9, 2019
  24. May 9, 2019 #24

    vcp

    vcp

    vcp

    Well-Known Member

    Joined:
    Jan 28, 2009
    Messages:
    908
    Likes Received:
    83
    Location:
    Boise, ID
    Now I want to extend the forward bit of that root downward, but the dimensions are a bit vague. I'm going to do a horrible, horrible hack. With this code:
    Code:
    module Booster_Fin () {
        Main_Span = 34.688;     // Bennett
        Root_Chord = 37.125;    //
        Tip_Chord = 10.50;      //
        Edge_Diameter = 0.25;   // Est.
        Root_Thickness = 2.297; //
        Tip_Thickness = 0.706;  //
       
        // unextended root
        hull () {
            // forward root edge
            translate ([Edge_Diameter/2, 0, 0]) sphere (d = Edge_Diameter, $fn = 20);
            // aft root edge
            translate ([Root_Chord - Edge_Diameter/2, 0, 0]) sphere (d = Edge_Diameter, $fn = 20);
            // aft tip edge
            translate ([Root_Chord/2 + Tip_Chord/2 - Edge_Diameter/2, 0, Main_Span]) sphere (d = Edge_Diameter, $fn = 20);
            // forward tip edge
            translate ([Root_Chord/2 - Tip_Chord/2 + Edge_Diameter/2, 0, Main_Span]) sphere (d = Edge_Diameter, $fn = 20);
            // root center
            translate ([Root_Chord/2, Root_Thickness/2 - Edge_Diameter/2, 0]) sphere (d = Edge_Diameter, $fn = 20);
            translate ([Root_Chord/2, -Root_Thickness/2 + Edge_Diameter/2, 0]) sphere (d = Edge_Diameter, $fn = 20);  
            // tip center
            translate ([Root_Chord/2, Tip_Thickness/2 - Edge_Diameter/2, Main_Span])
                sphere (d = Edge_Diameter, $fn = 20);
            translate ([Root_Chord/2, -Tip_Thickness/2 + Edge_Diameter/2, Main_Span])
                sphere (d = Edge_Diameter, $fn = 20);  
        } // end hull
       
        #hull () {
            // forward root edge
            translate ([Edge_Diameter/2, 0, -0.5]) sphere (d = Edge_Diameter, $fn = 20);
            // aft root edge
            translate ([Root_Chord - Edge_Diameter/2, 0, 0]) sphere (d = Edge_Diameter, $fn = 20);
            // forward tip edge
            translate ([Root_Chord/2 + Tip_Chord/2 - Edge_Diameter/2, 0, Main_Span]) sphere (d = Edge_Diameter, $fn = 20);
            // aft tip edge
            translate ([Root_Chord/2 - Tip_Chord/2 + Edge_Diameter/2, 0, Main_Span]) sphere (d = Edge_Diameter, $fn = 20);
            // root center
            translate ([Root_Chord/2, Root_Thickness/2 - Edge_Diameter/2, 0]) sphere (d = Edge_Diameter, $fn = 20);
            translate ([Root_Chord/2, -Root_Thickness/2 + Edge_Diameter/2, 0]) sphere (d = Edge_Diameter, $fn = 20);  
            // tip center
            translate ([Root_Chord/2, Tip_Thickness/2 - Edge_Diameter/2, Main_Span])
                sphere (d = Edge_Diameter, $fn = 20);
            translate ([Root_Chord/2, -Tip_Thickness/2 + Edge_Diameter/2, Main_Span])
                sphere (d = Edge_Diameter, $fn = 20);  
        } // end hull  
    }  // end module Booster_Fin
    
    Booster_Fin ();
    The second hull block is the same as the first except for this line:
    Code:
            // forward root edge
            translate ([Edge_Diameter/2, 0, -0.5]) sphere (d = Edge_Diameter, $fn = 20);
    The forward root tip sphere has been translated down by 0.5. The second block is also preceded by a '#' which makes it translucent. The tip looks like this:

    fin tip.JPG

    Now I'm going to move that lower tip forward a small increment at a time, until the leading edge of the translucent fin matches the first, opaque fin.
    Code:
            // forward root edge
            translate ([Edge_Diameter/2 - 0.2, 0, -0.5]) sphere (d = Edge_Diameter, $fn = 20);
    Moving it forward that 0.2 it becomes this:

    fin tip2.JPG

    The 'extended' fin leading edge is now in-line with the original fin, but extends below it. So now I'll trim off the root. According to Bennett that drop is 3/32", so start by differencing the fin with a cube that sits 0.94 below the x-y plane. We can also get rid of the non-extended fin, and we can also trim the fin tip. Remember that these things (cubes, in this case) aren't part of the fin - I'm using them to trim off the bits of the fin I don't want.

    I don't think I've mentioned using the cube () object yet. It just takes the form cube ({x. y, z]) , where x, y, and z are the dimensions of the cube. Adding the parameter center = true places the center of the cube at the origin, which usually makes it easier to position later. I've created a cube 10 high (z), and 10 wide (y); and four times the root length, so that even though it's x position is centered at the origin it extends past the length of the fin. Moving this cube in z by the fin span, plus half the height of the cube, places the lower surface of that cube at the fin tip, and subtracting it slices the tip off flat. (Remember, the tip wasn't flat, it was made with spheres.) Using the same cube moved downwards in z by 0.94 plus half its height slices off the root at the extended position. Same cube again, but this time only the root length, moved down by half its height, moved aft by half the root length, and moved further aft by the position of the start of the root slant, slices off the main flat area of the root. I also hulled this cube with a smaller cube to create the slanted area between the forward and aft root areas. Clear as mud.

    I also added the root cylindrical mounting hub.

    root trim.JPG
    trimmed root.JPG
    final boost fin.JPG
    Code:
    module Booster_Fin () {
        Main_Span = 34.688;     // Bennett
        Root_Chord = 37.125;    //
        Tip_Chord = 10.50;      //
        Edge_Diameter = 0.25;   // Est.
        Root_Thickness = 2.297; //
        Tip_Thickness = 0.706;  //
        Root_Drop_Extension = 0.094; // 3/32 Bennett
       
        difference() {
            hull () {
                // forward root edge
                translate ([Edge_Diameter/2 - 0.2, 0, -0.5]) sphere (d = Edge_Diameter, $fn = 20);
                // aft root edge
                translate ([Root_Chord - Edge_Diameter/2, 0, 0]) sphere (d = Edge_Diameter, $fn = 20);
                // forward tip edge
                translate ([Root_Chord/2 + Tip_Chord/2 - Edge_Diameter/2, 0, Main_Span]) sphere (d = Edge_Diameter, $fn = 20);
                // aft tip edge
                translate ([Root_Chord/2 - Tip_Chord/2 + Edge_Diameter/2, 0, Main_Span]) sphere (d = Edge_Diameter, $fn = 20);
                // root center
                translate ([Root_Chord/2, Root_Thickness/2 - Edge_Diameter/2, 0]) sphere (d = Edge_Diameter, $fn = 20);
                translate ([Root_Chord/2, -Root_Thickness/2 + Edge_Diameter/2, 0]) sphere (d = Edge_Diameter, $fn = 20);  
                // tip center
                translate ([Root_Chord/2, Tip_Thickness/2 - Edge_Diameter/2, Main_Span])
                    sphere (d = Edge_Diameter, $fn = 20);
                translate ([Root_Chord/2, -Tip_Thickness/2 + Edge_Diameter/2, Main_Span])
                    sphere (d = Edge_Diameter, $fn = 20);  
            } // end hull  
            // trim the fin tip with a cube translated by the fin span.
            translate ([0, 0, Main_Span + 10/2]) cube (size = [Root_Chord * 4, 10, 10], center = true);
            // trim the extended fin root
            translate ([0, 0, -Root_Drop_Extension - 10/2]) cube (size = [Root_Chord * 4, 10, 10], center = true);      
            // trim the shroud (non-extended) section of the fin root
            translate ([Root_Chord/2 + 7.875, 0, -10/2]) cube (size = [Root_Chord, 10, 10], center = true);  
            // slanted trim between the two sections
            hull () {
                translate ([Root_Chord/2 + 7.875, 0, -10/2]) cube (size = [Root_Chord, 10, 10], center = true);
                translate ([6, 0, -Root_Drop_Extension]) cube (size = [0.01, 10, 0.01], center = true);
            }
        } // end difference
        // fin mount rod
        translate ([Root_Chord/2, 0, 0]) cylinder (h = 1, d = 2, center = true, $fn = 60);          
    }  // end module Booster_Fin
    
    Booster_Fin ();
    Well, I said it was a horrible hack. But, it produced exactly what I wanted. The best way to see what's going on would be to run the above code, and comment out sections to see what happens. Eventually, you should be able to pick up on what each section does.
     
  25. May 9, 2019 #25

    vcp

    vcp

    vcp

    Well-Known Member

    Joined:
    Jan 28, 2009
    Messages:
    908
    Likes Received:
    83
    Location:
    Boise, ID
    Just for grins now we can make a quick booster shroud with fins. I see that I screwed up in that I placed the fin leading edge tip at the origin instead of placing the trailing edge tip there like I did for the main sustainer fin. That causes a few more gyrations in getting it rotated into position. I first have to translate it on the x-axis so that the trailing edge tip is at the origin, then rotate it vertical, then translate it again on the x-axis to the surface of the shroud, and finally rotate three fins radially into position.

    I've added a little 'Fin_Spacing' fudge, because I doubt the fin root is actually flush with the shroud.

    There will be a bunch of bolts and rivets to be added soon.
    Code:
    module Booster_Fin_Can () {
        Root_Chord = 37.125;    //
        Boost_Shroud_Diameter = 16.67;  // Bennett
        Boost_Shroud_Length = 28.125;   // Bennett
        Boost_Shroud_Thickness = 0.085; // Alway
        Fin_Spacing = 0.05; // est spacing between fin root and shroud
    
        difference() {
            cylinder (h = Boost_Shroud_Length, d = Boost_Shroud_Diameter, $fn = smooth);
            cylinder (h = 3 * Boost_Shroud_Length, d = Boost_Shroud_Diameter - 2 * Boost_Shroud_Thickness, center = true, $fn = smooth);
        }
        for ( rot = [0, 120, 240]) {   
            rotate (a = [0, 0, rot]) translate ([Boost_Shroud_Diameter/2 + Fin_Spacing, 0, 0])
                rotate (a = [0, 90, 0]) translate ([-Root_Chord, 0, 0]) Booster_Fin ();
        }
        // TODO bolts
    }
    
    Booster_Fin_Can ();
    boost fin can.JPG
     
  26. May 11, 2019 #26

    vcp

    vcp

    vcp

    Well-Known Member

    Joined:
    Jan 28, 2009
    Messages:
    908
    Likes Received:
    83
    Location:
    Boise, ID
    The Nike Ajax booster fin has some fairly prominent rivets on the leading and trailing edge. Probably not enough to be seen at most scales, but I like to have details like that in the CAD model anyway - it's easy enough to turn them off if I don't want them interfering with printing.
    booster fin rivets.JPG

    I count 37 on each edge. The center and root fasteners are flush phillips-heads that aren't nearly as prominent - I'll add them later. But now, the rivets.

    First a new little module:
    Code:
    module rivet (diameter, prominence) {  //single rivet
    // diameter = rivet outer diameter
    // prominence = value 0-1 ; 1 = hemisphere, 0.35 = flattened, etc
        scale (v = [1, 1, prominence])  sphere (d = diameter, $fn = 12);
    } // module rivets    
    This module adds a new feature of passed variables. The factors (diameter, prominence) are passed into this module from the line that calls it, and defines the size of the rivet. The diameter is pretty obvious, the prominence is used in the scale command. The scale command simply takes the form scale ([x, y, z]) where x, y, and z are how much the object is scaled on each axis. In this case the head of the rivet isn't going to be a sphere, but will be flattened somewhat. Calling it with a command like rivet (0.35, 0.3); will produce one rivet.


    rotate (a = [90, 0, 0]) rivet (0.35, 0.3); This part just calls the rivet module to produce one rivet at the origin and rotates it on edge to match the vertical orientation that I used to develop the fin.
    one rivet.JPG
    Now I'll add the
    for loop that produces 37 rivets. The variable rivet_spaceLE is a first guess at the spacing between the rivets.
    Code:
        rivet_spaceLE = 1.0;    
    
        for ( rivet_number = [ 0: 36]) {
            translate ([rivet_number * rivet_spaceLE, 0, 0])
                rotate (a = [90, 0, 0]) rivet (0.35, 0.3);
        } // end for 
    This form of the
    for command increments the variable rivet_number 37 times between the values of 0 and 36. Each time it's multiplied by the value rivet_spaceLE which makes an x-translation for each rivet in the loop, producing a row. At the moment they're still down the center of the root.

    rivet row1.JPG

    So now we want to translate them to be in line with the leading edge, using rotate (a = [0, -69, 0]) The angle value -69 was just found by plugging in values until the rivets lined up with the edge - no math required.

    rivet row 2.JPG

    So now I'm going to just translate the entire row, so that the first rivet is in the right place:
    translate ([0.45, -0.18, 0.3]) Once again, these numbers were diddled with until TLAR.
    rivet row 3.JPG

    The last thing to do is look at the other end of the row:
    rivet row 4.JPG

    That's a little short - the photos show the last rivet right in the corner. Adjusting the variable
    rivet_spaceLE = 1.0; will take care of that. It looks like a value of 1.017 will place it just right.

    Now gosh, do we have to go through that again for the trailing edge, and the other side? Not quite. All we have to do is translate the starting point along the root edge x-axis to the trailing edge, and use a mirror of the leading edge angle, adjust the starting point a bit, and it's done. The other side is even easier with the
    mirror ([x, y, z]) command. With the mirror command, we'll put a '1' in the 'y' position, which mirrors everything in the following curley brackets around the y-axis. So we just use mirror on the exact same code that the produced the rivets on the front side, and they will be mirrored onto the opposite side. The full booster fin code now looks like this:
    Code:
    module Booster_Fin () {
        Main_Span = 34.688;     // Bennett
        Root_Chord = 37.125;    //
        Tip_Chord = 10.50;      //
        Edge_Diameter = 0.25;   // Est.
        Root_Thickness = 2.297; //
        Tip_Thickness = 0.706;  //
        Root_Drop_Extension = 0.094; // 3/32 Bennett
      
        difference() {
            hull () {
                // forward root edge
                translate ([Edge_Diameter/2 - 0.2, 0, -0.5]) sphere (d = Edge_Diameter, $fn = 20);
                // aft root edge
                translate ([Root_Chord - Edge_Diameter/2, 0, 0]) sphere (d = Edge_Diameter, $fn = 20);
                // forward tip edge
                translate ([Root_Chord/2 + Tip_Chord/2 - Edge_Diameter/2, 0, Main_Span]) sphere (d = Edge_Diameter, $fn = 20);
                // aft tip edge
                translate ([Root_Chord/2 - Tip_Chord/2 + Edge_Diameter/2, 0, Main_Span]) sphere (d = Edge_Diameter, $fn = 20);
                // root center
                translate ([Root_Chord/2, Root_Thickness/2 - Edge_Diameter/2, 0]) sphere (d = Edge_Diameter, $fn = 20);
                translate ([Root_Chord/2, -Root_Thickness/2 + Edge_Diameter/2, 0]) sphere (d = Edge_Diameter, $fn = 20); 
                // tip center
                translate ([Root_Chord/2, Tip_Thickness/2 - Edge_Diameter/2, Main_Span])
                    sphere (d = Edge_Diameter, $fn = 20);
                translate ([Root_Chord/2, -Tip_Thickness/2 + Edge_Diameter/2, Main_Span])
                    sphere (d = Edge_Diameter, $fn = 20); 
            } // end hull 
            // trim the fin tip with a translated by the fin span.
            translate ([0, 0, Main_Span + 10/2]) cube (size = [Root_Chord * 4, 10, 10], center = true);
            // trim the extended fin root
            translate ([0, 0, -Root_Drop_Extension - 10/2]) cube (size = [Root_Chord * 4, 10, 10], center = true);     
            // trim the shroud section of the fin root
            translate ([Root_Chord/2 + 7.875, 0, -10/2]) cube (size = [Root_Chord, 10, 10], center = true); 
            // slanted trim between the two sections
            hull () {
                translate ([Root_Chord/2 + 7.875, 0, -10/2]) cube (size = [Root_Chord, 10, 10], center = true);
                translate ([6, 0, -Root_Drop_Extension]) cube (size = [0.01, 10, 0.01], center = true);
            }
        } // end difference
      
        // fin mount rod
        translate ([Root_Chord/2, 0, 0]) cylinder (h = 1, d = 2, center = true, $fn = 60);     
    
        rivet_spaceLE = 1.017; // leading edge rivet spacing
        translate ([0.45, -0.18, 0.3])  for ( rivet_number = [ 0: 36]) { // for 37 rivets
            rotate (a = [0, -69, 0]) translate ([rivet_number * rivet_spaceLE, 0, 0])
                rotate (a = [90, 0, 0]) rivet (0.35, 0.3);
        } // end for
        rivet_spaceTE = 1.016; // trailing edge rivet spacing
        translate ([0.3, -0.18, 0.3]) for ( rivet_number = [ 0: 36]) { // for 37 rivets
            translate ([Root_Chord - 0.7, 0, 0]) rotate (a = [0, -111, 0])
                translate ([rivet_number * rivet_spaceTE, 0, 0]) rotate (a = [90, 0, 0]) rivet (0.35, 0.3);
        } // end for
      
        mirror ([0, 1, 0]) { // mirror places the rivets on the opposite side
            translate ([0.45, -0.18, 0.3])  for ( rivet_number = [ 0: 36]) { // for 37 rivets
                rotate (a = [0, -69, 0]) translate ([rivet_number * rivet_spaceLE, 0, 0])
                    rotate (a = [90, 0, 0]) rivet (0.35, 0.3);
            } // end for
            translate ([0.3, -0.18, 0.3]) for ( rivet_number = [ 0: 36]) { // for 37 rivets
                translate ([Root_Chord - 0.7, 0, 0]) rotate (a = [0, -111, 0])
                    translate ([rivet_number * rivet_spaceTE, 0, 0]) rotate (a = [90, 0, 0]) rivet (0.35, 0.3);
            } // end for
        } // end mirror
    
    }  // end module Booster_Fin
    
    Booster_Fin ();
    Remember that this also has to have the little module rivet() from above, in the code as well. The whole fin can now looks like this. Notice that I didn't make any changes to the Booster_Fin_Can code - since it calls the revised Booster_Fin module, the new rivets come in automatically.
    fin can rivets.JPG









     
  27. May 11, 2019 #27

    vcp

    vcp

    vcp

    Well-Known Member

    Joined:
    Jan 28, 2009
    Messages:
    908
    Likes Received:
    83
    Location:
    Boise, ID
    Have I lost everybody? ... Ah well. One more neet little thing anyway. There's an attached file below titled 'Nike_M5_Motor.txt' Download that file and rename it to: 'Nike_M5_Motor.scad' and place it in the same directory with the other Nike Ajax OpenSCAD files.

    At the top of the Nike Ajax file we've been working on, add the line:
    include <Nike_M5_Motor.scad>;

    That other file was my OpenSCAD code for the Nike M5 motor, which I'm not going to try and explain. You might be able to figure it out, but I didn't write it with the intention of other humans reading it, so it might be pretty obscure. The good news is, you don't have to. Using the include statement above, effectively adds that code right into the Nike-Ajax stuff we've been working on. Code re-use. (And re-usable for every other Nike-based rocket - neet.)

    Now with the module rivet() from above, the module Booster_Fin_Can () , and the module Booster_Fin () , plus that include line, we can do this:
    Code:
    //Booster_Fin ();
    //Booster_Fin_Can ();
    
    color ("White") Booster_Fin_Can ();
    rotate (a = [0, 0, 60]) Nike_M5_motor();
    Comment out any earlier calls to display the Booster Fin or Booster Fin Can. The last two lines display the Booster Fin Can in white, and drops in the Nike M5 motor from the other file. It's rotated 60 degrees to get the flange holes lined up right. Wa-la. The entire Nike-Ajax booster: (Whoops - less the interstage, for now.)

    Ajax m5.JPG

    The fin leading edge detail shows how the root comes off of the shroud and perfectly skips over the Nike weld line so that the front of the root is flush with the Nike body.

    fin LE weld.JPG

    Ajax M5 2.JPG

    There are a few details on the M5 ignitor that will have to be changed for the Ajax.
     

    Attached Files:

  28. May 11, 2019 #28

    dhbarr

    dhbarr

    dhbarr

    Amateur Professional TRF Supporter

    Joined:
    Jan 30, 2016
    Messages:
    5,432
    Likes Received:
    493
    I'm watching but don't have much to add. Looks very cool!
     
  29. May 14, 2019 #29

    vcp

    vcp

    vcp

    Well-Known Member

    Joined:
    Jan 28, 2009
    Messages:
    908
    Likes Received:
    83
    Location:
    Boise, ID
    Ok, this is getting out of hand. Files get too big and are unwieldy. Time to split things up and organize a bit. This means, however, that the project will be split into perhaps a dozen files, usually one for each component.

    The text editor embedded into OpenSCAD has improved a lot recently, but it doesn't handle having multiple tabbed files open simultaneously. (You can just have multiple OpenSCAD windows open, but that gets clumsy.) It's not necessary, but I suggest using an alternate programming editor - my choice is Notepad++. It can be configured for a particular language, so that it has keyword coloring, autocomplete, and help notes. Notepad++ is free and easy to install, but the language configuration takes some work. If you want to try it, there are instructions and language files here: https://www.thingiverse.com/thing:167899 When using Notepad++ with OpenSCAD, you turn off the OpenSCAD editor window, and anytime you save a Notepad++ file that is open in OpenSCAD, it forces OpenSCAD to recompile the project. Works neet. There are some other programming editors that have been configured to work with OpenSCAD, but this is the one I know - 'cause I did the language files.
     
    dhbarr likes this.
  30. May 14, 2019 #30

    vcp

    vcp

    vcp

    Well-Known Member

    Joined:
    Jan 28, 2009
    Messages:
    908
    Likes Received:
    83
    Location:
    Boise, ID
    With the files I'll be including here, there really are no programming changes - nothing new - just some rearrangement. I'll only detail a couple here. First the Nike-Ajax common.scad file, which contains some global variables and common modules:
    Code:
    /*
    Nike Ajax - global dimensions and common modules
    
    Use of this file is licensed under the Creative Commons - Attribution - Non-Commercial license.
    http://creativecommons.org/licenses/by-nc/3.0/  by Gary A. Crowell Sr.
    */
    
    smooth = 120;
    
    Forward_Cone_Forward_Diameter = 5.8;
    Body_Diameter = 12;
    Tail_Diameter = 9; // Alway
    
    Nose_Cone_Length = 14; // Alway
    
    
    // Booster_Fin_Shroud dimensions
        Root_Chord = 37.125;    //
        Boost_Shroud_Diameter = 16.67;  // Bennett
        Boost_Shroud_Length = 28.125;   // Bennett
        Boost_Shroud_Thickness = 0.085; // Alway
        Fin_Spacing = 0.05; // spacing between fin root and shroud
    
    
    module rivet (diameter, prominence) {  //single rivet
    // diameter = rivet outer diameter
    // prominence = value 0-1 ; 1 = hemisphere, 0.35 = flattened, etc
        scale (v = [1, 1, prominence])  sphere (d = diameter, $fn = 12);
    } // module rivet    
    Nothing really new there. And then the top-level file Nike-Ajax.scad.
    Code:
    /*
    Nike Ajax
    
    Use of this file is licensed under the Creative Commons - Attribution - Non-Commercial license.
    http://creativecommons.org/licenses/by-nc/3.0/  by Gary A. Crowell Sr.
    
    For ease of development, since all data sources were scaled in inches, all dimensions were
    entered as inches, but OpenSCAD uses mm.  So the resulting scale is 1 mm = 1 in, or 1/25.4.
    
    For conversion to other scales use the following factors:
     
            1/144   = 0.176
            1/100   = 0.254
            1/87    = 0.292
            1/72    = 0.353
            1/48    = 0.529
            1/35    = 0.726
            1/24    = 1.058
            1/12    = 2.117
            1/10    = 2.540
            1/8     = 3.175
    BT5   = 1/30.33 = 0.837
    BT20  = 1/22.42 = 1.133
    BT50  = 1/16.91 = 1.502
    BT55  = 1/12.45 = 2.040
    BT60  = 1/10.08 = 2.520
    BT70  = 1/7.44  = 3.414
    BT80  = 1/6.35  = 4.000
    3"LOC = 1/5.32  = 4.744
    3.9LOC= 1/4.13  = 6.150
    */
    
    // include files for Nike-Ajax components
        //include <Nike-Ajax common.scad>; // this is included in all other files
        include <Nike_M5_Motor.scad>;
        include <Nike-Ajax body.scad>;
        include <Nike-Ajax main fin.scad>;
        //include <Nike-Ajax guide fin.scad>;
        //include <Nike-Ajax radar fin.scad>;
        include <Nike-Ajax booster fin.scad>;
        include <Nike-Ajax booster fin shroud.scad>;
        //include <Nike-Ajax interstage.scad>;
        //include <Nike-Ajax nose cone.scad>;
        //include <Nike-Ajax launch lugs.scad>;
    
    // main component locations  
        Bottom_Ajax_Tail_Cone_Sta = 251;
        Bottom_Nike_Sta = 392;
        Main_Fin_Sta = 195;
    
       
    module Nike_Ajax_Sustainer () {
        // main body
        color ("White") Main_Body ();
    
        // fins
        color ("White") for ( rot = [45, 135, 225, 315]) {
            rotate (a = [0, 0, rot])
                translate ([Body_Diameter/2, 0, Bottom_Ajax_Tail_Cone_Sta - Main_Fin_Sta]) Main_Fin ();
            //rotate (a = [0, 0, rot]) translate ([-3.8, 0, 251 - 48.826]) Guide_Fin ();
            //rotate (a = [0, 0, rot]) translate ([-5.48, 0, 251 - 74.675]) Radar_Fin ();  
        } // end for
       
        // TODO tunnels
        // TODO nose cone
       
    } // end module Nike Ajax Sustainer
       
       
    // booster fins
        for ( rot = [0, 120, 240]) {  
            rotate (a = [0, 0, rot]) translate ([Boost_Shroud_Diameter/2 + Fin_Spacing, 0, Root_Chord/2])
                Booster_Fin ();
        } // end for
     
     
    color ("White" ) Booster_Fin_Shroud ();
    translate ([0, 0, Bottom_Nike_Sta - Bottom_Ajax_Tail_Cone_Sta]) Nike_Ajax_Sustainer ();
    rotate (a = [0, 0, 60]) Nike_M5_motor();
    // TODO
        // interstage
        // launch lugs

    First thing in that code is that in the header comments I've put in the scale factors that would be used for most model sizes. A scale () command around the final model with the scale factor will produce a model in the indicated scale.

    Next, are the include statements for all of the individual component files. Some are commented out because we don't have those components developed yet. And finally, there are some TODO placeholders for some other bits that are yet to be done. All of these .txt files must have their extension changed to .scad for use with OpenSCAD.
     

    Attached Files:

Share This Page