示例#1
0
        public StepsPosition ToStepsPosition(UnitsPosition current, double feedrate, bool fastMovement)
        {
            // Delta Position & Delta Steps -> with this movement
            double xDelta = Math.Abs(this.X - current.X);
            double yDelta = Math.Abs(this.Y - current.Y);
            double zDelta = Math.Abs(this.Z - current.Z);
            // creamos el vector EN PASOS del movimiento que va a hacer la punta
            StepsPosition lineSteps = new StepsPosition(
                            Convert.ToInt64(Math.Ceiling(this.X * Configuration.configValueX)),
                            Convert.ToInt64(Math.Ceiling(this.Y * Configuration.configValueY)),
                            Convert.ToInt64(Math.Ceiling(this.Z * Configuration.configValueZ)));

            if (fastMovement)
            {
                lineSteps.Delay = 1;
                return lineSteps;
            }

            // delay parameters
            double totalDistance = Math.Sqrt(xDelta * xDelta + yDelta * yDelta + zDelta * zDelta);
            //if (curveLength == -1) curveLength = totalDistance * totalDistance; // To handle lines and curveSections

            long maxDeltaSteps = Convert.ToInt64(Math.Ceiling(Math.Max(xDelta * Configuration.configValueX, yDelta * Configuration.configValueY)));
            maxDeltaSteps = Convert.ToInt64(Math.Ceiling(Math.Max(maxDeltaSteps, zDelta * Configuration.configValueZ)));
            // Calculating Delay: totalDistance * 1 second(microseconds) / speed / maxDelta / 2-changeStates per step / milliseconds
            if (maxDeltaSteps > 0)
            {
                lineSteps.Delay = Convert.ToInt64(Math.Ceiling( totalDistance * 60000000.0 / feedrate / maxDeltaSteps / 2 / 1000)); // time between clock for most dinamyc axis - microseconds
            }
            else
            {
                lineSteps.Delay = 0;
            }
            return lineSteps;
        }
        private UnitsPosition GetCenterPosition(string command)
        {
            UnitsPosition result = new UnitsPosition();

            if (HasValueParameter('R', command))
            {
                double r = GetValueParameter('R', command);
                result = GetFromRadius(r, command);
            }
            else
            {
                // The center point is relative to the start position... Translate to absolute programming mode
                result.X = GetValueParameter('I', command) + this.CurrentPosition.X;
                result.Y = GetValueParameter('J', command) + this.CurrentPosition.Y;
                result.Z = GetValueParameter('K', command) + this.CurrentPosition.Z;
            }

            return result;
        }
示例#3
0
 public StepsPosition ToStepsPosition(UnitsPosition current, double feedrate)
 {
     return ToStepsPosition(current, feedrate, false);
 }
        private List<UnitsPosition> ProcessCurvePlaneYZ(string code)
        {
            List<UnitsPosition> result = new List<UnitsPosition>();
            double feedRate = HasValueParameter('F', code) ? GetValueParameter('F', code) : Configuration.defaultFeedrate; // Ver qué valor va cuando no hay valor - CONFIGURACION? -

            UnitsPosition startPosition = this.CurrentPosition;
            UnitsPosition finalPosition = this.GetFinalPosition(code);
            UnitsPosition centerPosition = this.GetCenterPosition(code);
            int gCode = Convert.ToInt32(GetValueParameter('G', code));
            bool clockwise = gCode == 2 ? true : false;

            double aY, aZ, bY, bZ, angleA, angleB, angle, radius, length;
            int steps;

            aY = currentPosition.Y - centerPosition.Y;
            aZ = currentPosition.Z - centerPosition.Z;
            bY = finalPosition.Y - centerPosition.Y;
            bZ = finalPosition.Z - centerPosition.Z;

            angleA = clockwise ? Math.Atan2(bZ, bY) : Math.Atan2(aZ, aY);
            angleB = clockwise ? Math.Atan2(aZ, aY) : Math.Atan2(bZ, bY);

            if (angleB <= angleA) angleB += 2 * Math.PI;
            angle = angleB - angleA;

            radius = Math.Sqrt(aY * aY + aZ * aZ);
            length = radius * angle;
            steps = (int)(length / Configuration.millimetersCurveSection);

            for (int s = 1; s <= steps; s++)
            {
                UnitsPosition sectionPosition = new UnitsPosition();
                int step = clockwise ? steps - s : s;
                sectionPosition.X = (finalPosition.X - startPosition.X) * ((float)s / steps);
                sectionPosition.Y = centerPosition.Y + radius * Math.Cos(angleA + angle * ((float)step / steps));
                sectionPosition.Z = centerPosition.Z + radius * Math.Sin(angleA + angle * ((float)step / steps));

                if ((sectionPosition.X < 0) || (sectionPosition.Y < 0) || (sectionPosition.Z < 0))
                {
                    logger.Error("Underflow procesando: " + code + ".");
                    throw new Exception("Underflow procesando: " + code + ".");
                }

                result.Add(sectionPosition);
            }

            return result;
        }
        private List<UnitsPosition> ProcessCurvePlaneXY(string code)
        {
            List<UnitsPosition> result = new List<UnitsPosition>();
            double feedRate = HasValueParameter('F', code) ? GetValueParameter('F', code) : Configuration.defaultFeedrate; // Ver qué valor va cuando no hay valor - CONFIGURACION? -

            UnitsPosition startPosition = this.CurrentPosition;
            logger.Info("procesando curva XY");
            UnitsPosition finalPosition = this.GetFinalPosition(code);
            UnitsPosition centerPosition = this.GetCenterPosition(code);
            int gCode = Convert.ToInt32(GetValueParameter('G', code));
            bool clockwise = gCode == 2 ? true : false;

            double aX, aY, bX, bY, angleA, angleB, angle, radius, length;
            int steps;

            aX = currentPosition.X - centerPosition.X;
            aY = currentPosition.Y - centerPosition.Y;
            bX = finalPosition.X - centerPosition.X;
            bY = finalPosition.Y - centerPosition.Y;

            angleA = clockwise ? Math.Atan2(bY, bX) : Math.Atan2(aY, aX);
            angleB = clockwise ? Math.Atan2(aY, aX) : Math.Atan2(bY, bX);

            if (angleB <= angleA) angleB += 2 * Math.PI;
            angle = angleB - angleA;

            radius = Math.Sqrt(aX * aX + aY * aY);
            length = radius * angle;
            steps = (int)(length / Configuration.millimetersCurveSection);
            steps = steps == 0 ? 1 : steps;

            for (int s = 1; s <= steps; s++)
            {
                UnitsPosition sectionPosition = new UnitsPosition();
                int step = clockwise ? steps - s : s;
                sectionPosition.X = centerPosition.X + radius * Math.Cos(angleA + angle * ((float)step / steps));
                sectionPosition.Y = centerPosition.Y + radius * Math.Sin(angleA + angle * ((float)step / steps));
                sectionPosition.Z = (finalPosition.Z - startPosition.Z) * ((float)s / steps) + this.ReferencePosition.Z;

                if ((sectionPosition.X < 0) || (sectionPosition.Y < 0) || (sectionPosition.Z < 0))
                {
                    logger.Error("Underflow procesando: " + code + ".");
                    throw new Exception("Underflow procesando: " + code + ". (PuntoDestino: X" + sectionPosition.X + " Y" + sectionPosition.Y + " Z" + sectionPosition.Z);
                }

                // Traducir la curva (G02 / G03) como varias rectas (G01)
                result.Add(sectionPosition);
            }

            return result;
        }
 protected CommandPreprocessor()
 {
     this.workingPlane = WorkingPlane.XY;
     this.currentPosition = new UnitsPosition(0, 0, 0);
     this.referencePosition = new UnitsPosition(0, 0, 0);
 }
        private UnitsPosition GetFromRadius(double r, string command)
        {
            double midX, midY, midZ, cat1x, cat1y, cat1z, cat1, cat2x, cat2y, cat2z, cat2;
            logger.Info("Get from radius");
            UnitsPosition final = GetFinalPosition(command);
            UnitsPosition centerPosition = new UnitsPosition();

            // componentes de Punto Medio de segmento que une Punto Inicial con Punto Final
            midZ = (final.Z + CurrentPosition.Z) / 2;
            midY = (final.Y + CurrentPosition.Y) / 2;
            midX = (final.X + CurrentPosition.X) / 2;
            // componentes de Longitud desde Punto Inicial a Punto Medio de segmento
            cat1x = midX - CurrentPosition.X;
            cat1y = midY - CurrentPosition.Y;
            cat1z = midZ - CurrentPosition.Z;

            switch (this.WorkingPlane)
            {
                case WorkingPlane.XY:
                    cat1 = Math.Sqrt(cat1x * cat1x + cat1y * cat1y);

                    if (cat1 > Math.Abs(r))
                    {
                        logger.Error("Imposible realizar arco: " + command + ". (Distancia media entre punto inicial y final es mayor al radio)");
                        throw new Exception("Imposible realizar arco: " + command + ". (Distancia media entre punto inicial y final es mayor al radio)");
                    }

                    cat2 = Math.Sqrt(r * r - cat1 * cat1);
                    cat2x = cat1y * cat2 / cat1;
                    cat2y = -cat1x * cat2 / cat1;

                    if (r > 0)
                    {
                        centerPosition.X = midX + cat2x;
                        centerPosition.Y = midY + cat2y;
                    }
                    else
                    {
                        centerPosition.X = midX - cat2x;
                        centerPosition.Y = midY - cat2y;
                    }
                    centerPosition.Z = midZ;
                    break;

                case WorkingPlane.XZ:
                    cat1 = Math.Sqrt(cat1x * cat1x + cat1z * cat1z);

                    if (cat1 > Math.Abs(r))
                    {
                        logger.Error("Imposible realizar arco: " + command + ". (Distancia media entre punto inicial y final es mayor al radio)");
                        throw new Exception("Imposible realizar arco: " + command + ". (Distancia media entre punto inicial y final es mayor al radio)");
                    }

                    cat2 = Math.Sqrt(r * r - cat1 * cat1);
                    cat2x = cat1z * cat2 / cat1;
                    cat2z = -cat1x * cat2 / cat1;

                    if (r > 0)
                    {
                        centerPosition.X = midX + cat2x;
                        centerPosition.Z = midZ + cat2z;
                    }
                    else
                    {
                        centerPosition.X = midX - cat2x;
                        centerPosition.Z = midZ - cat2z;
                    }
                    centerPosition.Y = midY;
                    break;

                case WorkingPlane.YZ:
                    cat1 = Math.Sqrt(cat1y * cat1y + cat1z * cat1z);

                    if (cat1 > Math.Abs(r))
                    {
                        logger.Error("Imposible realizar arco: " + command + ". (Distancia media entre punto inicial y final es mayor al radio)");
                        throw new Exception("Imposible realizar arco: " + command + ". (Distancia media entre punto inicial y final es mayor al radio)");
                    }

                    cat2 = Math.Sqrt(r * r - cat1 * cat1);
                    cat2y = cat1z * cat2 / cat1;
                    cat2z = -cat1y * cat2 / cat1;

                    if (r > 0)
                    {
                        centerPosition.Y = midY + cat2y;
                        centerPosition.Z = midZ + cat2z;
                    }
                    else
                    {
                        centerPosition.Y = midY - cat2y;
                        centerPosition.Z = midZ - cat2z;
                    }
                    centerPosition.X = midX;
                    break;
            }
            return centerPosition;
        }
        private UnitsPosition GetFinalPosition(string command)
        {
            UnitsPosition result = new UnitsPosition();

            if (Configuration.absoluteProgamming)
            {
                result.X = HasValueParameter('X', command) ? GetValueParameter('X', command) + this.ReferencePosition.X : CurrentPosition.X;
                result.Y = HasValueParameter('Y', command) ? GetValueParameter('Y', command) + this.ReferencePosition.Y : CurrentPosition.Y;
                result.Z = HasValueParameter('Z', command) ? this.ReferencePosition.Z - GetValueParameter('Z', command) : CurrentPosition.Z;
            }
            else
            {
                // Translate to relative programming mode
                result.X = HasValueParameter('X', command) ? GetValueParameter('X', command) + this.CurrentPosition.X : CurrentPosition.X;
                result.Y = HasValueParameter('Y', command) ? GetValueParameter('Y', command) + this.CurrentPosition.Y : CurrentPosition.Y;
                result.Z = HasValueParameter('Z', command) ? this.CurrentPosition.Z - GetValueParameter('Z', command) : CurrentPosition.Z;
            }

            logger.Info("voy a ir al Z " + result.Z);
            if (result.Z < 0) throw new Exception("Movimiento Inválido. (Eje Z sobrepasa límite superior)");

            // If the values are in inches, convert to millimeters
            if (!Configuration.millimetersProgramming)
            {
                result.X *= 25.4;
                result.Y *= 25.4;
                result.Z *= 25.4;
            }

            return result;
        }