LinuxCNC S-Curve Accelerations
- Aciera
-
- Offline
- Administrator
-
Less
More
- Posts: 4644
- Thank you received: 2065
28 Jan 2026 15:36 - 28 Jan 2026 15:38 #342082
by Aciera
Replied by Aciera on topic LinuxCNC S-Curve Accelerations
I've been trying to test this on real hardware using Mesa but I cannot seem to get the new planner to work at all.
- [TRAJ] section has 'MAX_LINEAR_JERK = 1000.0'
- both [JOINT_0] and [JOINT_1] have 'MAX_JERK = 1000.0'
- ini.planner_type = 1
Yet running this code in G61.1 mode
I get this:
here is my ini file:
# This file was updated with the Mesa Configuration Tool on Nov 25 2025 13:43:50
# Changes to most things are ok and will be read by the Configuration Tool
[MESA]
VERSION = 2.1.8
BOARD = 7i95
BOARD_NAME = 7i95t
[EMC]
VERSION = 1.1
MACHINE = test_setup
DEBUG = 0x00000000
[HM2]
DRIVER = hm2_eth
ADDRESS = 192.168.1.121
[DISPLAY]
DISPLAY = axis
PROGRAM_PREFIX = ./nc_files
POSITION_OFFSET = RELATIVE
POSITION_FEEDBACK = ACTUAL
MAX_FEED_OVERRIDE = 1.2
MIN_LINEAR_VELOCITY = 0.0
DEFAULT_LINEAR_VELOCITY = 150.0
MAX_LINEAR_VELOCITY = 300.0
CYCLE_TIME = 0.1
INTRO_GRAPHIC = emc2.gif
INTRO_TIME = 0
OPEN_FILE = ./square.ngc
EDITOR = gedit
DEFAULT_ANGULAR_VELOCITY = 18000
MAX_ANGULAR_VELOCITY = 36000
MIN_ANGULAR_VELOCITY = 1
[KINS]
KINEMATICS = trivkins
JOINTS = 2
[EMCIO]
CYCLE_TIME = 0.100
TOOL_TABLE = tool.tbl
[RS274NGC]
PARAMETER_FILE = parameters.var
[EMCMOT]
EMCMOT = motmod
COMM_TIMEOUT = 1.0
SERVO_PERIOD = 1000000
[TASK]
TASK = milltask
CYCLE_TIME = 0.010
[TRAJ]
COORDINATES = XY
LINEAR_UNITS = mm
ANGULAR_UNITS = degree
MAX_LINEAR_VELOCITY = 200.0
PLANNER_TYPE = 1
MAX_LINEAR_JERK = 1000.0
DEFAULT_LINEAR_JERK = 500.0
[HAL]
HALFILE = main.hal
[AXIS_X]
MIN_LIMIT = 0
MAX_LIMIT = 300
MAX_VELOCITY = 300
MAX_ACCELERATION = 800
[JOINT_0]
CARD = 0
MIN_LIMIT = 0
MAX_LIMIT = 300
MAX_VELOCITY = 300
MAX_ACCELERATION = 800
MAX_JERK = 1000.0
TYPE = LINEAR
SCALE = 252.65
STEPGEN_MAX_VEL = 360.00
STEPGEN_MAX_ACC = 960.00
DIRSETUP = 10000
DIRHOLD = 10000
STEPLEN = 4000
STEPSPACE = 4000
ENCODER_SCALE = 200
FERROR = 1.5
MIN_FERROR = 0.25
DEADBAND = 0.01
P = 1000
I = 0
D = 0
FF0 = 0
FF1 = 1
FF2 = 0
BIAS = 0
MAX_OUTPUT = 0
MAX_ERROR = 0.0127
HOME_OFFSET = -0.75
HOME = 0
HOME_SEARCH_VEL = -5
HOME_LATCH_VEL = -5
HOME_FINAL_VEL = 2.5
HOME_IGNORE_LIMITS = YES
HOME_SEQUENCE = 0
[AXIS_Y]
MIN_LIMIT = 0
MAX_LIMIT = 300
MAX_VELOCITY = 300
MAX_ACCELERATION = 800
[JOINT_1]
CARD = 0
MIN_LIMIT = 0
MAX_LIMIT = 300
MAX_VELOCITY = 300
MAX_ACCELERATION = 800
MAX_JERK = 1000.0
TYPE = LINEAR
SCALE = 252.65
STEPGEN_MAX_VEL = 360.00
STEPGEN_MAX_ACC = 960.00
DIRSETUP = 10000
DIRHOLD = 10000
STEPLEN = 4000
STEPSPACE = 4000
ENCODER_SCALE = 200
FERROR = 1.5
MIN_FERROR = 0.25
DEADBAND = 0.01
P = 1000
I = 0
D = 0
FF0 = 0
FF1 = 1
FF2 = 0
BIAS = 0
MAX_OUTPUT = 0
MAX_ERROR = 0.0127
HOME_OFFSET = 0.25
HOME = 0
HOME_SEARCH_VEL = -5
HOME_LATCH_VEL = -5
HOME_FINAL_VEL = 2.5
HOME_IGNORE_LIMITS = YES
HOME_SEQUENCE = 0
What am I missing?
- [TRAJ] section has 'MAX_LINEAR_JERK = 1000.0'
- both [JOINT_0] and [JOINT_1] have 'MAX_JERK = 1000.0'
- ini.planner_type = 1
Yet running this code in G61.1 mode
G21
F5000
G0 x0 y0
g1 x20
y20
x0
y0
m2I get this:
here is my ini file:
Warning: Spoiler!
# This file was updated with the Mesa Configuration Tool on Nov 25 2025 13:43:50
# Changes to most things are ok and will be read by the Configuration Tool
[MESA]
VERSION = 2.1.8
BOARD = 7i95
BOARD_NAME = 7i95t
[EMC]
VERSION = 1.1
MACHINE = test_setup
DEBUG = 0x00000000
[HM2]
DRIVER = hm2_eth
ADDRESS = 192.168.1.121
[DISPLAY]
DISPLAY = axis
PROGRAM_PREFIX = ./nc_files
POSITION_OFFSET = RELATIVE
POSITION_FEEDBACK = ACTUAL
MAX_FEED_OVERRIDE = 1.2
MIN_LINEAR_VELOCITY = 0.0
DEFAULT_LINEAR_VELOCITY = 150.0
MAX_LINEAR_VELOCITY = 300.0
CYCLE_TIME = 0.1
INTRO_GRAPHIC = emc2.gif
INTRO_TIME = 0
OPEN_FILE = ./square.ngc
EDITOR = gedit
DEFAULT_ANGULAR_VELOCITY = 18000
MAX_ANGULAR_VELOCITY = 36000
MIN_ANGULAR_VELOCITY = 1
[KINS]
KINEMATICS = trivkins
JOINTS = 2
[EMCIO]
CYCLE_TIME = 0.100
TOOL_TABLE = tool.tbl
[RS274NGC]
PARAMETER_FILE = parameters.var
[EMCMOT]
EMCMOT = motmod
COMM_TIMEOUT = 1.0
SERVO_PERIOD = 1000000
[TASK]
TASK = milltask
CYCLE_TIME = 0.010
[TRAJ]
COORDINATES = XY
LINEAR_UNITS = mm
ANGULAR_UNITS = degree
MAX_LINEAR_VELOCITY = 200.0
PLANNER_TYPE = 1
MAX_LINEAR_JERK = 1000.0
DEFAULT_LINEAR_JERK = 500.0
[HAL]
HALFILE = main.hal
[AXIS_X]
MIN_LIMIT = 0
MAX_LIMIT = 300
MAX_VELOCITY = 300
MAX_ACCELERATION = 800
[JOINT_0]
CARD = 0
MIN_LIMIT = 0
MAX_LIMIT = 300
MAX_VELOCITY = 300
MAX_ACCELERATION = 800
MAX_JERK = 1000.0
TYPE = LINEAR
SCALE = 252.65
STEPGEN_MAX_VEL = 360.00
STEPGEN_MAX_ACC = 960.00
DIRSETUP = 10000
DIRHOLD = 10000
STEPLEN = 4000
STEPSPACE = 4000
ENCODER_SCALE = 200
FERROR = 1.5
MIN_FERROR = 0.25
DEADBAND = 0.01
P = 1000
I = 0
D = 0
FF0 = 0
FF1 = 1
FF2 = 0
BIAS = 0
MAX_OUTPUT = 0
MAX_ERROR = 0.0127
HOME_OFFSET = -0.75
HOME = 0
HOME_SEARCH_VEL = -5
HOME_LATCH_VEL = -5
HOME_FINAL_VEL = 2.5
HOME_IGNORE_LIMITS = YES
HOME_SEQUENCE = 0
[AXIS_Y]
MIN_LIMIT = 0
MAX_LIMIT = 300
MAX_VELOCITY = 300
MAX_ACCELERATION = 800
[JOINT_1]
CARD = 0
MIN_LIMIT = 0
MAX_LIMIT = 300
MAX_VELOCITY = 300
MAX_ACCELERATION = 800
MAX_JERK = 1000.0
TYPE = LINEAR
SCALE = 252.65
STEPGEN_MAX_VEL = 360.00
STEPGEN_MAX_ACC = 960.00
DIRSETUP = 10000
DIRHOLD = 10000
STEPLEN = 4000
STEPSPACE = 4000
ENCODER_SCALE = 200
FERROR = 1.5
MIN_FERROR = 0.25
DEADBAND = 0.01
P = 1000
I = 0
D = 0
FF0 = 0
FF1 = 1
FF2 = 0
BIAS = 0
MAX_OUTPUT = 0
MAX_ERROR = 0.0127
HOME_OFFSET = 0.25
HOME = 0
HOME_SEARCH_VEL = -5
HOME_LATCH_VEL = -5
HOME_FINAL_VEL = 2.5
HOME_IGNORE_LIMITS = YES
HOME_SEQUENCE = 0
What am I missing?
Attachments:
Last edit: 28 Jan 2026 15:38 by Aciera.
Please Log in or Create an account to join the conversation.
- Aciera
-
- Offline
- Administrator
-
Less
More
- Posts: 4644
- Thank you received: 2065
28 Jan 2026 16:03 #342085
by Aciera
Replied by Aciera on topic LinuxCNC S-Curve Accelerations
A word of caution to anyone testing the new planner on real hardware:
I would strongly recommend to NOT activate the new planner in the ini file.
I dropped my homing velocities to 20% and my real hardware setup still runs into the hard stops on homing.
Users should leave ini.planner_type = 0, home the machine and use halshow to set ini.planner_type = 1.
I would strongly recommend to NOT activate the new planner in the ini file.
I dropped my homing velocities to 20% and my real hardware setup still runs into the hard stops on homing.
Users should leave ini.planner_type = 0, home the machine and use halshow to set ini.planner_type = 1.
The following user(s) said Thank You: endian
Please Log in or Create an account to join the conversation.
- endian
-
- Away
- Elite Member
-
Less
More
- Posts: 292
- Thank you received: 98
28 Jan 2026 18:36 - 28 Jan 2026 18:44 #342092
by endian
I do not want to talk about ethercat here .. we have separate space, but in reality it is lagging 2cycles because at hardare layer it writes command first and then it reads the slave status... then next cycle it write command by last status and then cycle it reach real status datas ... (Martin Rostan (Chairman ETG group) - when I was with him at last time at conference in Bratislava)
SDO 0x60C2 is configuring the timing of internal stuff of interpolationn of synchronized movement by subindex 01 and 02 .. most drivers it has to have it at same time of master command tick but we knows some which do not as Beckhoff AX5 series
I am at second computer and I will update picture later this weel but during movement in 15m/s it can produce lag of 0.2mm with timing 250us ... which sound terrible 0
I did compensation component which add posCmd = position command + compensation during vcommand != 0 and every lag was gone ... it was purely for testing but solution is clear
Replied by endian on topic LinuxCNC S-Curve Accelerations
I think not every hardware has 0x60B1:01 in the accessible PDOs and not everyone can use unsynchronized SDO to change during OP ... therefore I am high-lighing it before job is done ... I have working with 16 different brands of servodrivers based on ethercat and just one it has(nidec control techniques) ... What I know from TC3 this is solved by NC stuff computing for the each single axis ...@endian I discussed this with YangYang who attends the EtherCAT consortium meetings. AitalMAC is part of the consortium and we design I/O for EtherCAT, so we're not guessing here.
The standard already solves this problem. You don't need pos(t+1).
The 1 cycle delay is real, but it's identical for all axes. With Distributed Clocks everything executes on the same SYNC edge, synchronized to ~100ns. Every axis is "late" by the same amount, so the path shape is correct. Calculate it last week, execute it this week, the part is the same.
The CiA 402 standard provides feedforward objects exactly for this: 0x60B1 (velocity offset) and 0x60B2 (torque offset). The master can send position plus velocity feedforward so the drive can anticipate acceleration. This is the standard's solution, it just needs to be mapped in lcec.
Also, good drives interpolate internally. The servo loop runs faster than the bus cycle (Maxon runs 0.4ms internal vs 1ms bus). The drive doesn't jump between positions, it interpolates. That's what 0x60C2 configures.
If you're seeing ferror correlate with velocity in halscope, that's likely a display artifact. The ferror compares "commanded from 1 cycle ago" with "actual now", so it shows an offset proportional to velocity. It's not a real machining error.
What does your actual part surface look like? Any real deviation you can measure?
I do not want to talk about ethercat here .. we have separate space, but in reality it is lagging 2cycles because at hardare layer it writes command first and then it reads the slave status... then next cycle it write command by last status and then cycle it reach real status datas ... (Martin Rostan (Chairman ETG group) - when I was with him at last time at conference in Bratislava)
SDO 0x60C2 is configuring the timing of internal stuff of interpolationn of synchronized movement by subindex 01 and 02 .. most drivers it has to have it at same time of master command tick but we knows some which do not as Beckhoff AX5 series
I am at second computer and I will update picture later this weel but during movement in 15m/s it can produce lag of 0.2mm with timing 250us ... which sound terrible 0
I did compensation component which add posCmd = position command + compensation during vcommand != 0 and every lag was gone ... it was purely for testing but solution is clear
positionOutputCompensated = positionOutput;
if(fabs(vel_cmd) > 0.001)
{
double leadCycleLocal = lead_cycles;
const double Ts = periodTime;
const int L = (leadCycleLocal < 1) ? 1 : leadCycleLocal;
const double LTs = (double)L * Ts;
double lead = (vel_cmd * LTs) + (0.5 * acc_cmd * LTs * LTs);
double ferr;
ferr = (positionOutput - pos_fb_from_incremental);
double comp = (kff * lead) + (k_err * ferr);
posCompensation = comp;
if(fabs(ferr) > fabs(fErrorOld) || fTopError == 0.0)
{
fErrorOld = ferr;
fTopError = fErrorOld;
}
}
else
{
posCompensation = 0;
}
positionOutputCompensated = positionOutput + posCompensation;
if(ui_delayFinal > 0)
{
positionOutputCompensated = positionOutput;
ui_delayFinal--;
}
//drv_target_position_incremental = (int32_t)(positionOutput * pos_scale * incremental_pos_scale);
drv_target_position_incremental = (int32_t)(positionOutputCompensated * pos_scale * incremental_pos_scale);
Last edit: 28 Jan 2026 18:44 by endian. Reason: add code
Please Log in or Create an account to join the conversation.
Time to create page: 0.103 seconds