Sunday, April 27, 2014

A Parametric Vise in FreeCAD

This post is for Normand. I promised him that I would show this a long time ago.

In FreeCAD, you can create parametric objects with python scripting. What this means is you can create objects that change by altering their parameters. This makes it nice to create geometric objects similar to what you would find in the Draft workbench- rectangles, polygons, circles, and points are some of the parametric objects that Yorik has created. The Draft and Arch workbenches are pure python, so there are many examples of parametric objects to learn from.

A few months ago, I created a parametric milling machine vise, by importing *.step files from a well know vise manufacturer and worked them into some python scripting. When I first started playing with the script, I was copy/pasting it from my editor constantly, trying it out. This is fine for me to do, at first, when it was just one file to play with, but as the project got larger, it became a pain. I had added an *.svg file for the icon and split the *.step file in two. Things were starting to get a lot larger than my usual one page scripts, so it was time to make a small project out of it.
As the project got a little larger, I realized that this could be a pain for other folks to use, if I didn't clean it up and make it easy to install. I noticed that Yorik had made the dxf import/export part of his Draft workbench into an automatic download with FreeCAD, on the first instance of importing or exporting a DXF file. That looked like a good way to go for my script.

The small script that downloads the other files is here:

Copy and paste it into your FreeCAD python console or into the FreeCAD macro editor and run it with the green play button.

The vise looks like this:

That last image shows the parameter for the jaw opening- it's in metric and you can give it value up to 220 mm and the movable jaw of the vise will open up.

Have fun with it.

Sunday, January 19, 2014

Helping a Boy Scout

My son is in the Boy Scout program, here in the US. I feel that it is a very good program. He has learned some very good skills and had some awesome adventures. We also end up working together on a lot of projects. One of those was helping one of his fellow scouts with his Eagle project. This scout wanted to help a local charitable organization that gives clothes to needy children around the area. The organization didn't have any work tables for sorting clothes or benches for their clients to sit on, while they were waiting outside the door.

The scout working on this project knows that I like to design and build things, so he contacted me about the project. He started by getting the requirements from the charity director and came back with dimensions. We discussed some general design ideas and what materials he wanted to use. The materials would be construction grade timbers and plywood (laminated sheet).

 I needed to make four different designs for these various tables and benches. There were three tables that needed to be different lengths and two benches that should be the same as each other. The tables were all very short, since they were going to be used for stacking boxes and clothes on. We wanted a similar design on all of them, since they were all going to the same place and it would make things easier for volunteers to assemble. After a group assembled one table, the next should be very familiar to them. We decided to make the benches look similar to the tables.

 I decided to use a combination of FreeCAD for design and DraftSight for dimensioned drawings. I like using FreeCAD for design, because I am comfortable with it and feel that it is very powerful. I could start with one design and then change just a few parameters to make it fit the requirements for the next table or bench. I could probably even dimension all the drawings for the project in FreeCAD, but I am much more comfortable doing that in DraftSight.

 Since we don't have an assembly workbench in FreeCAD yet- and I wanted all components to be related/driven by the table top, I did a sort of crude hack to keep everything in sync. I used PartDesign workbench with sketches and made a base sketch that represented the outside dimensions of the table or bench top for every set of components. The corners of the table top sketch were mirrored around X0 Y0 to give some consistency to my hack. I copied this same geometry  from the table top sketch  and pasted into one  sketch and changed it into construction geometry
I copied and pasted this base construction geometry into four other sketches- to mimic the table top.  Here is an example of the sketch construction:

(I am also working in inches on this project but chose not to change units in FreeCAD- so notice that the units in my sketch are in mm)

Within the sketches for everything, except the table top, I used additional construction geometry to space the padded part of the sketches away from the lip of the table top. This would typically be the over hang of the top and the thickness of the timber next to what I was working on:

One problem with this approach is that if I needed to change the length of the piece of furniture that I was working on, I had to change the construction geometry in several pieces to make this work. Since I didn't really care to code up a total parametric table in python, I thought that was a fair trade off. In the end, it wasn't a huge hassle to change the parameters for the 4 unique designs.

I did the components in groups:
1. table top -this was simple- make a sketch and pad it in a positive Z direction.
2. two long timbers for the frame - sketch their perimeters and pad in a negative Z direction.
3. two short cross timbers for frame - sketch their perimeters and pad in a negative Z direction.
4. all four legs - sketch their perimeters and pad in a negative Z direction.
5. two cross braces (mounted towards the floor on outside of legs) - move placement of the sketch to be lower than the table top and pad in a negative Z direction.
6. stretcher (mounted to the inside faces of the cross braces) - move placement of the sketch to be lower than the table top and pad in a negative Z direction.
7. The corner blocks were a little more difficult. They had to be sketched on a plane that was perpendicular to the table sketch. I ended up having to fudge on their locations a bit, but I survived :)

Here is a screenshot of all of the components put together:

In FreeCAD's Draft workbench there is a command to create a 2D projection of a 3D object called Shape2DView. I used that (with the help of a python script to speed up positioning) to create this:

These 2D views were then selected and exported as a *.DXF file for detailing in DraftSight.

We finished up construction earlier today, with the help of a lot of other scouts.

Saturday, November 30, 2013

Parsing Solid Models for Holes

I've been playing with a macro to get hole information (coordinates, diameter, etc) out of solid models in FreeCAD. It is a challenge and I don't think I will ever be totally done, because there are so many corner cases. I am concentrating on the types of parts that I would be milling in my shop- ie blocks of metal that I can drill with a simple 3 axis Bridgeport CNC mill. I will leave the 5 axis stuff to others :) Here is a screenshot of what I have so far:
The lines coming up and out of the holes indicate that I am successful. Here is my macro:

Sunday, October 27, 2013

Welcome to the Monkey Lab

I had a client request that I make an aluminum panel for mounting an LCD monitor and touchscreen for his research group. He supplied the monitor, touchscreen, a light, and a drink dispenser. Hmmm- sounds interesting. Who would be using the touch screen? Monkeys of course. Wow...
Here is how I did it: To begin with, I found spec sheets for the monitor and touch screen online.

I used FreeCAD to make a 3D model of the components and an assembly.
Then I used HeeksCNC to create CNC code for milling out the panel.

Milling the whole thing on my Bridgeport CNC was a challenge. My Y axis travel was barely 10.75" and the cutout for the monitor/touchscreen was 10.3" alone. This meant that I needed to slide the ram that the milling head attaches to back and forth in Y to get the full range. To do that, I had to pick up on a known edge, with my edge finder, several times. That was a bit of a trick, but I got it to work.
Here is a picture of the finished assembly:
My client was very happy with the panel. Maybe I will make another and install it in my kitchen...

Sunday, July 21, 2013

Javascript G-Code Generator

Bolt Circle G-Code Generator
Bolt Circle G-Code Generator
Drill Cycle
Feed Rate
Clearance Plane
X Center
Y Center
Z Depth
Number of Holes
Bolt Circle Diameter
Start Angle


Sunday, October 14, 2012

Heekscnc method of getting data to the python script

In my last post, I talked about how Heekscnc uses a master python script to coordinate the generation of g-code. In this post, I will try to convey how data is translated from the gui to this python script.

1. Look at the layout of HeeksCAD with the HeeksCNC installed :

Notice that there is an Objects tree on the left side. This is how all the data for the cnc program is graphically represented. Double clicking in items in this tree usually causes the parameters of that particular item to be displayed and editable.

To create a toolpath in Heeks, you need a 'sketch' (geometry), a 'tool' (end mill, drill, etc...) , and an 'operation' (profile, pocket, drilling...). So the first thing needed to get this ball rolling is the 'sketch'. Here I select the face of a solid and right click on it. A dialog pops up and allows me to create sketches from the face.

The representation of the 'sketch' (or two sketches in this one)  appears in the 'Objects tree':

Notice that in my Objects tree there are already some tools listed. I have a tool table file stored on my hard drive with these tools in it.
I next select a sketch and one of the tools from the tree and then create an operation:

I selected a 'Profile' operation because I want to cut around the outside profile of this part.

I also did the same thing with the inner sketch, but this time used a smaller tool and then selected the 'Pocket' operation. In Heekscnc, the pocket operation dialog looks like this:

When I have a few operations set up, I usually get curious and want to see some results, so I usually post process what I have do far to see what the resulting tool paths look like:

Pressing the 'Post-Process' button causes the master python script to be built and placed in the 'Program' panel:

This is the same type of script that I blogged about last time. This script is run and creates a gcode file in the 'Output' panel.

So, there you have it- that is a basic rundown of how Heekscnc operates.

The thing that I want to stress in this post is that anything that is represented in the Objects tree will be translated to the master python script and later converted into gcode.

Friday, October 5, 2012

Python toolpath generation -HeeksCNC method

In this post, I want to explain the basics of how HeeksCNC uses python to generate toolpaths. The method that Dan Heeks came up with for doing this was brilliant. I have used bits and pieces of this method with different applications a lot and am just starting to use it with FreeCAD. Here is a python script (Dan Heeks named it in HeeksCNC) that is the main script for a gcode file. : 
import area
import kurve_funcs
from import *
import nc.emc2

program_begin(123, 'Test program')

comment('Feeds and Speeds set for machining Please select a material to machine')

tool_defn( id=3, name='1/4 inch Carbide End Mill', radius=0.125, length=1.25, gradient=-0.1)
#(0.188 inch Carbide End Mill)

comment('tool change to 1/4 inch Carbide End Mill')
tool_change( id=3)
feedrate_hv(33.07086614, 7)
clearance = float(0.1968503937)
rapid_safety_space = float(0.07874015748)
start_depth = float(0)
step_down = float(0.035)
final_depth = float(-0.07)
tool_diameter = float(0.25)
cutting_edge_angle = float(0)
#absolute() mode
roll_radius = float(0.125)
offset_extra = 0
curve = area.Curve()
curve.append(area.Point(1.25, -0.7))
curve.append(area.Point(-0.65, -0.7))
curve.append(area.Vertex(-1, area.Point(-1.4, 0.05), area.Point(-0.65, 0.05)))
curve.append(area.Point(-1.4, 0.45))
curve.append(area.Vertex(-1, area.Point(-0.65, 1.2), area.Point(-0.65, 0.45)))
curve.append(area.Point(1.25, 1.2))
curve.append(area.Vertex(-1, area.Point(2, 0.45), area.Point(1.25, 0.45)))
curve.append(area.Point(2, 0.05))
curve.append(area.Vertex(-1, area.Point(1.25, -0.7), area.Point(1.25, 0.05)))

roll_on = 'auto'
roll_off = 'auto'
extend_at_start= 0
extend_at_end= 0
lead_in_line_len= 0.25
lead_out_line_len= 0
kurve_funcs.profile(curve, 'left', tool_diameter/2, offset_extra, roll_radius, roll_on, roll_off, rapid_safety_space, clearance, start_depth, step_down, final_depth,extend_at_start,extend_at_end,lead_in_line_len,lead_out_line_len )
This script is processed like this: reaches out to other scripts/modules in the heekscnc world for processing and formatting. These other scripts need to be in the python path, as you would expect.
libarea can be had from many places now, although I prefer to use the 'New BSD' licensed version that can be found here. is used for processing toolpaths for milling profiles. It depends on libarea too. I think we could probably untangle the dual dependency of calling 'import area' in and in, if we looked into it.

the line 'import nc.emc2' calls upon a user editable script that formats gcode for the emc2 (linuxcnc now) milling machine. There are a lot of other scripts in the nc directory that let one format the gcode for other machines.

Here is a summary of the components of this system again: