Giles Hall Laser Cutters, 3D Printers, and Python PyCon 2016

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[applause] Hi there, how are you doing? Thank you so much for coming. So, I am here to talk about using Python to generate designs for 3D printers and laser cutters, but first I want to talk about myself and introduce myself. That's my email address and my GitHub repository. So, I work at a start-up in Boston called Ginkgo Bioworks. We apply techniques from synthetic biology and genetic engineering to build custom organisms for our customers. We build thousands of custom strains, and to do this at scale, we rely heavily on Python to help us design, track, and analyze our engineered samples. And if you're interested about Ginkgo, you can learn more about us at ginkgobioworks.com. We are hiring. In my spare time, I like to explore a lot of different hobbies, and that includes things like photography and gardening and cycling and cooking, electronics and making art. And for each one of my hobbies, I've at least written like a handful of Python scripts to facilitate it one way or another. So here's a quick example: in my backyard, I have a Davis weather station. This transmits weather data wirelessly to a Raspberry Pi in my house, and I have another Raspberry Pi in my basement that monitors this data and controls a set of relays that switch on sprinklers to water the garden. So Python for me, it's not just a programming language. It's one of the primary means I use to express myself creatively. But as powerful as Python is, programming by its very nature is not a physical medium. Frederick P. Brooks wrote one of my favorite quotes about computer programming in his book "The Mythical Man-Month." (reading quote) And the world is filled with these amazing but nebulous castles but we can't really appreciate them without the aid of a computer. You can't share your code like you would a painting, or a sculpture, or a well-cooked meal. And, you know, to be honest, I realize that this is not true. Like, we use software to manipulate our physical world every day. Our computers produce sound and light and they churn out printed documents. There are many ways that you can write code to affect the physical world. And that's the core of what I want to talk about. But first, a little history. Before there were computers, people had to make things by hand. The period between the late 19th century and the middle of the 20th century was collectively known as the Machine Age. And during this time, we perfected the art of building parts at an industrial scale using a process called subtractive manufacturing. This includes techniques such as: milling, turning, boring, broaching, sawing, reaming, tapping. The general idea was to shape bulk stock into some kind of part by removing material with incredible precision. But after the 1950s, the world entered the Atomic Age and ushered in the digital computer. And during the 1940s and 50s, existing tools like mills and lathes were connected to electric motors that were controlled by punch tape. This was the first step towards automation of these machine tools. And as computers evolved in sophistication, it spawned a new field of fabrication called computer numerical control, also known as CNC. So today, computer-controlled automation is ubiquitous throughout all areas of manufacturing. Not only has the computer hardware and software programming evolved to such a point of sophistication, but there are new manufacturing tools and processes that had never existed just a few decades prior. This includes things like plasma cutters and water jets and 5-axis milling machines, lithography, and two of my personal favorites: laser cutters and 3D printers. So, we're going to examine each one of these technologies individually, and then we're going to discuss how we can use Python to generate designs for these tools. So first, laser cutters. Laser cutters are devices that utilize high-powered lasers to etch or cut a variety of different materials. Most commercially available laser cutters are capable of cutting and etching paper or wood, plastic, leather, fabric, up to a certain thickness. And the laser tube itself is static to the device, typically mounted towards the back of the machine. Carefully positioned mirrors bounce the laser light to the laser head, and the laser head itself is composed of mirrors and lenses that focus the laser beam onto the target material. Stepper motors then move the laser head in the X and Y plane parallel to the work material, thus allowing the laser to trace out the contours of a given design. Laser cutters are incredibly precise and they're capable of producing just really complex and intricate detail in your design. Digital design for laser cutters though, typically start as vector graphics. This is, you know, design programs like Adobe Illustrator and Inkscape are vector illustrator packages. This is in contrast to programs like the GIMP or Photoshop which are raster or bitmap oriented graphics packages. Vector graphics make it easy for the software controlling the motion of the laser cutter to translate your graphics into motion. The process of creating laser cut designs is relatively straightforward. After you think about what your design should look like, you need to pick the material that you want to use and the size. Generally speaking, if you're cutting with a laser cutter, thinner is better than thicker. Your design should then be sized according to the constraints of the material you're cutting out. But with vector graphics you can scale your designs without losing any fidelity of your design. Most laser cutter software then requires you to indicate which parts of your design are meant to be cut versus which should be etched. This can be achieved with a color of the line, for example, red for cut or blue for etch. And then when you're ready to execute your cut, you position your material on the laser bed, and you focus the laser beam, and you upload your design file. Every laser cutter, to be honest, is a little different, so the specifics of how that actually gets done is dictated by the company that makes that specific cutter. So, you can upload your designs as PDF or EPS, but I personally prefer SVG. SVG files are XML documents and a closely-related cousin to HTML. HTML and SVG share a lot of attribute names for various tags, like width, height, style, and border. They share style syntax as well, and later revisions of SVG actually support cascading style sheets. This is a simple example of an SVG document. You can see the two tags: rec for rectangle, and circ for circle. The rectangle tag takes an XY position to define its top-left corner and a width and height value to define its size. The circle, on the other hand, requires an x and y coordinate to define its center, and another value for its radius. And each of these objects take parameters that define how the shape is stroked and filled, that is, with what color. But as you can see, you can get relatively complex designs with just a few lines of code with an SVG. My personal favorite feature of SVG are paths. A path is simply a list of connected line segments that are used to build complex polygons. A path segment can be a straight line or a curve spline with control points. Within the SVG document, the path is defined by a string of characters. It's broken up into single letter commands like m for move or l for line, and then two or more numbers that represent the coordinate of that command. You can do a lot with just circles and squares, but paths allow you to build incredibly complex shapes. And in this example, I just rattled off a few random points to make this squiggly line. So, for this talk I wrote a Python program to generate a laser-cuttable cube or box that uses finger joints. Even though this design originates in 2D space, when you put it together like a puzzle it produces a three-dimensional shape. The program itself is a few hundred lines of code so we won't be able to discuss it in its entirety, but you can go check out my GitHub repository after this talk, and look at the code, and look at the various options that allow you to change its design. I brought a bunch of examples as well, and so if you come find me, I can show them to you. And I'm gonna auction these off later at the PyLadies auction. So, this is what one of the generated designs looks like that is sent verbatim to the laser cutting control software. You can see that the layout of the design packs the faces closely together to minimize the overall waste of the material. And you can see that it's not the same face over and over again. There are slight differences between each of the individual faces. And that's to help the puzzle-like way that it fits together. And so this is the result of what you get when you cut that design on wood. You can see the scorch marks caused by small flare-ups as the material briefly ignites from the laser. As a bonus the board has this nice, refreshing burnt wood smell. Since the cube fits together like a puzzle, the edges of each face must interlock. I think of these edges as being either positive or negative, dependent upon whether they have a outer edge to them or an inner edge to them. And I've color coded them to distinguish this feature. So in this case, red is positive and green is negative. So, as we kind of dial in, we can just think about a single edge on a single face, and consider the code that we would need to write in order to generate it. The width of the material dictates the height of each individual finger, and the length of the edge combined with the number of fingers that you want in your design dictates the overall width of the finger itself. And so from these configurable parameters, we can write a function to draw a single edge. And this is what that code looks like. This function takes the size of a cube face as a tuple, the number of fingers in an edge, the width of a single finger, and the thickness of the material, and it calculates various geometrical offsets. First, we use the size of the face in order to find its center. Along with the number of fingers in the finger width, we use the center position then to calculate where our first point in the edge line should occur. We then build two lists of positional offsets, one for the finger width, and the other for the finger depth. And we iterate through each point along the edge, calculating the offsets for each. The code exploits the fact that every other point moves forward through the edge, and every second point raises the edge and every fourth point lowers it. So we use a modulus operator to replay those offsets as we build the edge profile. And here is an example of how you would call that previous function. Since the previous function was a generator that returns a list of positions, the caller takes those points and translates them into a string that is formatted as an SVG path. You can note that the first command is an M command because we want to move to that position. And then it's followed by L commands to actually draw those connected line segments. And that's the result of what we've drawn. This is obviously only a small piece of the overall box generator, but it's central to the design. The code is object-oriented and relatively easy to follow. You can configure and customize it in many different ways, such as the size of the box, the thickness of the material, and the designs on the box faces themselves. So for example, since the box generator itself has a base class that defines a geometric rules for each face, you can inherit from this class and hook into it's rendering method. In this example, I've added a Fermat's spiral. This is a simple mathematical function that generates a pattern that is reminiscent of the pattern of seeds you would find on the face of a sunflower. And this is the code that is used in order to generate that. Rather than going through this in detail, I just want to highlight this idea that you can come up with interesting artifacts like that and embed it in part of -- in your overall larger design. It's very easy to do, once you figure out kind of the base of your object, to add these kinds of artifacts that give your design more flavor. And this is the resultant image that is generated from that. So, SVG makes it really easy to layer in new elements and add to the design without requiring you to change the overall structure of the SVG document itself. Coupled with Python, it's the perfect technology to express your laser-cuttable designs. Whoops. Alright. So, 3D printers. 3D printers are devices that can build three-dimensional objects. They range in price and sophistication, but the most common 3D printers available are known as fused deposition models. These work by breaking down three-dimensional objects into 2D slices that, when stacked one on top of the other, will reconstruct the geometry of the three-dimensional object. FDM printers, specifically, work by extruding plastics at really high temperatures. But unlike laser cutters, 3D printers work in three axes instead of two. The X and Y axes are utilized by the printhead to deposit the material in a desired shape, and the Z axis is then used to advance the model to the next two-dimensional slice. This is a high-level design pipeline for 3D printers. Most 3D printing software consumes STL files and produce what is known as GCODE files. But STL files are not easy to generate by hand since they actually represent the three-dimensional object in a triangle mesh form. Personally, I don't think about my three-dimensional designs as a mesh of triangles. I like to think about them as solid objects. About five years ago my girlfriend and I purchased our first 3D printer, and we were so excited about it that we were obsessed about all the things that we were going to design and make on it. But I was immediately frustrated with the standard tools out there that people typically used to design CAD models for printing. You know, I'd spend hours in programs like SketchUp building up a complex design only to realize I needed to change something core to the model. Most of the design tools do not make it easy for you to make these kinds of drastic changes. It's kind of like painting a family portrait and realizing you left out your brother. So, there are more sophisticated 3D modelers out there, including some that are parametric. But most are expensive or only run in Windows or are difficult to learn, or typically all three. So I looked around to find a programmatic solution that I would find more comfortable and that's how I discovered something called OpenSCAD. OpenSCAD utilizes constructive solid geometry. The idea is to build your objects from two-dimensional and three-dimensional primitives such as cubes, cylinders, and spheres. You position these objects in space and then you define boolean operations between them. The most common boolean operation is union, to join two or more solids together as one. And then there is difference, which is used to subtract one or more solids from another. So for example, let's just take a drinking glass. We can construct it with just two cylinders. The first cylinder -- sorry, the top got cut off but we'll see the code later. The first cylinder describes the outside surface and the second describes the empty volume inside. Using OpenSCAD, we would define the first cylinder with a second cylinder inside. The inside cylinder would then be offset in the Z axis, or the up axis, and would have a smaller radius than the outer cylinder. We would then subtract that inner cylinder from the outer cylinder to create that empty envelope. In order for this to work, we have to make sure that it leaves the floor of the glass but creates the mouth as well, and that's why we do the offset. So this is what your two cylinders would look like. And you can see in the third line of code, there's a translate operation. And that is what moves that inner cylinder up to create the floor of the glass and the mouth of the glass. Right now I have this as a union of two objects to highlight the fact that these two cylinders are inset, but by changing that top union to a difference, we then create the empty volume that we're aiming for. OpenSCAD does all of the hard, complicated math to calculate the mesh for these objects, freeing us up to think about how to construct our models with just primitive shapes. I think it's impressive to consider what we can build with just four lines of code. But the scripting language for OpenSCAD is relatively simple in and of itself, and doesn't really provide a lot of the features that we know and love from Python. But with the simplicity of OpenSCAD in our favor, we can easily then generate OpenSCAD from Python. So, for a more complicated example, we're going to consider a flower pot. Flower pots are similar to drinking glasses, but they also have a few distinct features. First, most flower pots are wider at the top and smaller at the bottom. Although we think about the shape as a cone, it's often described as a cylinder in OpenSCAD because you can define a cylinder with two different radiuses for each end. Second, they usually have a hole at the bottom to facilitate drainage. And finally, they often provide a lipped collar at the top to make it easy to hold and move the pot around. So now that we have a feel for OpenSCAD syntax, let's talk about how we can generate this design from Python. There are a few different Python libraries that allow you to build OpenSCAD syntax from Python, including a library that I've written called Python SCAD. Most of these libraries work in very similar ways, wrapping OpenSCAD definitions with Python classes. For my demo, I'll be using my library but you can accomplish the same thing with any of the other alternative libraries out there. So, most of my SCAD objects that I write in Python start out like this, with a series of parametric variables that help define the physical constraints of the object. I try to write a few top-level variables that are designed to be flexible, and then compute other variable values based on those initial values. In this example, many of the variables for the flower pot are derived from the flowerpot's overall height. This makes it easy to change the overall size of the flower pot without having to change each individual variable. You can also see that I have -- as an example, I have ratios in there that define, for example, the top radius versus the bottom radius. You know, I went around measuring flower pots around my house and found that it was typically about a .6 ratio. And along with things like the thickness or the wall thickness of the pot itself, because we have to calculate our offsets in order to do the subtraction. So this is all the code that is required to then produce that pot. It's, to be honest, much simpler than the cube for the laser cutter. It's pretty boring, actually. We start from the outside and add other cylinders to carve out the spaces we need. It's built entirely with the cylinder primitive along with unions and translations. Really the only hard part is imagining your model and then breaking it down into primitive solids. Once you've done this, building the design and code is incredibly straightforward. So, this is my printer at home building a 2.5 inch flower pot which is right here. It took about two hours to print, but one thing you'll notice is that it's printing an outer wall that's actually not part of the design. This wall is generated by the printer software and is known as a support material. The lip of the flowerpot overhangs in space and without that support material, the printer wouldn't be able to successfully print that overhang. But you can just tear it off once the print is done. And there's the finished result. So, now I'm going to talk about two projects I have done with laser cutters and 3D printers that are more complicated, and the code is available for these projects. But it's to kind of whet your appetite of, beyond these simple examples what else can you do with it? So to start off first is my snowflake generator. This project, my girlfriend and I started about four years ago. We were trying to figure out what to make our friends and family for the holidays. And Rachel found this amazing paper that describes a physical model to simulate the growth of snowflakes. We translated the math from this paper into Python code and proceeded to make personalized snowflakes for everyone on our gift list. The model works at the mesoscopic level, which is to say it models a collection of molecules, specifically water molecules as an undefined unit. And it starts off first by constructing a hexagonal grid. The grid is then populated with a homogeneous field of water molecules. And these water molecules can move from one neighboring cell to another and can switch between three defined states: vapor, boundary, or frozen. The boundary state is often used to describe water that is neither vaporous or frozen, but caught in between those two states. The initial field of water molecules are set to a vaporous state, except for the cell in the middle, which is initialized as a frozen state. And then, from there, the simulation runs and the snowflake begins to form. The model takes eight different parameters which dictate the behavior of these individual steps in the algorithm. So each cell does these individual calculations for its own state. It first figures out how the vapor of the cell should move. And then it figures out if some of it should freeze to the boundary vapor. And a portion of the frozen boundary cells then attach to the body of the snowflake. And then a certain portion of them melt off. And finally, as a parameter for noise, which I think is really beautiful, it adds just a little bit of randomness to the overall simulation. And what you end up are not perfectly symmetrical snowflakes, but snowflakes with slight defects with respect to their individual arms. So, from a grid perspective, as the simulation progresses, the snowflake crystal begins to grow out from its initial seed, so you can see the frozen state in the middle, and then the boundary seeds around it. And the program works like a cellular automata simulation. Each cell inspects its neighbors and calculates its changes based on the parameters But because there's hundreds of thousands of cells, the simulation is computationally intensive, taking hours to run. In order to generate the hundred snowflakes we made as a gift, actually, we generated all of our snowflakes in the cloud. [laughter] [applause] So, the result of this simulation is a complex bitmap. But instead of capturing red green blue intensities on a Cartesian grid, this bitmap stores the density of the frozen water molecules within a hexagonal grid. When the snowflake reaches a certain predetermined size, the simulation stops and the program proceeds to translate that snowflake into SVG files. Two SVG files are produced and merged. The first SVG file is a representation of the densest bands of frozen water molecules in the snowflake. That is where the most common abundance of water that froze, and there are these bands of density that you can see. And the second SVG actually defines the outline of the snowflake, and these two files are merged into a single SVG and then sent to the laser cutter. So, I have a kind of a cool video that just describes this whole process. One thing that really astounds me about this model is that it can generate just an amazing variety of different kinds of snowflakes. And very much with each not looking like the last. So this is -- I ran the simulation saving an image of the snowflake at every step, so this shows you the overall growth of it. You can see the black aura around it, and that's actually the depleted vapor that it's sucking into the body of the snowflake, while the gray area is still vaporous water. And here we are etching and cutting one of the snowflakes. So, you can see right here the laser cutter is in an etching mode, where it is just pulsing the laser and just ablating the surface of the plastic off to make a depression in the plastic but then not actually cut it. And then once it's done, it does the cutting step, which allows us to remove the snowflake. And again, I have brought examples of these guys, so if you want to, come take a peek at them after the talk. Alright, so the other example that I want to show you is something that I called Rockit. So, this is a model rocket construction kit. You know, this is kind of the first project I did with OpenSCAD and Python, and I wanted to make something functional, right? I wanted to be able to print something off my printer and have it actually do something. And so I made this model rocket generator that can design and print a range of different rockets and rocket types. So if you're not familiar with model rocketry, you should know that there are a range of different engine sizes. And these engines are made of solid propellant packed into a cardboard tube. The sizes of these engines vary in length and diameter, requiring different-sized engine holders to start a design. When you start a design, you first select an engine and then Rockit will calculate a bunch of different parameters for the rocket based on that engine size. Another neat feature of Rockit is that it uses these coupling sleeves that allow you to snap together the rocket like Legos. I mean, you can literally just print this off your printer, snap it together and then launch it. But I recommend using glue because it will probably come apart in flight. [laughter] And you can even print the base with that coupling sleeve and that will allow you to make multistage rockets. Rockit makes it very easy to change different aspects of your design. For example, you can swap in different kinds of nose cones, or you can add or remove fins, or one of my favorite features is to tilt the fins so that when the rocket is launched, it rifles up into the sky. But what I think is really fantastic about this is that you can print two very similar rocket designs with a slight tweak between them and they'll be very -- it's a very reproducible process. So you can empirically evaluate how you have changed the performance of your design. So, my friend Adam videotaped this one launch, and it's unfortunately the only video footage I have, and it's a pretty disastrous launch. But it does work. I believe this is one of the ones that had spiral, so it spiraled up into the air. But the weight ratio to the engine size was not calibrated, and so it also then promptly took a nosedive. But that's the best part -- I mean, these rockets, to be honest, they're not the most robust thing. I mean, it's plastic, and plastic doesn't like heat, and so you're likely to melt them, but I say who cares? Just go home and print some more, you know? You'll definitely at least get a few flights out of it. But yeah, I just -- what I think is just so neat about this is that you can print something off your printer and stuff a rocket engine in it and it will fly. Anyway, you may be asking yourself, how do I get access to these tools? So I realize that not everybody has these at their disposal. And in Boston, where I'm from, there are a number of local maker spaces that provide access to 3D printers and laser cutters. Some public libraries have also booted up their own maker spaces to provide access to these tools. And if you can't find anything local, you can always use popular internet-based service providers such as Ponoko or Shapeways. For example, I got all of my materials cut at Ponoko before I came to this talk. But the whole field is really rapidly changing and new tools are coming out every year. And as these tools advance, the total cost of ownership comes down in price. These are the relevant GitHub URLs for all the various software that I've written. The top one is a mirror of this talk. But you can also find my snowflake generator, the rocket generator, and the Python SCAD library there. And that's it, thank you very much. [applause] (moderator) So, a few minutes for questions. If you have any, come to the microphones please. (audience member) I'm curious as to why you didn't print your pot upside down. (Giles Hall) That's a great question. The reason is that, um -- the -- the flatness of the bottom of the pot would then be the overhang as opposed to the lip. To be honest, it's probably six of one, half-dozen of the other. But you would imagine that it would have to print a scaffolding into the center of the pot, and I find that to dig out support material is harder than just being able to rip it, so that's why I chose that orientation. (audience member) Thanks. (moderator) So if there are no more questions, let's thank the speaker again. [applause]
Info
Channel: PyCon 2016
Views: 1,580
Rating: undefined out of 5
Keywords:
Id: UwL-ncEr-_I
Channel Id: undefined
Length: 37min 47sec (2267 seconds)
Published: Fri Jun 17 2016
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.