Limit Feedrate in GCode G1

Moderators: TomKerekes, dynomotion

dominfo
Posts: 26
Joined: Tue Sep 12, 2023 8:39 am

Limit Feedrate in GCode G1

Post by dominfo » Thu Dec 05, 2024 2:48 pm

Hello Tom,

I'm struggling in the limitation of GCode executed on Kogna through my .Net HMI.
All my axes have the following setup:
-Counts/Unit:1000
-MaxVel: 150000 counts/unit (150 units/s)
-MaxAccel: 720000 counts/unit (720 units/s²)

I run a small C program in a thread outputting the real feed in my X axis.

With .Net implementation
* G0X100 is achieved at 150 units/s
* G1X1000F12000 (12000 units/mn -> 200 units/s) is achieved at 200 units/s (should be limited to MaxVel like G0)

With KMotionCNC with same parameters
* G1X1000F12000 is achieved at 150 units/s, being limited as expected.

I suppose that a parameter is missing when setting up one of the .Net KM_CoordMotion, KM_Interpreter or KM_Interpreter_Setup_Params object.

Thanks for your feedback
Frederic

User avatar
TomKerekes
Posts: 2703
Joined: Mon Dec 04, 2017 1:49 am

Re: Limit Feedrate in GCode G1

Post by TomKerekes » Thu Dec 05, 2024 6:00 pm

Hi Fredric,

There are different Axis Constraints for Rapid moves vs Feeds. Rapid (and Independent) moves are performed as 3rd order motions with constraints on Velocity, Acceleration and Jerk specified in KFLOP/Kogna. Feeds are performed as 2nd order motions with constraints of Velocity and Acceleration as set in the Trajectory Planner's Motion Parameters. The Trajectory Planner Motion Parameter units must be in Inches. See also in the wiki here.

See the example SimpleGCodeWPF as an example of how to set the Trajectory Planner Parameters:

Code: Select all

        private void SetMotionParameters()
        {
            KM.CoordMotion.MotionParams.BreakAngle = 30;
            KM.CoordMotion.MotionParams.MaxAccelX = 1;
            KM.CoordMotion.MotionParams.MaxAccelY = 1;
            KM.CoordMotion.MotionParams.MaxAccelZ = 1;
            KM.CoordMotion.MotionParams.MaxAccelA = 1;
            KM.CoordMotion.MotionParams.MaxAccelB = 1;
            KM.CoordMotion.MotionParams.MaxAccelC = 1;
            KM.CoordMotion.MotionParams.MaxVelX = 1;
            KM.CoordMotion.MotionParams.MaxVelY = 1;
            KM.CoordMotion.MotionParams.MaxVelZ = 1;
            KM.CoordMotion.MotionParams.MaxVelA = 1;
            KM.CoordMotion.MotionParams.MaxVelB = 1;
            KM.CoordMotion.MotionParams.MaxVelC = 1;
            KM.CoordMotion.MotionParams.CountsPerInchX = 100;
            KM.CoordMotion.MotionParams.CountsPerInchY = 100;
            KM.CoordMotion.MotionParams.CountsPerInchZ = 100;
            KM.CoordMotion.MotionParams.CountsPerInchA = 100;
            KM.CoordMotion.MotionParams.CountsPerInchB = 100;
            KM.CoordMotion.MotionParams.CountsPerInchC = 100;
            KM.CoordMotion.MotionParams.DegreesA = false;
            KM.CoordMotion.MotionParams.DegreesB = false;
            KM.CoordMotion.MotionParams.DegreesC = false;
        }
HTH
Regards,

Tom Kerekes
Dynomotion, Inc.

dominfo
Posts: 26
Joined: Tue Sep 12, 2023 8:39 am

Re: Limit Feedrate in GCode G1

Post by dominfo » Thu Dec 05, 2024 7:26 pm

Hi Tom,

I use the function KM_AxisGroup.EnableGroup() which should set the trajectory planner settings.

According to your explanation (all MotionParams properties in inch), there is then definitely a bug in its source code:

Code: Select all

for (int i = 0; i < _AxisList.Count; i++)
                {
                    if (_AxisList[i].ID > -1)
                    {
                        switch (i)
                        {
                            case 0:
                                _Controller.CoordMotion.MotionParams.MaxAccelX = _AxisList[i].Acceleration;
                                _Controller.CoordMotion.MotionParams.MaxVelX = _AxisList[i].Velocity;
                                _Controller.CoordMotion.MotionParams.CountsPerInchX = _AxisList[i].CPU;
...
should be

Code: Select all

for (int i = 0; i < _AxisList.Count; i++)
                {
                    if (_AxisList[i].ID > -1)
                    {
                        switch (i)
                        {
                            case 0:
                                _Controller.CoordMotion.MotionParams.MaxAccelX = _AxisList[i].Acceleration / _AxisList[i].CPU;
                                _Controller.CoordMotion.MotionParams.MaxVelX = _AxisList[i].Velocity / _AxisList[i].CPU;
                                _Controller.CoordMotion.MotionParams.CountsPerInchX = _AxisList[i].CPU;
...
Regards
Frederic

User avatar
TomKerekes
Posts: 2703
Joined: Mon Dec 04, 2017 1:49 am

Re: Limit Feedrate in GCode G1

Post by TomKerekes » Thu Dec 05, 2024 10:12 pm

Hi Fredric,

I don't think so as long as Velocity and Acceleration are specified as values in Inches/s and Inches/s^2

Maybe I'm missing something.
Regards,

Tom Kerekes
Dynomotion, Inc.

dominfo
Posts: 26
Joined: Tue Sep 12, 2023 8:39 am

Re: Limit Feedrate in GCode G1

Post by dominfo » Fri Dec 06, 2024 12:47 pm

Hello Tom

I confirm my issue also with KMotionCNC:

ToolSetup settings:
X 1000 counts/inch | Vel 150 | Accel 720
RapidAsFeed unchecked

With the Console:
Vel0=150.00 (equivalent of _AxisList[0].Velocity in .Net)
=> G1 is limited to 150 as expected BUT G0 is now limited to 0.15 (150/1000)

Changing to Vel0=150000
=> The situation is correct: G0 and G1 are limited to 150 units/s

I confirmed the bug reported in .Net because:
AxisList.Velocity and _AxisList.Acceleration must be in counts and not inches. ( _AxisList.Velocity = 150000)
Controller.CoordMotion.MotionParams.MaxVelX and MaxAccelX must be in inches and not in counts (_Controller.CoordMotion.MotionParams.MaxVelX = 150)


Regards
Frederic

User avatar
TomKerekes
Posts: 2703
Joined: Mon Dec 04, 2017 1:49 am

Re: Limit Feedrate in GCode G1

Post by TomKerekes » Sat Dec 07, 2024 12:44 am

Hi Fredric,

I think the issue is with confusion with mm vs inches.
I confirm my issue also with KMotionCNC:

ToolSetup settings:
X 1000 counts/inch | Vel 150 | Accel 720
RapidAsFeed unchecked
What are the units? I assume mm? Are you saying KMotionCNC limits Rapids properly? Is your system 1000 counts/inch or 1000 counts/mm?

With the Console:
Vel0=150.00 (equivalent of _AxisList[0].Velocity in .Net)
=> G1 is limited to 150 as expected BUT G0 is now limited to 0.15 (150/1000)
I don't understand this. The Velocity set in KFLOP should not have any effect on G1. But yes that should set G0 limit to 0.15 inch/sec

What do you want your Rapid limit to be?

Changing to Vel0=150000
=> The situation is correct: G0 and G1 are limited to 150 units/s
That would set G0 to 150 inches/sec and have no effect on G1. Can your system really move 150 inches/second?

I did the following test. Assuming:

Resolution 1000 counts/inch
Desired G0 limit 5 inches/sec
Desired G0 limit 150mm/sec (5.9 inches/sec) (354 inches/min)

KFLOP configures the 5 inch/sec G0 limit with:

Code: Select all

	ch0->Vel=5000;


.NET code sets 1000 counts/inch and 5.9 inches/sec G1 limit with

Code: Select all

            KMotion_dotNet.KM_Axis XAxis = KM.GetAxis(0, "X");
            KMotion_dotNet.KM_Axis YAxis = KM.GetAxis(1, "Y");
            KMotion_dotNet.KM_Axis[] AxisList = { XAxis, YAxis };

            KMotion_dotNet.KM_AxisGroup AxisGroup = KM.GetAxisGroup(123, "TK", AxisList);

            XAxis.Acceleration = 720 / 25.4;
            YAxis.Acceleration = 720 / 25.4;
            XAxis.Velocity = 150 / 25.4;
            YAxis.Velocity = 150 / 25.4;

            XAxis.CPU = 1000; // counts/inch
            YAxis.CPU = 1000;

            AxisGroup.EnableGroup();


Running GCode

Code: Select all

G0 G20 X0 Y0 Z0
F500
G1 X0  Y10
G1 X10 Y10
G1 X10 Y0
G1 X0  Y0
M2

Shows actual G1 Velocity of 5.9 inches/sec

Code: Select all

VelX=  -5.91 Y=   0.00 S=   5.91ips Ax=   0.00 Ay=   0.00
VelX=  -5.91 Y=   0.00 S=   5.91ips Ax=  -0.00 Ay=   0.00
VelX=  -5.91 Y=   0.00 S=   5.91ips Ax=  -0.00 Ay=   0.00
VelX=  -5.91 Y=   0.00 S=   5.91ips Ax=  -0.00 Ay=   0.00
VelX=  -5.91 Y=   0.00 S=   5.91ips Ax=   0.00 Ay=   0.00
VelX=  -5.91 Y=   0.00 S=   5.91ips Ax=  -0.00 Ay=   0.00
VelX=  -5.91 Y=   0.00 S=   5.91ips Ax=  -0.00 Ay=   0.00
VelX=  -4.68 Y=   0.00 S=   4.68ips Ax=  12.09 Ay=   0.00
VelX=  -1.83 Y=   0.00 S=   1.83ips Ax=  28.26 Ay=   0.00
VelX=  -0.03 Y=   0.00 S=   0.03ips Ax=  17.85 Ay=   0.00
HTH
Regards,

Tom Kerekes
Dynomotion, Inc.

dominfo
Posts: 26
Joined: Tue Sep 12, 2023 8:39 am

Re: Limit Feedrate in GCode G1

Post by dominfo » Sat Dec 07, 2024 5:56 pm

Hi,

Please see my picture below which may help to understand what I found on my experiments.
explanation.jpg
In Green (G1 related), I agree with you and find that G1 works as expected.
In Red (G0 related), the change done by

Code: Select all

 XAxis.Velocity = 150 / 25.4; 
changes automatically the G0 limit in KFLOP (ch0->Vel is now 5.91, replacing the previous value of 5000 for limiting to 5 inches/s with the resolution of 1000 counts/inch)
=> see below KMotion_dotNet.KM_Axis Velocity property which acts on this parameter.

Code: Select all

        /// <summary>
        /// Commanded velocity to use during positioning 
        /// </summary>
        public double Velocity
        {
            get
            {
                return _Velocity;
            }
            set
            {
                _Velocity = value;
                _Controller.WriteLine(String.Format("Vel{0}={1}", _ID, _Velocity));
            }
        }
Now the problem:
Running the Gcode, you should see that G0X0Y0Z0 is slow (maybe you did not see it if KFLOP was already at X0Y0Z0 position).
Please replace your first line by G0 G20 X10 Y0 Z0 to see the too slow G0 move, being limited to 0.00591 inches/s.

Code: Select all

G20 G01 X5 Y0 Z0 F18000
G0 X10
M2

outputs the following 

<Feed=5.90980 units/s ch0->Vel=   5.91> // G1 in progress
<Feed=5.90972 units/s ch0->Vel=   5.91>
<Feed=5.90971 units/s ch0->Vel=   5.91>
<Feed=5.90971 units/s ch0->Vel=   5.91>
<Feed=5.90971 units/s ch0->Vel=   5.91>
<Feed=5.90958 units/s ch0->Vel=   5.91>
<Feed=5.90985 units/s ch0->Vel=   5.91>
<Feed=5.12061 units/s ch0->Vel=   5.91> // G1 ending near X5
<Feed=0.00276 units/s ch0->Vel=   5.91> // G0 starting to X10
<Feed=0.00590 units/s ch0->Vel=   5.91>
<Feed=0.00591 units/s ch0->Vel=   5.91> // G0 at full "low" speed
<Feed=0.00591 units/s ch0->Vel=   5.91>
<Feed=0.00591 units/s ch0->Vel=   5.91>
<Feed=0.00591 units/s ch0->Vel=   5.91>
<Feed=0.00591 units/s ch0->Vel=   5.91>
<Feed=0.00591 units/s ch0->Vel=   5.91>
<Feed=0.00591 units/s ch0->Vel=   5.91>
<Feed=0.00591 units/s ch0->Vel=   5.91> 
Concerning inches or mm:
I did all my experiments considering inches, even if my values are big, those are just examples. Moreover, I don't have motors connected to the KFLOP so my values can be stupid sure.
I use G20 in the tested GCode programs to be sure that the interpreter is in inches.

I hope that my explanation is clear, and that you will also find the G0 issue in your test configuration.

Regards
Frederic

User avatar
TomKerekes
Posts: 2703
Joined: Mon Dec 04, 2017 1:49 am

Re: Limit Feedrate in GCode G1

Post by TomKerekes » Sun Dec 08, 2024 1:48 am

Hi Fredric,

Thanks for the complete explanation. You are correct. There are several flaws in the KM_Axis/KM_AxisGroup classes. I don't think anyone has been using the KM_AxisGroup.EnableGroup call to set the Motion Parameters.

We're thinking to make the following changes to KM_Axis/KM_AxisGroup:
  1. Velocity and Acceleration will be in 'Units' (inches or mm) and represent the values for Independent motions, Jogging, and G0 Rapids.
  2. Jerk will be added to be complete and will be in 'Units' as well.
  3. When set these values will be written to KFLOP/Kogna multiplied by the CPU (Counts/per unit)
  4. 2 new Parameters CoordVelocity and CoordAccel will be added for Coordinated Motion and be in 'Units'
  5. A new Boolean, CPU_is_mm will be added to indicate if Units are mm, otherwise Units are Inches, which will be used within EnableGroup to set the MotionParameters in inches appropriately
Any thoughts?
Regards,

Tom Kerekes
Dynomotion, Inc.

dominfo
Posts: 26
Joined: Tue Sep 12, 2023 8:39 am

Re: Limit Feedrate in GCode G1

Post by dominfo » Sun Dec 08, 2024 6:14 pm

Hi Tom,
Perfect !
I fully agree with your proposal.
TomKerekes wrote:
Sun Dec 08, 2024 1:48 am
Hi Fredric,

Thanks for the complete explanation. You are correct. There are several flaws in the KM_Axis/KM_AxisGroup classes. I don't think anyone has been using the KM_AxisGroup.EnableGroup call to set the Motion Parameters.

We're thinking to make the following changes to KM_Axis/KM_AxisGroup:
  1. Velocity and Acceleration will be in 'Units' (inches or mm) and represent the values for Independent motions, Jogging, and G0 Rapids.
  2. Jerk will be added to be complete and will be in 'Units' as well.
  3. When set these values will be written to KFLOP/Kogna multiplied by the CPU (Counts/per unit)
  4. 2 new Parameters CoordVelocity and CoordAccel will be added for Coordinated Motion and be in 'Units'
  5. A new Boolean, CPU_is_mm will be added to indicate if Units are mm, otherwise Units are Inches, which will be used within EnableGroup to set the MotionParameters in inches appropriately
Any thoughts?
Not thoughts but another issue with this command

Code: Select all

XAxis.Velocity = 150 / 25.4;
KMotion_dotNet.KM_CoordMotion.StraightTraverse(...)
The first StraightTraverse will run at the specified feed as expected (5.91 in this case).
Change XAxis.Velocity to 3 as an example, and run another StraightTraverse move.
The move still will run at 5.91 and not 3.
=> The new Velocity value is not used by KFlop.

I analysed deeper your source code and found the reason in GCodeInterpreter.cpp: The CoordMotion property RapidParamsDirty is not set to True when changing an axis Velocity.
I solved the issue by faking the KFlop in 3 steps:
1/ change Velocity
2/ run an empty Gcode file with the KMotion_dotNet.KM_CoordMotion.Interpreter.Interpret function.
3/ run the StraightTraverse move

The KMotion_dotNet.KM_CoordMotion.Interpreter.Interpret (in Step2 ) runs the code below found in GCodeInterpreter.cpp, which sets RapidParamsDirty to true (meaning a recalculation of the Rapid-StraightTraverse velocity)

Code: Select all

int CGCodeInterpreter::Interpret(
			  int board_type,
		      const char *fname,
			  int start, int end,
			  int restart,
              G_STATUS_CALLBACK *StatusFn,
			  G_COMPLETE_CALLBACK *CompleteFn)
{
we 	CoordMotion->m_board_type=board_type;
	CoordMotion->ClearAbort();
	CoordMotion->m_AxisDisabled=false;
	CoordMotion->RapidParamsDirty=true;

	m_CurrentLine=m_start=start;
	m_end=end;
	m_restart=restart;
	m_CompleteFn=CompleteFn;
	m_StatusFn=StatusFn;
	m_InFile=fname;
	m_Halt=m_HaltNextLine=false;
	CoordMotion->ClearHalt();

	LaunchExecution();	
	
	return 0;
}
Please can we have a smarter way to skip the Step 2 (exposing RapidParamsDirty to .Net with a method or property in KMotion_dotNet.KM_CoordMotion)?

Regards and thanks again for your highly appreciated support.
Frederic

User avatar
TomKerekes
Posts: 2703
Joined: Mon Dec 04, 2017 1:49 am

Re: Limit Feedrate in GCode G1

Post by TomKerekes » Wed Dec 11, 2024 10:29 pm

Hi Frederic,

Here is a patch for V5.3.6 which hopefully straightens things our with the KM_Axis/KM_AxisGroup classes.

Copy the dlls from here to the KMotion\Release folder. The changed sources are also there if needed.

Here is a description of the changes:

Fix bug with KM_IO.SetAnalogValue(int value)
Expose Interpreter.SaveVars to save the GCode Interpreter Variables to disk which include fixture and global offsets.
Expose CoordMotion.RapidParamsDirty to force refresh of Rapid axis parameters from KFLOP/Kogna
Expose DoRapidsAsFeeds which breaks down Rapids into small segments which is necessary for non-linear kinematics so that Rapids follow a straight line in CAD Space (which is curved in actuator space).
Fix Issues with KM_Axis and KM_AxisGroup:
1. Velocity and Acceleration will be in 'Units' (inches or mm) and represent the values for Independent motions, Jogging, and G0 Rapids.
2. Jerk will be added to be complete and will be in 'Units' as well.
3. When set these values will be written to KFLOP/Kogna multiplied by the CPU (Counts/per unit)
4. 2 new Parameters CoordVelocity and CoordAccel will be added for Coordinated Motion and be in 'Units'
5. Changed KM_AxisGroup property name from Velocity to FeedRate
6. A new Boolean, CPU_is_mm will be added to indicate if Units are mm, otherwise Units are Inches, which will be used within EnableGroup to set the MotionParameters in inches appropriately



Here is the example code that I tested:

Code: Select all

            KMotion_dotNet.KM_Axis XAxis = KM.GetAxis(0, "X");
            KMotion_dotNet.KM_Axis YAxis = KM.GetAxis(1, "Y");
            KMotion_dotNet.KM_Axis[] AxisList = { XAxis, YAxis };

            KMotion_dotNet.KM_AxisGroup AxisGroup = KM.GetAxisGroup(123, "TK", AxisList);

            XAxis.CPU = 1000; // counts/inch (must set first)
            XAxis.CPU_is_mm = false; // (actually not necessary as default is inches)
            YAxis.CPU = 1000;
            YAxis.CPU_is_mm = false;

            // set rapid 3rd order parameters
            XAxis.Jerk = 280; // inches/sec3
            YAxis.Jerk = 280;
            XAxis.Acceleration = 28;  // inches/sec2
            YAxis.Acceleration = 28;
            XAxis.Velocity = 5.9;  // inches/sec
            YAxis.Velocity = 5.9;

            // set Coordinated motion 2nd order parameters
            XAxis.CoordVelocity = 3; //inches/sec
            XAxis.CoordAccel = 30; // inches/sec2
            YAxis.CoordVelocity = 3; //inches/sec
            YAxis.CoordAccel = 30; // inches/sec2

            AxisGroup.EnableGroup();
Please let us know if you find any issues
Regards,

Tom Kerekes
Dynomotion, Inc.

Post Reply