@joergs5 It seemed to me as if it's motor position, because my kinematics is only called once with end position. The `GetLinearAxes()`

does `return AxesBitmap::MakeFromRaw(0)`

treating none of the axes as linear (or am I misunderstanding of it?) Otherwise I inherent the ZLeadscrewKinematics, where segmentsPerSecond=100, minSegmentLength=0.2000.

@dc42 I did this:

```
PAXKinematics::PAXKinematics() noexcept
: ZLeadscrewKinematics(KinematicsType::pax, SegmentationType(true, true, true)) // useSeg, useZSeg, useG0Seg
{
}
```

and as mentioned above, `GetSegmentsPerSecond()`

returns 100, and `GetMinSegmentLength()`

returns 0.2.

What am I missing otherwise? The `PAXKinematics::CartesianToMotorSteps()`

is called only once with `G1 B20`

(to keep the example simple).

I went ahead to understand it better what the problem could be, and dived into `Gcodes/Gcodes.cpp`

function `GCodes::DoStraightMove()`

: where the amount of segments are calculated, line #2110:

```
// Apply segmentation if necessary. To speed up simulation on SCARA printers, we don't apply kinematics segmentation when simulating.
// As soon as we set segmentsLeft nonzero, the Move process will assume that the move is ready to take, so this must be the last thing we do.
if (st.useSegmentation && simulationMode != 1 && (moveBuffer.hasPositiveExtrusion || moveBuffer.isCoordinated || st.useG0Segmentation))
{
debugPrintf("calculate segmentation\n");
// This kinematics approximates linear motion by means of segmentation
float moveLengthSquared = fsquare(currentUserPosition[X_AXIS] - initialUserPosition[X_AXIS]) + fsquare(currentUserPosition[Y_AXIS] - initialUserPosition[Y_AXIS]);
if (st.useZSegmentation)
{
moveLengthSquared += fsquare(currentUserPosition[Z_AXIS] - initialUserPosition[Z_AXIS]);
}
const float moveLength = fastSqrtf(moveLengthSquared);
const float moveTime = moveLength/moveBuffer.feedRate; // this is a best-case time, often the move will take longer
moveBuffer.totalSegments = (unsigned int)max<long>(1, lrintf(min<float>(moveLength * kin.GetReciprocalMinSegmentLength(), moveTime * kin.GetSegmentsPerSecond())));
}
```

it enters that `if`

block, but the result is

```
calculate segmentation
moveLength = 0.0000, moveTime = 0.0000, kin.GetReciprocalMinSegmentLength = 5.0000, kin.GetSegmentsPerSecond = 100.0000
mb.totalSegments = 1, mb.isCoordinated = 1, useSegmentation = 1, simulationMode = 0
```

mb = moveBuffer

Now, I did override `moveBuffer.totalSegments = 10`

(after the quoted `if`

block) and **now the motor moves exactly as I expected**.

At my superficial glance of that particular `if`

block, the axes `A`

& `B`

are disregarded there, so, I added in haste following lines (indicated by ** in front):

```
if (st.useZSegmentation)
{
moveLengthSquared += fsquare(currentUserPosition[Z_AXIS] - initialUserPosition[Z_AXIS]);
}
**moveLengthSquared += fsquare(currentUserPosition[3] - initialUserPosition[3]);
**moveLengthSquared += fsquare(currentUserPosition[4] - initialUserPosition[4]);
```

A[axis=3] and B[axis=4] are in degrees, so it's not really "length", but anyway, it produces this debug output:

```
calculate segmentation
moveLength = 45.0000, moveTime = 0.1350, kin.GetReciprocalMinSegmentLength = 5.0000, kin.GetSegmentsPerSecond = 100.0000
mb.totalSegments = 13, mb.isCoordinated = 1, useSegmentation = 1, simulationMode = 0
```

and now I have much better `mb.totalSegments = 13`

.

@dc42 am I missing some settings in my kinematics or is the segmentation computation problem actually higher up at `Gcodes/Gcode.cpp`

?

With the two axes (A & B) hardcoded into segments calculation the firmware & machine behaves now as I desired https://www.youtube.com/watch?v=TiV0zEc5spw - the nozzle stays in place, A & B are rotating, whereas X, Y & Z compensate properly.