**Status**: very early draft, inverse kinematics resolved

**Updates**:

**2021/02/28**: added animation PAX printing a 4-axis/RTN sliced overhang model**2021/02/17**: added two brief animations of inverse kinematics**2021/02/08**: inverse kinematics working, printhead mounted on Ashtar K as draft**2021/02/06**: machine vs nozzle coordinates, forward/reverse transformation requirements, heatsink fan and part cooler added**2021/02/04**: starting with collecting ideas and first drafts

## Introduction

After I saw 5- and 6-axis printers at Formnext 2019 and particularly seeing the belt printers able to print 90° overhangs in one direction without support, and then RotBot by ZHAW, a Rotating Tilted Nozzle (RTN) printer, where the 90° overhangs in different directions (given some conditions) can be printed without support – so it was more natural to consider to make the tilting nozzle angle (t_{rot}) flexible as well, 0 – 180°.

**0°: nozzle looking down**, ordinary orientation with Z sliced layers 3D printing**45°: belt printer or rotating tilted nozzle (RTN) printer**, printing 90° overhangs in one or more directions^{*)}**90°: printing horizontally outward**- 135°: printing upward 45°
- 180°: printing upward entirely

*) Rotating Tilted Nozzle capability printing 90° overhangs depends on location and symmetric alignments, no slicing software yet available.

## Flexible Tilting

## 2 Axes with NEMA 17

Let’s look at bit closer to the new rotating axes implemented with direct drive NEMA 17 stepper motors:

- Z rotation (aka Z
_{rot}) with- NEMA 17 39/40mm long (45Nm) or

- NEMA 17 25mm/180g (13Nm)

- Tilt rotation (aka T
_{rot}) with- NEMA 17 20mm/140g (16Nm) or

- NEMA 17 25mm/180g (13Nm)

both provide 1.8° (or optionally 0.9°) resolution per full step, or

**8 microsteps (20% force)**0.225° @1.8°step (0.1125° @0.9°step) per microstep- Z rotation 9 Nm (or 2.6Nm)
- T rotation 3.2 Nm

**16 microsteps (10% force) 0.1125°**@1.8°step (0.0565° @0.9°step) per microstep- Z rotation 4.5 Nm (or 1.3Nm)
- T rotation 1.6 Nm

For now, for sake of simplicity, both axes are in direct drive – if precision requirements dictate a simple reduction gear 1:4 or 1:5 (see below for some more details).

## Taking Advantage of 5 Axis

In 5 axis CNC context there are multiple configurations possible such as table/table, head/head and table/head – as I came from the Rotating Tilted Nozzle (RTN) the extra 2 axis are added to the head, hence **head/head** configuration.

The T_{rot} of 0° is the equivalent of ordinary 3D printer with top/down oriented nozzle, the 45° the belt printer or RotBot/RTN, and 90° printing vertical walls with the nozzle perpendicular, and 90-135° printing up-side down – I’m not sure if 135-180**°** is that useful, perhaps making underlying structures really smooth. For now I keep the tilt rotation from 0° to 180° even though I think I’m going to use 0-135° in real life application when the actual print procedure is developed, planar or non-planar slicing.

## Mathematics

### 5 Axis Kinematics

LinuxCNC 5 Axis kinematics describes the notations and provides a starting point and I realized quickly that in CNC context the 5 axis operations is quite thoroughly explored, but much fewer focus on 5 axis additive manufacturing yet (see below at References).

In order to reflect the rotation per axis, the notion A, B and C are adopted, which can be described in OpenSCAD as

`translate([X,Y,Z]) rotate([A,B,C]) ...`

Further the CNC notion **I, J and K **are used as** tool vector**, the way the nozzle points away. G-code supports natively `G1 X Y Z I J K`

which is machine independent. The machine specific firmware then computes the machine coordinates and rotating angles so the machine tool tip reaches those coordinates with that particular tool vector.

### Tool/Nozzle vs Machine Coordinates

Absolute coordinates X, Y, Z of the nozzle tip and angles Z_{rot}, T_{rot} and given the Z rotation arm there is a mapping required to X_{m}, Y_{m}, Z_{m} with same Z_{rot}, T_{rot}.

The forward transformation in OpenSCAD:

`translate([Xm,Ym,Zm]) rotate([0,0,Zrot]) rotate([Trot,0,0]) translate([0,0,-45]) sphere(0.1); // nozzle tip at X, Y, Z with I, J, K`

or expressing it as a list:

- at 0, 0, 0 (origin)
`translate([Xm,Ym,Zm])`

`rotate([0,0,Zrot])`

`rotate([Trot,0,0])`

`translate([0,0,-45])`

- at X, Y, Z

The `-45`

is the 45mm vertical offset of the tilt rotation to the tip of the nozzle.

In OpenSCAD it’s the reverse order, and enumerate matrices (used further below):

- at X, Y, Z
`translate([0,0,45])`

aka M1`rotate([-Trot,0,0])`

aka M2`rotate([0,0,-Zrot])`

aka M3`translate([ X`

aka MR, by inverting matrix the X_{m}, Y_{m}, Z_{m}])_{m}, Y_{m}, Z_{m}can be extracted- at 0, 0, 0 (origin)

Each transformation can be represented by a 4×4 matrix, the sequence of transformations are the multiplication of such, and when multiplying symbolical a single 4×4 matrix will result. When keeping the symbolical notion the inverse transformation can be obtained with one operation and getting X_{m}, Y_{m}, Z_{m} from X, Y, Z, Z_{rot}, T_{rot}, and that very computation needs to be done in the firmware and controller in order to process X, Y, Z, Z_{rot}, T_{rot} as `G1 X.. Y.. Z.. A.. B..`

and the internally X_{m}, Y_{m}, Z_{m} is processed to achieve that tool coordinate; A = Z_{rot}, B = T_{rot} .

**G-code**

`G1 X.. Y.. Z.. A.. B..`

**Firmware**

Z_{rot} = `A`

T_{rot} = `B`

X_{m}, Y_{m}, Z_{m} computed via reverse/inverse transformation on the controller

**Numerical Inverse Transformation**

Just for sake of confirming the reverse/inverse transformation utilizing m4.scad:

include <m4.scad> Zrot = 45; Trot = 45; M1 = [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 45 ], [ 0, 0, 0, 1 ] ]; M2 = [ [ 1, 0, 0, 0 ], [ 0, cos(-Trot), -sin(-Trot), 0 ], [ 0, sin(-Trot), cos(-Trot), 0 ], [ 0, 0, 0, 1 ] ]; M3 = [ [ cos(-Zrot), -sin(-Zrot), 0, 0 ], [ sin(-Zrot), cos(-Zrot), 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ]; MR = m4inv(M1 * M2 * M3); // or MR = m4inv(m4tr([0,0,45])*m4rx(-Trot)*m4rz(-Zrot)); echo(MR);

which outputs

`ECHO: [[1, 0, 0, 0], [0, 0.707107, -0.707107, 31.8198], [0, 0.707107, 0.707107, -31.8198], [0, 0, 0, 1]]`

so MR contains the inverse matrix of the previous transformations, so I can extract the translation vector, the 4th column `[ MR[0][3], MR[1][3], MR[2][3] ]`

or `m4trv(MR)`

to compensate X, Y, Z, Z_{rot}, T_{rot} -> X_{m}, Y_{m}, Z_{m}:

### Testing Inverse Kinematics (IK)

*X=150, Y=0, Z=0, Zrot=0,***Trot=0***X=150, Y=0, Z=0, Zrot=0,**Trot=*45*X=150, Y=0, Z=0, Zrot=0,**Trot=*90*(nozzle crashed into bed)**X=150, Y=0, Z=0, Zrot=0,*(just testing negative tilt angle)*Trot=*-45*X=150, Y=0, Z=0,***Zrot=45**,*Trot=*45*X=150, Y=0, Z=0,***Zrot=90**,*Trot=*45*X=150, Y=0, Z=0,***Zrot=135**,*Trot=*45*X=150, Y=0, Z=0,***Zrot=180**,*Trot=*45

Perhaps it’s worth to actually calculate symbolical forward and inverse transformation matrix using e.g. Matlab or alike to have transformations in one operation instead multiplying three matrices and inverting it – depending what hardware is used as controller multiplying individual matrices is faster than trying to have a complex single step matrix construct.

Although Marlin firmware supports Delta printer with complex delta inverse kinematics, not sure I can add mine as well, or I have to go with Duet RepRap firmware which seems more suitable (see notes below).

### Nozzle Precision from T_{rot}

The 45mm offset of the last rotation massivly contributes to the loss of nozzle position resolution:

s = 2 *π* * r / 360 = section length per degree

s = *π* * 45mm / 180 = 0.785mm/° which means:

**8 microsteps**with**1.8° full step**: 0.225°/microstep =>**176.7μm/microstep****16 microsteps**with**1.8° full step:**0.1125°/microstep =>**88.3μm/microstep****8 microsteps**with**0.9° full step**: 0.1125°/microstep =>**88.3μm/microstep****16 microsteps**with**0.9° full step**: 0.0565°/microstep =>**44.4μm/microstep**

so the direct drive using the shafts of the NEMA 17 will provide OK resolution, but for anything a bit more serious, a reduction gear might be worth to use.

### G-code & Firmware

As I likely will generate machine independent G-code as `G1 X Y Z I J K`

, the slicer stage will likely operate in X, Y, Z and Z_{rot} and T_{rot} as well – so we end up with a data pipeline like this:

- Slicer: X, Y, Z, Z
_{rot}, T_{rot} - G-code:
`G1 X Y Z I J K`

- Firmware:
`X Y Z I J K`

=> X_{m}, Y_{m}, Z_{m}and`I J K`

=> Z_{rot}, T_{rot}

Alternatively, instead using `I J K`

notion use the G-code `A`

and `B`

as two rotational axes as Duet RepRap Firmware offers `G1 X Y Z A B`

then it’s a bit simpler:

- Slicer: X, Y, Z, Z
_{rot}=>`A`

, T_{rot}=>`B`

- G-code
`G1 X Y Z A B`

- Firmware:
`X Y Z A B`

=> X_{m}, Y_{m}, Z_{m}and`A`

=>Z_{rot},`B`

=>T_{rot}

Reviewing existing slicer/printing software to see which notion is more suitable, and perhaps cover both to stay flexible.

## Issues to Resolve

**Bowden tube- & cable management**: properly resolve it, guides etc., done**Develop the transformation/inverse kinematics**X, Y, Z, Z_{rot}, T_{rot}<=> X_{m}, Y_{m}, Z_{m}, Z_{rot}, T_{rot}as well X, Y, Z, I, J, K <=> X_{m}, Y_{m}, Z_{m}, Z_{rot}, T_{rot}as required for slicing, and firmware stage**Calculate the precision of X, Y, Z in relation of X**, whether or how the motor resolution affect axes => getting a grasp how the overall precision of the final setup_{m}, Y_{m}, Z_{m}and Z_{rot}, T_{rot}**Direct drive mechanical precision**with 8/16 microsteps, repeatability, and heat dissipation from motor (see tweet)**Slicer/print software supporting 5 axis nozzle****Duet RepRap Firmware**: supports ABCD rotational axes- Supporting firmware calculation of X
_{m}, Y_{m}, Z_{m}(keeping G-code machine independent) inverse kinematic: e.g. adding new kinematics to Duet, and 5 Axis Robot configuration might help as a start

- Supporting firmware calculation of X
**Marlin firmware**capabilities, as it support Delta printers, inverse kinematics (IK) calculations seem supported well, question is how simple to add my own custom IK as well- printing: recognize model features or base design on seams or boundaries, like OPENCASCADE (STEP/IGES support)
- printing: use vertical slicing as fallback, given no other printing method is suitable

**explore different print modes**like RotBot/RTN- recognize rotational objects: print from inside out like with a lath but adding material
- detect steep overhangs, find proper way to print them

**collision detection**, e.g. tilt rotation becomes available at a certain Z level as below the upside looking nozzle will touch the build plate with the opposite end – the slicing/print software must be aware of the printhead geometry to calculate what’s possible to print and how

## Considerations

**Pros**

**many new ways to print in (almost) all directions**- hopefully print 90° and more overhangs without support at all

**Cons**

**significant mechanical complexity**- mechanical limitations arise with new freedom of rotation of printhead
- collision detection becomes essential which in Z sliced layers is not an issue at all

**significant software complexity**, no current 3D printing software available to take advantage of 5 axis printing

## Ashtar K with 5 Axis (PAX) Printhead

Experimental mounting on Ashtar K to see how it looks, including display showing rotations of Z_{rot} (A), T_{rot} (B) too.

**Note**: the display shows original tool coordinates, whereas the firmware does tool translation aka inverse kinematics as shown in the screenshots with the display readable.

With all the freedom to angle the nozzle, all of the sudden the part cooler air nozzle shape becomes an issue, and has to become narrow as well; and overall geometry of the printhead becomes quite relevant when planning print sequences (collision detection).

PAX can operate in 4-axis mode, e.g. printing a conic sliced (4-axis RTN) overhang model (without support structure) in 4-axis Rotating Tilted Nozzle (RTN) mode (45*°* titled nozzle):

## PAX Tilt 180 vs 90

The PAX which tilts up to 180° will be referenced further as PAX or PAX 180, the 360° Z rotation is implied then too, as comparison of PAX 90 tilting to 90*°* only with shorter arm:

As the slicing strategy isn’t determined, it’s not yet clear if tilt 90..180*°* is required or not. In case only 0..90*°* is sufficient, the Z rotation arm can be shortened.

## References

**5 Axis**

**Pentarod**, 5 axis RepRap, 2 axis added to bed (not head), master thesis (see also paper), most useful- Multi-Axis 3D Printing Technique Improves FDM Strength Over 2X (see also paper)
- Three-Dimensional Printing of Continuous Flax Fiber-Reinforced Thermoplastic Composites by Five-Axis Machine with paper (PDF)
- 5 Axis Maker, former Kickstarter, multi-tool CNC & 3D Printer
- 3D Digital Manufacturing via Synchronous 5-Axes Printing for Strengthening Printing Parts (paper, PDF)
**5-Axis 3D Printing**paper (PDF), it gives some information on- Volume decomposition
- Build orientation
- Sub-volume sequencing
- Collision detection
- 5-axis G-code generation
- with some sort of details via pseudo-code, no software released

- How To Fully Leverage 5-Axis 3D Printing (article)
**Epit3D Delta**with rotating & tilting bed (5 Axis)- DotXControl: 5 Axis Slicer (closed source), uses
`I J K`

tool vector notion (machine independent positioning)

**4 Axis**

- RotBot by ZHAW, rotating 45° tilted nozzle, little details released but informative paper (paywalled)
- Rotating Tilted Nozzle Option (RTN), my own approach of RotBot

As I progress I will update this blog-post.

That’s it.