Skip to content

Latest commit

 

History

History
404 lines (266 loc) · 20.1 KB

File metadata and controls

404 lines (266 loc) · 20.1 KB

OpenSCAD Machine Design Framework - Tutorial 1

Basic quad frame layout with motors

In this first tutorial, we're going to cover:

  • Starting a project, pre-requisites
  • Key concepts - parts and assemblies
  • Simple assembly of a printed part and an existing vitamin
  • Using the vitamin catalogue
  • Use of utility tools and assembly guide generation
  • Using the sandbox
  • Printing the STL

Back to Tutorials page

Objective

The outcome of this tutorial is a basic quad-copter frame sized to fit the motors from the Hubsan X4 (or similar). Our OpenSCAD model will contain the frame itself (as a single printable part) and a representation of the motors. The model will not contain the battery, flight controller, wiring, etc (this will be tackled in the later tutorials).

If you have the relevant parts, then at the end of the tutorial you will be able to print out the frame for test assembly, and even fly the frame by taping the battery/flight-controller to it.

Starting a project, pre-requisites

Python Pre-requisites

There are various utility scripts included in the template project to aid the design process, they are all written in Python (tested against v2.7.9). As such, you will need to ensure you have a compatible version of Python installed along with a couple of dependencies:

  1. PIL - the Python Image Library - use: pip install pillow
  2. Pystache - the Pystache template library - use: pip install pystache

Other Pre-requisites

The framework can generate animated assembly guides, but relies upon the following:

  1. ffmpeg
  2. convert (ImageMagick command line)

Starting a new Project

Once you have the pre-requisites installed, you need a local copy of the framework from which to bootstrap a new project - download or clone it from github, for the sake of the tutorial, we'll assume the framework is stored in /OMDF:

To start a new project:

  1. Open a terminal and navigate to the /OMDF/scripts directory
  2. Run ./startaproject.py <in-dir> QuadFrame. Replace with the directory within which you would like to create the project (e.g. ~/Documents).

The startaproject.py script will:

  • Create the directory structure for the new project
  • Setup standard config files
  • Setup a root .scad file
  • Init git
  • Setup and clone the framework as a submodule within the QuadFrame/hardware/framework directory

Once the project is created, you can optionally add it to a site like .

File structure

The project files are all contained within a top-level "hardware" directory, on the assumption you will add other top-level directories for software development, notes, etc.

You will find the following directories within /hardware:

Directory Contains
. Top-level machine .scad file (e.g. QuadFrame.scad), generated by the framework
assemblies SCAD files that describe all the assemblies/sub-assemblies
build files generated by the framework during the build process (you can ignore these!)
config Global configuration files
cutparts SCAD files for any cut parts
docs Generated documentation including assembly guide(s) and vitamin catalogue
framework the framework, embedded as a git submodule
images Generated images of the machine
printedparts SCAD files for the printed parts of your machine
sandbox Playground for developing parts, assemblies, etc
vitamins Rendered images of non-printable parts (e.g. motors, switches, nuts, bolts), the actual vitamin source code is contained within the framework

You can check everything is laid out and working correctly by opening the hardware/QuadFrame.scad file. OpenSCAD should open and preview a small cube. You shouldn't have any error messages in the console. :)

You can also test the Python utility scripts are working properly by:

  1. Open a terminal
  2. Navigate to the /hardware/framework directory
  3. Run ./build.sh to run the build process - this will take a while!

A lot of status messages should fly by, with the last line being "Build Complete". If you look in the /hardware/images directory, you should find a single image file QuadFrame_view.png showing a small cube. This image will get a lot more interesting once we've created some parts!

Key Concepts - Parts and Assemblies

Models of complete machines are comprised of a few fundamental building blocks:

  • Vitamins - are the physical parts you use as-is (not make) within your machine (e.g. screws, motors, batteries), majority of these should be reusable between different projects
  • Printed-parts - are the parts you will print on a 3D printer
  • Cut-parts - are the parts you make using a non-printing fabrication process (e.g. cutting, drilling, bending)
  • Assemblies - represent how the vitamins, printed-parts and cut-parts should be put together

Vitamins, printed-parts and cut-parts are collectively referred to as parts.

Assemblies are typically arranged in a hierarchy, with a top-level assembly containing a combination of parts and sub-assemblies.

A typical design process will rapidly iterate over the following steps:

  • Import, or develop, the key vitamins (often drive systems and electronics)
  • Layout groups of vitamins within assemblies
  • Develop the printed parts to hold the vitamins together
  • Print, test, repeat

Project teams can often tackle these steps in parallel, with team members owning development of the various vitamins, printed-parts and assemblies. Collaboration techniques are covered in a later tutorial.

Defining our machine

The machine SCAD file (/hardware/QuadFrame.scad) is primarily a "wrapper" around your top-level assembly, but it also links in the global configuration file (/hardware/config/config.scad) and provides information to the build process about the project.

We'll return to edit this file once we've created our top-level assembly.

Creating the top-level assembly

The top-level, or final, assembly is where you define how all the various parts come together. It is purely for on-screen display, either in OpenSCAD or in the assembly guide, but is critical to helping you correctly model your machine. It's also one of the best places to start a new design.

Creating a new assembly file requires a few steps, however, there is a utility script that automates most of the process:

  1. Open a terminal and navigate to /hardware/framework/scripts
  2. Run ./adda.py assembly Final "Final Assembly"

The parameters for adda.py represent:

  • assembly - Create an assembly (the same script can also be used to create other parts)
  • Final - this is both the filename for the new assembly (the .scad extension will be added automatically) and the prefix to the module name (e.g. FinalAssembly())
  • "Final Assembly" - this is the descriptive name of the assembly, as used in the generated guides

The adda.py script will:

  • Create a templated assembly file at: /hardware/assemblies/Final.scad
  • Add the assembly to the global configuration (/hardware/config/assemblies.scad)
  • Create a sandbox file to aid with developing your assembly at: /hardware/sandbox/assembly_FinalAssembly.scad

Open the assembly file (/hardware/assemblies/Final.scad) in your text editor, it should look something like this:

module FinalAssembly () {

    assembly("assemblies/Final.scad", "Final Assembly", str("FinalAssembly()")) {

        // base part

        // steps
        step(1, "Do something") {
            view(t=[0,0,0], r=[52,0,218], d=400);

            //attach(DefConDown, DefConDown)
            //      AnotherAssembly();
        }

    }
}

The FinalAssembly module represents the assembly, and critically, it contains as assembly() statement. The assembly() statement tells the build-system to treat this as an assembly and to show the assembly steps in generated guides. The assembly statement takes three parameters:

  1. The location of the the current file (relative to the /hardware directory)
  2. The description of the assembly, as used in generated guides
  3. How to call the module from within OpenSCAD scripts - this is critical to the build system

Within the assembly() statement are:

  1. A call to the base part - the part you start with when assembling this assembly, typically this is a printed part (e.g. a base plate), but may also be a key vitamin that has other parts attached to it (e.g. a motor)
  2. A sequence of assembly steps - defined within step() statements

A step() statement takes two parameters:

  1. The step number (use integers, from 1 upwards)
  2. The assembly instructions for the step - these are inserted directly into the assembly guide and can contain markdown syntax

Each step() statement then contains:

  1. Any views that should be rendered by the build system and included in the assembly guide
  2. The part(s) that should be attached to the base part in this assembly step

Don't worry about the contents of the step() statement for now, we'll come back to that later in the tutorial.

We have one more small change to make before we start integrating parts into this assembly - we need to add this assembly to our machine file:

  1. Open '/hardware/QuadFrame.scad'
  2. Replace from //Top level assembly to cube([10,10,10]) with FinalAssembly();
  3. Save the changes

At this point, opening /hardware/QuadFrame.scad in OpenSCAD will show a blank screen, as the FinalAssembly doesn't yet contain any parts!

Using the vitamin catalogue

As mentioned above, the best way to start a designing a part is by first laying out any associated vitamins within an assembly. With that in mind, we'll first layout the 4 motors for our quadcopter, before designing a printed frame to hold them.

All of the library vitamins are located in the /hardware/framework/vitamins directory. The associated source code should all be clearly structured, but reading through lots of SCAD files is not the quickest way to get started. Instead, the framework generates a Vitamin Catalogue to make life easier.

Like all of the auto-generated documentation, it is produced in two formats: markdown and HTML. The HTML version is actually dynamically rendered from the markdown file, which unfortunately means it can only be viewed through a local web server (due to browser security restrictions). If you have a local web server configured, then navigate to /hardware/framework/docs/VitaminCatalogue.htm. Otherwise, grab yourself a markdown viewer (e.g. LightPaper) or text editor and open /hardware/framework/docs/VitaminCatalogue.md.

NB: You can also view the live reference catalogue on github here: Vitamin Catalogue

You should see a long list of vitamins that are available for use in your project, including all the part variants that can be generated by each vitamin SCAD file. Alongside a description and image of each part is the associated call statement that you should use in your project.

Locate the section for the DCMotor.scad file and look for the CL072014 DC Motor part. The associated call statement should be DCMotor(DCMotor_CL072014). This is a basic model of the motors used in the Hubsan X4 and is what we'll use to help layout our printable frame.

Including the motor vitamin in your machine

Now we've located an appropriate vitamin in the library, we need to add it to our project. This is a two step process:

  1. Make sure the relevant vitamin SCAD file is included in our global configuration
  2. Call the appropriate vitamin from within an assembly

To include the DCMotor.scad file in our global configuration:

  1. Open /hardware/config/vitamins.scad in your text editor
  2. Append this line: include <../framework/vitamins/DCMotor.scad>

The /hardware/config/vitamins.scad file lists all the include statements for vitamins we are using in our project. It's best to keep these in alphabetical order for readability.

Now let's add the DCMotor(DCMotor_CL072014) call to our assembly. Open /hardware/assemblies/Final.scad in your text editor and modify the step() statement to the following:

step(1, "Insert the motors") {
    view(t=[0,0,0], r=[52,0,218], d=400);

    attach(DefConUp, DCMotor_Con_Face)
        DCMotor(DCMotor_CL072014);
}

If you open /hardware/QuadFrame.scad in OpenSCAD, you should see the DC motor model centered on the origin. Clearly we are going to need more than one motor, but first let's specify some global machine parameters to define the layout.

Global machine parameters

Global machine parameters are available in every assembly, part, etc and should be used for the key parametric values of your design. For our quadcopter layout, we'll keep things simple and assume the frame will be symmetrical with the arms arranged in a cross - the X layout. This means we only need to define one parameter for the length of the arms:

  1. Open /hardware/config/config.scad in your text editor
  2. Insert the following line below // Global design parameters: ArmLength = 85/2;
  3. Save and close the file

This ArmLength is based on the Hubsan X4 having a diagonal distance of approx 85mm between motors. You're welcome to choose a different ArmLength for your design.

Laying out the motors

Now we have our ArmLength global parameter, we can roughly layout the motors within the assembly. To do this, let's change the code where we previously attached a single motor to:

for (i=[0:3])
    rotate([0,0, 45 + i*90])
    translate([ArmLength,0,0])
    attach(DefConUp, DCMotor_Con_Face)
    DCMotor(DCMotor_CL072014);

Previewing the machine in OpenSCAD should now show 4 motors laid out in a cross.

Adding a new printed part to the machine

Now it's time to create a new printed part for the frame - as with the assembly, the Python utility automates the process:

  1. Open a terminal and navigate to /hardware/framework/scripts
  2. Run ./adda.py printedpart Frame Frame

The adda.py script will:

  • Create a templated printed-part file at: /hardware/printedparts/Frame.scad
  • Add the printed-part to the global configuration (/hardware/config/printedparts.scad)
  • Create a sandbox file to aid with developing your part at: /hardware/sandbox/printedpart_Frame.scad

Open the printed-part file (/hardware/printedparts/Frame.scad) in your text editor, it should look something like this:

// Connectors
Frame_Con_Def = [[0,0,0], [0,0,-1], 0,0,0];

module Frame_STL() {
    printedPart("printedparts/Frame.scad", "Frame", "Frame_STL()") {

        view(t=[0,0,0],r=[72,0,130],d=400);

        if (DebugCoordinateFrames) frame();
        if (DebugConnectors) {
            connector(Frame_Con_Def);
        }

        color(Level3PlasticColor) {
            if (UseSTL) {
                import(str(STLPath, "Frame.stl"));
            } else {
                Frame_Model();
            }
        }
    }
}


module Frame_Model()
{
    // local vars

    // model
    difference() {
        union() {
            cube([10,10,10]);
        }


    }
}

Don't worry t0o much about the contents, for now let's add the Frame to our assembly:

  1. Open /hardware/assemblies/Final.scad in your text editor
  2. After the // base part comment add the line: Frame_STL();
  3. Save and close the file

At this point, if you preview the machine in OpenSCAD you won't see anything new except for a warning in the console stating WARNING: Can't open import file '"printedparts/stl/Frame.stl"'.. This is because our new part is still in development and we've not yet run the build tools to generate the associated STL.

This is where the sandbox comes into play - it allows us to work on new parts before running the build process. Open the /hardware/sandbox/printedpart_Frame.scad file in OpenSCAD and you should be able to see the new part (just a small cube).

Refining the Frame

We can now refine our frame design within the Frame_Model() module at the bottom of the /hardware/printedparts/Frame.scad file.

Here's a basic frame design to get you started - refine/change it as much as you'd like:

module Frame_Model()
{
    l = ArmLength;
    aid = DCMotor_RearCan_OD(DCMotor_CL072014) + 0.5;  // dia of motors, inc tolerance
    aod = aid + 2 * 2.5; // outer dia of motor holders
    ll = 15;  // leg length
    w = 25;  // width of central plate

    difference() {
        union() {

            // arms
            for (i=[0:3])
                rotate([0,0,45 + i*90]) {
                    // Nice rounded end
                    hull() {
                        translate([l, 0, -tw])
                            cylinder(r=aod/2, h=tw);

                        translate([l-aod, -tw/2, -tw])
                            cube([1, tw, tw]);
                    }

                    // Rest of the arm
                    translate([0, -tw/2, -tw])
                        cube([l, tw, tw]);

                    // basic landing leg
                    translate([l-aod, -tw/2, -ll])
                        cube([tw, tw, ll]);
                }

            // central plate for fixing battery and flight controller to
            translate([-w/2, -w/2, -tw])
                cube([w, w, tw]);
        }

        // holes for motors
        for (i=[0:3])
            rotate([0,0,45 + i*90])
            translate([l, 0, 0])
                cylinder(r=aid/2, h=100, center=true);


    }
}

The resulting frame should look like this in OpenSCAD:

Run the build process

Now we have a basic frame design, we can run the build process and explore the results:

  1. Open a terminal and navigate to /hardware/framework
  2. Run ./build.sh

The build process will take a minute or so to complete, you can see a fairly verbose output in the terminal window. Once the process has completed, let's check a few things:

  • Open the machine SCAD file /hardware/QuadFrame.scad in OpenSCAD, you should now see the frame with motors

Guides

  • Open /hardware/docs/QuadFrameAssemblyGuide.htm (served from a web server) or open /hardware/docs/QuadFrameAssemblyGuide.md in a markdown viewer - you should see a section for the Bill of Materials and assembly instructions for the Final Assembly (albeit one step)
  • Similarly, there is a:
    • Printing Guide - listing the parts that need to be printed and approx volume of plastic/cost
    • Sourcing Guide - listing where you can buy the various vitamins (which will be blank at this point, as we've not defined any sources)

Printable STLs

  • Browse to /hardware/printedparts/stl and open the Frame.stl file (e.g. in Meshlab, Netfabb, MeshMixer, etc) - this is the STL for the frame, ready to print

If you're keen and have the relevant hardware, you could test print the frame and check:

  • The motors fit correctly - not too tight, not too loose
  • The arm lengths are as expected (i.e. 85mm diagonal distance between motors, 60mm between adjacent motors)
  • Whether the thickness, stiffness, strength of the part seems sufficient - this part is small enough to consider destructive testing

Refining your design

Based on your findings, you'll probably want to refine the Frame design further. Obvious improvements:

  • Somewhere for the LEDs to go
  • Something to help keep the wires neat (perhaps little retaining clips)
  • Nicer landing legs - perhaps a curve or two

Summary

This concludes the first tutorial in the series. If you've made it this far you should have a good idea of how you'd add additional parts, assemblies and/or incorporate additional vitamins. In the next tutorial we'll be covering all of those aspects in more detail, as well as how to use various utility libraries and customising the generated documentation.

Back to Tutorials page