LinuxCNC S-Curve Accelerations

More
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
G21
F5000
G0 x0 y0
g1 x20
y20
x0
y0
m2

I get this:

 

here is my ini file:
Warning: Spoiler!


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.

More
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.
The following user(s) said Thank You: endian

Please Log in or Create an account to join the conversation.

  • endian
  • endian's Avatar
  • Away
  • Elite Member
  • Elite Member
More
28 Jan 2026 18:36 - 28 Jan 2026 18:44 #342092 by endian
Replied by endian on topic LinuxCNC S-Curve Accelerations

@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 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 ... 

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
Powered by Kunena Forum