Programming CNC machines in Haskell







Recent advances in Computerized Numeric Control (CNC) have allowed the manufacturing of products with high quality standards. Since CNC programs consist of a series of assembler-like instructions, several high-level languages, such as AutoLISP, have been proposed in order to raise the programming abstraction level. Unfortunately, the lack of formality in these languages prevents the verification of programs. In this work, we propose the use of Haskell in CNC programming. Haskell is a modern pure functional language permitting formal verification and presenting advanced features such as lazy evaluation, higher order, etc. These features will allow us to cope with infinite data structures, to apply heuristics to CNC programs in order to optimize them, etc.



CNC Machines



US Air Force commissioned MIT to develop the first "numerically controlled" machine in 1949. It was demonstrated in 1952.

Motivation: To manufacture complex curved geometries in 2D or 3D was extremely expensive by mechanical means (which usually would require complex jigs to control the cutter motions).

Most modern machine tool companies manufacture only NC or CNC machine tools. The dominant advantages of NC machines are:

	- Easier to program; easy storage of existing programs;
- Easy to change a program
- Avoids human errors
- NC machines are safer to operate
- Complex geometry is produced as cheaply as simple ones
- Usually generates closer tolerances than manually operated machines

System M3X-3S 3-Axis Control and Machine

Computer Numerical Control (CNC for short) is the process of having a computer controlling the operation of a machine. CNC machines typically replace (or work in conjunction with) some existing manufacturing process. Almost all operations performed with conventional machine tools are programmable with CNC machines. For instance, with CNC machines we can perform motion control in linear (along a straight line) or rotary (along a circular path) axes. The axes of any CNC machine are required for the purpose of causing the motions needed for the manufacturing process.

Having the computer control the machine is accomplished by a program that is written using NC code. A CNC program is a series of instructions written in sentence-like format. These statements are executed in sequential order, step by step. A special series of CNC words are used to communicate what the machine is intended to do. CNC words begin with letter addresses (like F for feedrate, S for spindle speed, and X, Y and Z for axis motion). When placed together in a logical method, a group of CNC words make up a command that resemble a sentence. For any given CNC machine type, there will only be about 40-50 words used on a regular basis.



Standard ISO 6983 (G-codes)



The International Organization for Standardization proposes the ISO 6983 which contains the G-codes for CNC programming. It s pecifies requirements and gives recommendations for the data format for control systems used in the numerical control of machines. Improves the co-ordination of system design in order to minimize the variety of program manuscripts required. Is not intended for use in flame cutting machines and drafting machines used specifically and exclusively in the shipuilding industry.


Micro Mill 2000
by Quantum

by Roland

A G-codes example of a program which perfores three holes in a straight line is shown below:

More information about G-codes and the standard ISO6983 can be found in:




CNC programming using Haskell

  We propose to cope with CNC programming using the pure functional language Haskell. Haskell provides many advantadges over existing tools:
  • Complex data structures and recursion
  • Polymorphism
  • Higher-Order Functions
  • Laziness
  • Type System
  • Type Classes
  • Verification and Heuristics: Since Haskell is a formal language, it permits to formally verify programs. This means that we can prove the correctness of our programs with the help of automated theorem provers as Isabelle.
    We are also able to formally specify the CNC machines behavior by using Heuristics with Haskell!!!

Small example of a program using Haskell:

CNC program using G-codes

A program which perform two holes on the positions (10,10) and (15,15):

N0010 (two-hole drilling)
N0020 G90
N0030 G00 Z05
N0035 X10 Y10
N0040 Z-05
N0050 Z05
N0060 X15 Y15
N0070 Z-05
N0080 Z05

Haskell data structure intended to hold the CNC program

data CNCprogram = Header Body
data Header = Maybe Comment
type Comment = (String)
data Maybe a = Nothing | Just a
type Body = [Block]
data Block = BComment Comment | Code Command
type Command = [Instruction]
data Instruction = X Int | Y Int | Z Int | G String

Some Haskell functions from the Haskell-CNC library used to implement CNC programs

-- creates a [Block] containing the CNC instructions for
-- making n holes in a straight line

nHolesLine :: Int -> Int -> Int -> Int -> Int ->  [Block]
nHolesLine n x y incX incY = [posType,initMov] ++ concat (map makeHole nLine)  
       line    = createLine x y incX incY
       nLine   = finiteLine n line
       posType = Code [G "90"]
       initMov = Code [G "00",Z 5]

-- creates an infinite list of absolute coordinates
createLine :: Int -> Int -> Int -> Int -> [(Int,Int)]
createLine x y incX incY = (x,y) : createLine (x + incX) (y + incY) incX incY

--takes an list and returns a sublist containing the first n elements
finiteLine :: Int -> [a] -> [a]
finiteLine _ [] = []
finiteLine 0 _  = []
finiteLine n (x:xs) = x : finiteLine (n-1) xs

-- takes a XY coordinate and return a block containing
-- all instructions needeed to make a hole at such position

makeHole :: (Int,Int) -> [Block]
makeHole (x,y) =        [posXY,down,up]  
       up    = Code [Z 5]
       down  = Code [Z (-5)]
       posXY = Code [X x,Y y]

-- takes an initial numbering and a list of blocks 
-- and print them through the output console

printBlocks :: Int -> [Block] -> IO ()
printBlocks _ [] = putStrLn ""
printBlocks numBlock (x:xs) =    
printBlock numBlock x      
printBlocks (numBlock+10) xs

-- takes a number and a block and block and prints it    
printBlock :: Int -> Block -> IO ()
printBlock numBlock block = putStrLn ("N"++(show numBlock)++"\t"++(blockToStr block))

-- converts a block to a String
blockToStr :: Block -> String
blockToStr (BComment c)  = "("++c++")"
blockToStr (Code []) = ""
blockToStr (Code (x:xs)) = (instrToStr x) ++ " " ++ (blockToStr (Code xs))

-- converts an instruction to a String
instrToStr :: Instruction -> String
instrToStr (X n) = "X"++(show n)
instrToStr (Y n) = "Y"++(show n)
instrToStr (Z n) = "Z"++(show n)

CNC program written in Haskell equivalent to the previous written in G-codes

A program which perform two holes on the positions (10,10) and (15,15):main = printBlocks 10 (nHolesLine 2 10 10 5 5)






Here you can download some files with the current implementation of our Haskell library for CNC programming. Our library currently contains:

  1. A XML DTD which allows to properly specify CNC programs following the ISO 6983. With this DTD we are able to completely describe any CNC program.
  2. A Haskell data structure which is equivalent to the previous DTD. We are able to automatically convert programs specified with the XML DTD to programs specified with the Haskell data structure and viceversa.
    For that purpose we use the well-known Haskell library HaXML and the tool DrIFT.
  3. A set of utilities and functions for manipulating the data structure which allow to easily implement CNC programs. In addition, several testing and debugging functions are provided

Cutting path plane for a CNC machine

___________________XML Files___________________

DTD for the representation of CNC programs


Barrenos Example

XML example

CNC program (XML)


External DTD (XML)

External DTD


_________________Haskell Library_________________

CNC library Implementation

Haskell Library


____________Applications and Examples ____________

CNCTypesa.hs (Types Modifiers)

CNC Types




Example 2