Page 1 of 3
Limit Feedrate in GCode G1
Posted: Thu Dec 05, 2024 2:48 pm
by dominfo
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
Re: Limit Feedrate in GCode G1
Posted: Thu Dec 05, 2024 6:00 pm
by TomKerekes
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
Re: Limit Feedrate in GCode G1
Posted: Thu Dec 05, 2024 7:26 pm
by dominfo
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
Re: Limit Feedrate in GCode G1
Posted: Thu Dec 05, 2024 10:12 pm
by TomKerekes
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.
Re: Limit Feedrate in GCode G1
Posted: Fri Dec 06, 2024 12:47 pm
by dominfo
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
Re: Limit Feedrate in GCode G1
Posted: Sat Dec 07, 2024 12:44 am
by TomKerekes
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:
.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
Re: Limit Feedrate in GCode G1
Posted: Sat Dec 07, 2024 5:56 pm
by dominfo
Hi,
Please see my picture below which may help to understand what I found on my experiments.
In Green (G1 related), I agree with you and find that G1 works as expected.
In Red (G0 related), the change done by
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
Re: Limit Feedrate in GCode G1
Posted: Sun Dec 08, 2024 1:48 am
by TomKerekes
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:
- Velocity and Acceleration will be in 'Units' (inches or mm) and represent the values for Independent motions, Jogging, and G0 Rapids.
- Jerk will be added to be complete and will be in 'Units' as well.
- When set these values will be written to KFLOP/Kogna multiplied by the CPU (Counts/per unit)
- 2 new Parameters CoordVelocity and CoordAccel will be added for Coordinated Motion and be in 'Units'
- 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?
Re: Limit Feedrate in GCode G1
Posted: Sun Dec 08, 2024 6:14 pm
by dominfo
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:
- Velocity and Acceleration will be in 'Units' (inches or mm) and represent the values for Independent motions, Jogging, and G0 Rapids.
- Jerk will be added to be complete and will be in 'Units' as well.
- When set these values will be written to KFLOP/Kogna multiplied by the CPU (Counts/per unit)
- 2 new Parameters CoordVelocity and CoordAccel will be added for Coordinated Motion and be in 'Units'
- 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
Re: Limit Feedrate in GCode G1
Posted: Wed Dec 11, 2024 10:29 pm
by TomKerekes
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