I am using C# to make a path on an X,Y, Z Axis machine. Just a simple line. It is a router tool for making louvers on a board.
The picture I include is a sample of the tool paths. The lower number written by the path is a speed give for the path.
The faster the speed the trailing path is distorted. Could you help me solve on what is going on. Only if it is a setting in the
Coor Motion C# interface. It distorts the faster the speed.
Thank you.
David Taylor
C# Coor Motion
Moderators: TomKerekes, dynomotion
- TomKerekes
- Posts: 2677
- Joined: Mon Dec 04, 2017 1:49 am
Re: C# Coor Motion
Hi David,
It looks like the XY motion trajectory is faster than the axes are able to move so the router lags behind where it is supposed to be. Also because the X motion is less than the Y motion it gets to the final position before the Y.
What are units of the Speeds? Normally the Coordinate Motion Library works in inches/second.
I assume these are Servos? What are your settings? Have you tested these speeds in the KMotion.exe Step Response Screen?
It could be that your Axes aren't capable of this speed or your parameters (max limits) are limiting what is being commanded to the amplifiers.
Also Max Following Error is normally set to a small number so that if an axes ever lags behind by a significant amount the axis disables and motion stops rather that going on with large errors.
It looks like the XY motion trajectory is faster than the axes are able to move so the router lags behind where it is supposed to be. Also because the X motion is less than the Y motion it gets to the final position before the Y.
What are units of the Speeds? Normally the Coordinate Motion Library works in inches/second.
I assume these are Servos? What are your settings? Have you tested these speeds in the KMotion.exe Step Response Screen?
It could be that your Axes aren't capable of this speed or your parameters (max limits) are limiting what is being commanded to the amplifiers.
Also Max Following Error is normally set to a small number so that if an axes ever lags behind by a significant amount the axis disables and motion stops rather that going on with large errors.
Regards,
Tom Kerekes
Dynomotion, Inc.
Tom Kerekes
Dynomotion, Inc.
-
- Posts: 15
- Joined: Fri Mar 22, 2019 7:37 pm
Re: C# Coor Motion
This is the crux of the problem, we have no idea what the units of speed are (group.velocity?). We normally run everything in a standardized inches per minute, and for example the X axis (left and right represented in the provided image) can handle upwards of 3800 inches per minute with a counts per inch gear ratio of 6288.3. While the Y axis is capable of over 1880 inches per minute, geared at 12700 counts per inch..
In the example you have built we are using a speed value of 0 to 5 units? How these decimals correlate to velocity values in the thousands is a mystery to me.
Normally we cut these types of features between 100-300 inches per minute on our other machines/controllers.
I did increase the Accel and the behavior seem to have correct it self.
Thank you Tom
David Taylor
In the example you have built we are using a speed value of 0 to 5 units? How these decimals correlate to velocity values in the thousands is a mystery to me.
Normally we cut these types of features between 100-300 inches per minute on our other machines/controllers.
I did increase the Accel and the behavior seem to have correct it self.
Thank you Tom
David Taylor
-
- Posts: 15
- Joined: Fri Mar 22, 2019 7:37 pm
Re: C# Coor Motion
On the first and second grove we get a hole then the grove then hole at the end.
I am giving the start and end the same X,Y yet it is off all at the beginning and end.
The big distortion on the last grove is gone. But still getting the knobs at begging ang end.
Any ideal how to solve this.
Thank You,
David Taylor
I am giving the start and end the same X,Y yet it is off all at the beginning and end.
The big distortion on the last grove is gone. But still getting the knobs at begging ang end.
Any ideal how to solve this.
Thank You,
David Taylor
-
- Posts: 15
- Joined: Fri Mar 22, 2019 7:37 pm
- TomKerekes
- Posts: 2677
- Joined: Mon Dec 04, 2017 1:49 am
Re: C# Coor Motion
Hi David,
Those are very high speeds. 3800 ipm is over 5 feet in a second. Have you tested these speeds in the KMotion Step Response Screen? What are the following errors at those speeds? What Acceleration and Jerk are you testing? Please post Step Response Screen Plots.
Generally our libraries operate in inches and seconds. To convert inches per minute to inches per second divide by 60 seconds/minute. So 3800ipm = 63.3ips.
The Step Response Screen uses units of counts. So for example for X to test the 15ips that would be 15x6288.3 = 94324.5 counts/sec
Before attempting to run coordinated motion you must make sure the axes are working accurately and what velocities and accelerations are possible.
So I assume these are Servos?This is the crux of the problem, we have no idea what the units of speed are (group.velocity?). We normally run everything in a standardized inches per minute, and for example the X axis (left and right represented in the provided image) can handle upwards of 3800 inches per minute with a counts per inch gear ratio of 6288.3. While the Y axis is capable of over 1880 inches per minute, geared at 12700 counts per inch..
Those are very high speeds. 3800 ipm is over 5 feet in a second. Have you tested these speeds in the KMotion Step Response Screen? What are the following errors at those speeds? What Acceleration and Jerk are you testing? Please post Step Response Screen Plots.
Generally our libraries operate in inches and seconds. To convert inches per minute to inches per second divide by 60 seconds/minute. So 3800ipm = 63.3ips.
The Step Response Screen uses units of counts. So for example for X to test the 15ips that would be 15x6288.3 = 94324.5 counts/sec
Before attempting to run coordinated motion you must make sure the axes are working accurately and what velocities and accelerations are possible.
Regards,
Tom Kerekes
Dynomotion, Inc.
Tom Kerekes
Dynomotion, Inc.
-
- Posts: 15
- Joined: Fri Mar 22, 2019 7:37 pm
Re: C# Coor Motion
public void Init(List<AxisNodeContainer> axes, int devicenumber, string name,
double vvel, double vacc, double vdec, double v_Jerk)
{
_Axes = axes;
_DevNum = devicenumber;
_Name = name;
_NumAxis = axes.Count;
_CPU = new double[_NumAxis];
_AxisNums = new int[_NumAxis];
_MaxAccel = new double[_NumAxis];
_MaxDecel = new double[_NumAxis];
_MaxJerk = new double[_NumAxis];
_VelCounts = new double[_NumAxis];
_Accel = new double[_NumAxis];
_AccelCounts = new double[_NumAxis];
_Decel = new double[_NumAxis];
_DecelCounts = new double[_NumAxis];
_Jerk = new double[_NumAxis];
double invert;
axisNum = 0;
foreach (AxisNodeContainer axis in _Axes)
{
if (axis.Node.Inverted)
invert = -1D;
else
invert = 1D;
_CPU[axisNum] = axis.Node.CountsPerUnit * invert;
_AxisNums[axisNum] = axis.Node.AxisData.NodeId;
_MaxAccel[axisNum] = axis.Node.MaxAccel;
_MaxDecel[axisNum] = axis.Node.MaxDecel;
_MaxJerk[axisNum] = axis.Node.JerkPercentage;
axisNum++;
}
_AccelCounts = AxisUtil.AccelToCounts(_MaxAccel, _CPU);
_DecelCounts = AxisUtil.AccelToCounts(_MaxDecel, _CPU);
_Jerk = _MaxJerk;
_VectorVelocity = 10;
_VectorAccel = 3000;
_VectorDecel = 3000;
_VectorJerk = 66;
var axislist = from a in _Axes select a.GetDevice() as KM_Axis;
_AxisGroupObject = new KM_AxisGroup(DYN_Controller.Instance.Controller, axislist.ToArray());
_AxisGroupObject.Velocity = 1000;
_AxisGroupObject.Acceleration = 500;
DYN_Controller.Instance.Controller.CoordMotion.Abort();
DYN_Controller.Instance.Controller.CoordMotion.ClearAbort();
DYN_Controller.Instance.Controller.WriteLine(String.Format("DefineCS = {0} {1} {2} {3} {4} {5}", 0, 1, 2, -1, -1, -1));
DYN_Controller.Instance.Controller.WriteLine(String.Format("EnableAxis{0}", 0));
DYN_Controller.Instance.Controller.WriteLine(String.Format("EnableAxis{0}", 1));
DYN_Controller.Instance.Controller.WriteLine(String.Format("EnableAxis{0}", 2));
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.BreakAngle = 30;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.RadiusA = 5;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.RadiusB = 5;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.RadiusC = 5;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.MaxAccelA = 30;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.MaxAccelB = 30;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.MaxAccelC = 30;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.MaxVelA = 100;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.MaxVelB = 100;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.MaxVelC = 100;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.MaxVelX = axes[0].MaxVel;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.MaxAccelX = 100;
_AxisGroupObject.AxisList[0].CPU = _CPU[0];
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.CountsPerInchX = _CPU[0];
if (axisNum >= 2)
{
_AxisGroupObject.AxisList[1].CPU = _CPU[1];
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.CountsPerInchY = _CPU[1];
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.MaxVelY = axes[1].MaxVel;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.MaxAccelY = 100;
}
if (axisNum >= 3)
{
_AxisGroupObject.AxisList[2].CPU = _CPU[2];
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.CountsPerInchZ = _CPU[2];
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.MaxVelZ = axes[2].MaxVel;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.MaxAccelZ = 100;
}
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.CountsPerInchA = 1;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.CountsPerInchB = 1;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.CountsPerInchC = 1;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.DegreesA = false;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.DegreesB = false;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.DegreesC = false;
_AxisGroupObject.ClearAbort();
_AxisGroupObject.EnableGroup();
}
double vvel, double vacc, double vdec, double v_Jerk)
{
_Axes = axes;
_DevNum = devicenumber;
_Name = name;
_NumAxis = axes.Count;
_CPU = new double[_NumAxis];
_AxisNums = new int[_NumAxis];
_MaxAccel = new double[_NumAxis];
_MaxDecel = new double[_NumAxis];
_MaxJerk = new double[_NumAxis];
_VelCounts = new double[_NumAxis];
_Accel = new double[_NumAxis];
_AccelCounts = new double[_NumAxis];
_Decel = new double[_NumAxis];
_DecelCounts = new double[_NumAxis];
_Jerk = new double[_NumAxis];
double invert;
axisNum = 0;
foreach (AxisNodeContainer axis in _Axes)
{
if (axis.Node.Inverted)
invert = -1D;
else
invert = 1D;
_CPU[axisNum] = axis.Node.CountsPerUnit * invert;
_AxisNums[axisNum] = axis.Node.AxisData.NodeId;
_MaxAccel[axisNum] = axis.Node.MaxAccel;
_MaxDecel[axisNum] = axis.Node.MaxDecel;
_MaxJerk[axisNum] = axis.Node.JerkPercentage;
axisNum++;
}
_AccelCounts = AxisUtil.AccelToCounts(_MaxAccel, _CPU);
_DecelCounts = AxisUtil.AccelToCounts(_MaxDecel, _CPU);
_Jerk = _MaxJerk;
_VectorVelocity = 10;
_VectorAccel = 3000;
_VectorDecel = 3000;
_VectorJerk = 66;
var axislist = from a in _Axes select a.GetDevice() as KM_Axis;
_AxisGroupObject = new KM_AxisGroup(DYN_Controller.Instance.Controller, axislist.ToArray());
_AxisGroupObject.Velocity = 1000;
_AxisGroupObject.Acceleration = 500;
DYN_Controller.Instance.Controller.CoordMotion.Abort();
DYN_Controller.Instance.Controller.CoordMotion.ClearAbort();
DYN_Controller.Instance.Controller.WriteLine(String.Format("DefineCS = {0} {1} {2} {3} {4} {5}", 0, 1, 2, -1, -1, -1));
DYN_Controller.Instance.Controller.WriteLine(String.Format("EnableAxis{0}", 0));
DYN_Controller.Instance.Controller.WriteLine(String.Format("EnableAxis{0}", 1));
DYN_Controller.Instance.Controller.WriteLine(String.Format("EnableAxis{0}", 2));
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.BreakAngle = 30;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.RadiusA = 5;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.RadiusB = 5;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.RadiusC = 5;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.MaxAccelA = 30;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.MaxAccelB = 30;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.MaxAccelC = 30;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.MaxVelA = 100;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.MaxVelB = 100;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.MaxVelC = 100;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.MaxVelX = axes[0].MaxVel;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.MaxAccelX = 100;
_AxisGroupObject.AxisList[0].CPU = _CPU[0];
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.CountsPerInchX = _CPU[0];
if (axisNum >= 2)
{
_AxisGroupObject.AxisList[1].CPU = _CPU[1];
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.CountsPerInchY = _CPU[1];
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.MaxVelY = axes[1].MaxVel;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.MaxAccelY = 100;
}
if (axisNum >= 3)
{
_AxisGroupObject.AxisList[2].CPU = _CPU[2];
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.CountsPerInchZ = _CPU[2];
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.MaxVelZ = axes[2].MaxVel;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.MaxAccelZ = 100;
}
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.CountsPerInchA = 1;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.CountsPerInchB = 1;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.CountsPerInchC = 1;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.DegreesA = false;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.DegreesB = false;
DYN_Controller.Instance.Controller.CoordMotion.MotionParams.DegreesC = false;
_AxisGroupObject.ClearAbort();
_AxisGroupObject.EnableGroup();
}