OpenSCADMD_Tutorial1 - swindonmakers/wiki GitHub Wiki
OpenSCAD Machine Design - Tutorial 1
Basic quad frame layout with motors
In this first tutorial, we're going to cover:
- Starting a project, python 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
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, Python 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.6). As such, you will need to ensure you have a compatible version of Python installed along with a couple of dependencies:
- PIL - the Python Image Library - use:
pip install pillow
- Pystache - the Pystache template library - use:
pip install pystache
Cloning the template
Once you have the pre-requisites installed, you can copy, clone or fork the template project from github:
Rename the root directory to something meaningful for this project, e.g. "QuadFrame"
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 (named "OpenSCAD_Machine_Design_Template.scad" in the template) |
assemblies | SCAD files that describe all the assemblies/sub-assemblies |
ci | Python utility scripts |
config | Global configuration files |
cutparts | SCAD files for any cut parts |
docs | Generated documentation including assembly guide(s) and vitamin catalogue |
images | Generated images of the machine |
printedparts | SCAD files for the printed parts of your machine |
sandbox | Playground for developing parts, assemblies, etc |
utils | Utility scad files to provide assembly functionality, speed modelling, etc |
vitamins | Models of all the non-printable parts (e.g. motors, switches, nuts, bolts) |
You can check the template files are laid out correctly by opening the hardware/OpenSCAD_Machine_Design_Template.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:
- Open a terminal
- Navigate to the
/hardware/ci
directory - Run
./catalogue.py
to update the Vitamin Catalogue
A lot of status messages will fly by, with the last line being "Saving markdown". We'll explore the Vitamin Catalogue in more detail later in this tutorial.
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)
- 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
Before we start modelling our parts, we need to setup our machine SCAD file:
- Rename
/hardware/OpenSCAD_Machine_Design_Template.scad
to/hardware/QuadFrame.scad
- Open
/hardware/QuadFrame.scad
in your favourite text editor - Change the line:
machine("OpenSCAD_Machine_Design_Template.scad","OpenSCAD_Machine_Design_Template") {
tomachine("QuadFrame.scad","My Printable Quadcopter Frame") {
NB: It's generally good practise to use the same name for the machine SCAD file as for the root project directory.
The machine SCAD file is a primarily a "wrapper" around your top-level assembly, but it also links in the global configuration file (config.scad) and provides information to the build process about the project. Critically, the line you edited in step 4 tells the build process the name of the machine file and the description to use in the assembly guide.
We'll return to edit this file once we've created our top-level assembly. For now, just check it previews without errors in OpenSCAD.
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:
- Open a terminal and navigate to
/hardware/ci
- Run
./adda.py assembly Final "Final Assembly"
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 is an OpenSCAD module, contain as assembly()
statement. The assembly()
statement tells the build-system to treat this as an assembly and to show the assembly steps. It takes three parameters:
- The location of the the current file (relative to the
/hardware
directory) - The description of the assembly
- How to call the module from within OpenSCAD scripts - this is critical to the build system
Within the assembly()
statement are:
- A call to the base part - the part you start with when assembling this assembly
- A sequence of assembly steps - defined within
step()
statements
A step()
statement takes two parameters:
- The step number
- The assembly instructions for the step - these are inserted directly into the assembly guide and can contain markdown syntax
Each step()
statement then contains:
- Any views that should be rendered by the build system and included in the assembly guide
- 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:
- Open '/hardware/QuadFrame.scad'
- Replace from
//Top level assembly
tocube([10,10,10])
withFinalAssembly();
- Save the changes
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 before before designing a printed frame to hold them.
All of the library vitamins are located in the /hardware/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 machine design template 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/docs/VitaminCatalogue.htm
. Otherwise, grab yourself a markdown viewer (e.g. LightPaper) and open /hardware/docs/VitaminCatalogue.md
.
NB: You can also view the live reference catalogue on github here: Reference Vitamin Catalogue
You should see a long list of vitamins that are available for use in your project. The variety of parts that can be generated by each vitamin SCAD file are shown. 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 vitamins/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 machine. This is a two step process:
- Make sure the relevant vitamin SCAD file is included in our global configuration
- Call the appropriate vitamin from within an assembly
To include the DCMotor.scad
file in our machine:
- Open
/hardware/config/vitamins.scad
in your text editor - Append this line:
include <../vitamins/DCMotor.scad>
The /hardware/config/vitamins.scad
file lists all include statements for vitamins we are using in our machine. 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. 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:
- Open
/hardware/config/machine.scad
in your text editor - Add the following line to the end of the file:
ArmLength = 85/2;
- 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 add a new printed part for the frame - as with the assembly, the Python utility makes this very quick:
- Open a terminal and navigate to
/hardware/ci
- 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 to much about the contents, for now let's add the Frame to our assembly:
- Open
/hardware/assemblies/Final.scad
in your text editor - After the
// base part
comment add the line:Frame_STL();
- 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 to explore the results:
- Open a terminal and navigate to
/hardware/ci
- Run
./build.py
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 in OpenSCAD, you should now see the frame with motors
-
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) -
Browse to
/hardware/printedparts/stl
and open theFrame.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
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.