/// <summary> /// Calcola percorso di spianatura a spirale /// </summary> /// <param name="programPhase"></param> /// <param name="offsetX"></param> /// <param name="offsetY"></param> /// <param name="larghezza"></param> /// <param name="altezza"></param> /// <param name="larghPassata"></param> /// <param name="diaFresaEffettivo">Diametro Effettivo Fresa</param> /// <param name="diaFresaIngombro">Diametro Ingombro Fressa</param> /// <param name="sovraMetallo"></param> /// <param name="profPassata"></param> /// <param name="zFinale"></param> /// <param name="zSicurezza">Z Sicurezza</param> /// <param name="extraCorsaSicurezza"></param> /// <param name="ottimizzaPassate">Con true calcolo nuova larghezza di passata minima</param> /// <param name="passataMinimaPercentuale">Passata Minima Percentuale</param> private static void SpiralFaceMillingV2(MoveActionCollection programPhase, double offsetX, double offsetY, double larghezza, double altezza, double larghPassata, double diaFresaEffettivo, double diaFresaIngombro, double sovraMetallo, double profPassata, double zFinale, double zSicurezza, double extraCorsaSicurezza, bool ottimizzaPassate, double passataMinimaPercentuale) { /* * todo : considerare anche raggio inserto-- */ /* * é meglio se avanzamenti li registro qui.. */ if (CheckValueHelper.GreatherOrEqualZero(new[] { sovraMetallo, extraCorsaSicurezza }) || CheckValueHelper.GreatherThanZero(new[] { larghezza, altezza, larghPassata, diaFresaEffettivo, profPassata, diaFresaIngombro }) || CheckValueHelper.GreatherThan(new[] { new KeyValuePair <double, double>(zSicurezza, zFinale + sovraMetallo), new KeyValuePair <double, double>(diaFresaEffettivo, larghPassata), }) ) { return; } /* * Per creare spianatura divido l'area di lavoro in griglia a quadrati con lato == larghezzaPassata */ var larghezzaPassataX = larghPassata; var larghezzaPassataY = larghPassata; var nColonneTeoriche = larghezza / larghPassata; var nRigheTeoriche = altezza / larghPassata; var nColonne = (int)Math.Floor(nColonneTeoriche); var nRighe = (int)Math.Floor(nRigheTeoriche); /* * devo per forza cambiare larghPassata, mantenendo il valore compreso fra un min e max. * * una volta che ho questo valore , proseguo per il mio ciclo come solito.. * */ if (ottimizzaPassate) { var passataMin = (larghPassata * passataMinimaPercentuale) / 100; var restoX = larghezza % larghezzaPassataX; var restoY = altezza % larghezzaPassataY; if (restoX < passataMin) { // modifico larghezza passata X larghezzaPassataX = larghezza / nColonne; nColonne--; } if (restoY < passataMin) { // modifico larghezza passata Y larghezzaPassataY = altezza / nRighe; // dimuisco numero di righe, nRighe--; } } /* * Raggio della fresa, sara il raggio che usero durante gli angoli nella spianatura */ var raggioEffettivoFresa = diaFresaEffettivo / 2; /* * todo: gestire anche diversi direzioni lavorazione e quindi punti entrata */ var sx = offsetX - larghezza / 2; var dx = offsetX + larghezza / 2; var down = offsetY - altezza / 2; var up = offsetY + altezza / 2; /* * in pratica per trovare punto arrivo moltiplico la larghezza di Passata per le celle delle griglia rimaste.. */ var zCurrent = zFinale + sovraMetallo; // Itero per tutte le passate in Z while (zCurrent > zFinale) { zCurrent -= profPassata; if (zCurrent < zFinale) { zCurrent = zFinale; } // rimuovere var minElement = (int)Math.Min(nColonne, nRighe); /* * 1.1 ) Punto attacco XY * * Il punto di inizio in alto a dx , tiene presente dell'ingombro massimo fresa e diametro effettivo di lavorazione + extraCorsaSicurezza */ var raggioIngombro = diaFresaIngombro / 2; var puntoInizio = new Point2D { X = sx + (nColonne) * larghezzaPassataX, Y = up + raggioIngombro + extraCorsaSicurezza }; programPhase.AddLinearMove(MoveType.Rapid, AxisAbilited.Xy, puntoInizio.X, puntoInizio.Y, null); programPhase.AddLinearMove(MoveType.Rapid, AxisAbilited.Z, null, null, zSicurezza); // 1.2 ) Andare a z Corrent programPhase.AddLinearMove(MoveType.SecureRapidFeed, AxisAbilited.Z, null, null, zCurrent); // 1.3 ) Punto avvicinamento diametro effettivo fresa var puntoAvvi = new Point2D { X = puntoInizio.X, Y = up + raggioEffettivoFresa }; programPhase.AddLinearMove(MoveType.PlungeFeed, AxisAbilited.Xy, puntoAvvi.X, puntoAvvi.Y, null); // 1.4) Interpolazione per fare entrata var puntoFinaleArcoEntrata = new Point2D { X = sx + (nColonne * larghezzaPassataX) + raggioEffettivoFresa, Y = up, }; programPhase.AddArcMove(AxisAbilited.Xy, puntoFinaleArcoEntrata.X, puntoFinaleArcoEntrata.Y, null, raggioEffettivoFresa, true, new Point2D(puntoAvvi.X, up)); /* * Ora magari vorrei cercare di cambiare ciclo in qualcosa di più chiaro e gestibile.. * * qui a posso usare metodi aux.. * * poso */ // 1.5) Lavorazione fino a termine materiale var continueCycle = true; var moveEnum = SpiralMoveEnum.ToDown; var startMove = moveEnum; var tempX = puntoFinaleArcoEntrata.X; var tempY = puntoFinaleArcoEntrata.Y; // cambiare se cambia senso direzione // counterCelleY++; var tempConterColonne = nColonne; var tempCounterRighe = nRighe; while (continueCycle) { continueCycle = SpiralMovementV2(programPhase, ref moveEnum, ref tempX, ref tempY, up, down, sx, dx, larghezzaPassataX, larghezzaPassataY, ref tempConterColonne, ref tempCounterRighe, nRighe, nColonne, minElement, raggioEffettivoFresa); // anche questo va cambiato se si decide di fare scegliere punto attacco //if (moveEnum == SpiralMoveEnum.ToDown) //{ // tempConterColonne--; // tempCounterRighe--; //} } // 1.6) Porto fresa a Z Sicurezza programPhase.AddLinearMove(MoveType.Rapid, AxisAbilited.Z, null, null, zSicurezza); } }
private static bool SpiralMovementV2(MoveActionCollection programPhase, ref SpiralMoveEnum moveEnum, ref double tempX, ref double tempY, double up, double down, double sx, double dx, double larghPassataX, double larghezzaPassataY, ref int counterX, ref int counterY, int nRighe, int nColonne, int minCounter, double raggioFresa) { switch (moveEnum) { /* * teoria v2: * * dopo che ho fatto la divisione in celle ( come solito ) * ho lo scarto nella parte dx e down , * * considero di partire da alto a dx * mi serve convenzione.. * * per convenzione punto finale è punto "teorico" ovvero punto arrivo se non ci fosse raggio. * * in modo che òa coordinata che non cambia si apposto per il prossimo movimento */ case SpiralMoveEnum.ToDown: { var nextY = up - (counterY * larghezzaPassataY) - raggioFresa; var delta = tempY - nextY; var yFinale = tempY; var xFinale = tempX; if (Math.Abs(delta) < raggioFresa * 2) { programPhase.AddLinearMove(MoveType.Work, AxisAbilited.Xy, xFinale, yFinale - raggioFresa, null); return(false); } yFinale = tempY = nextY; var startArc = new Point2D { X = xFinale, Y = yFinale + raggioFresa }; var endArc = new Point2D { X = xFinale - raggioFresa, Y = yFinale }; var center = new Point2D { X = endArc.X, Y = startArc.Y }; programPhase.AddLinearMove(MoveType.Work, AxisAbilited.Xy, startArc.X, startArc.Y, null); programPhase.AddArcMove(AxisAbilited.Xy, endArc.X, endArc.Y, null, raggioFresa, true, center); moveEnum = SpiralMoveEnum.ToLeft; counterX--; } break; case SpiralMoveEnum.ToLeft: { var passi = nColonne - counterX; var nextX = sx + (passi * larghPassataX) - raggioFresa; var delta = tempX - nextX; var yFinale = tempY; var xFinale = tempX; if (Math.Abs(delta) < raggioFresa * 2) { programPhase.AddLinearMove(MoveType.Work, AxisAbilited.Xy, xFinale - raggioFresa, yFinale, null); return(false); } xFinale = tempX = nextX; var startArc = new Point2D { X = xFinale + raggioFresa, Y = yFinale }; var endArc = new Point2D { X = xFinale, Y = yFinale + raggioFresa }; var center = new Point2D { X = startArc.X, Y = endArc.Y }; programPhase.AddLinearMove(MoveType.Work, AxisAbilited.Xy, startArc.X, startArc.Y, null); programPhase.AddArcMove(AxisAbilited.Xy, endArc.X, endArc.Y, null, raggioFresa, true, center); moveEnum = SpiralMoveEnum.ToUp; counterY--; } break; case SpiralMoveEnum.ToUp: { var passi = nRighe - counterY; var nextY = up - (passi * larghezzaPassataY) + raggioFresa; var delta = tempY - nextY; var yFinale = tempY; var xFinale = tempX; if (Math.Abs(delta) < raggioFresa * 2) { programPhase.AddLinearMove(MoveType.Work, AxisAbilited.Xy, xFinale, yFinale + raggioFresa, null); return(false); } yFinale = tempY = nextY; var startArc = new Point2D { X = xFinale, Y = yFinale - raggioFresa }; var endArc = new Point2D { X = xFinale + raggioFresa, Y = yFinale }; var center = new Point2D { X = endArc.X, Y = startArc.Y }; /* * devo controllare che la distanza che devo coprire sia maggiore del raggio fresa */ programPhase.AddLinearMove(MoveType.Work, AxisAbilited.Xy, startArc.X, startArc.Y, null); programPhase.AddArcMove(AxisAbilited.Xy, endArc.X, endArc.Y, null, raggioFresa, true, center); moveEnum = SpiralMoveEnum.ToRight; // counterX--; } break; case SpiralMoveEnum.ToRight: { var nextX = sx + (counterX * larghPassataX) + raggioFresa; var delta = tempX - nextX; var xFinale = tempX; var yFinale = tempY; if (Math.Abs(delta) < raggioFresa * 2) { programPhase.AddLinearMove(MoveType.Work, AxisAbilited.Xy, xFinale + raggioFresa, yFinale, null); return(false); } xFinale = tempX = nextX; var startArc = new Point2D { X = xFinale - raggioFresa, Y = yFinale }; var endArc = new Point2D { X = xFinale, Y = yFinale - raggioFresa }; var center = new Point2D { X = startArc.X, Y = endArc.Y }; programPhase.AddLinearMove(MoveType.Work, AxisAbilited.Xy, startArc.X, startArc.Y, null); programPhase.AddArcMove(AxisAbilited.Xy, endArc.X, endArc.Y, null, raggioFresa, true, center); moveEnum = SpiralMoveEnum.ToDown; } break; default: throw new NotImplementedException(); } /* * in pratica deve restituirmi linea dritta e movimento angolare */ return(true); }
//internal override ProgramPhase GetOperationProgram(Operazione operazione) //{ // var program = new ProgramPhase(SicurezzaZ); // var toolChange = new ChangeToolAction(program, operazione); // program.ActiveAsseC(true); // var fresa = operazione.Utensile as FresaCandela; // var parametro = operazione.Utensile.ParametroUtensile as ParametroFresaCandela; // if (fresa == null || parametro == null) // throw new NullReferenceException(); // var diaFresa = fresa.DiametroFresa; // var larghezzaPassata = parametro.GetLarghezzaPassata(); // var profPassata = parametro.GetProfonditaPassata(); // var feed = parametro.GetFeed(FeedType.ASync); // var plungeFeed = parametro.AvanzamentoAsincronoPiantata.Value.Value; // var secureFeed = 1; // var extraCorsa = 1; // var moveCollection = new MoveActionCollection(); // if (feed <= 0) // return null; // var feedDictionary = new Dictionary<MoveType, double> // { // {MoveType.Rapid, 10000}, // {MoveType.SecureRapidFeed, secureFeed}, // {MoveType.Work, feed}, // {MoveType.Cw, feed}, // {MoveType.Ccw, feed}, // {MoveType.PlungeFeed, plungeFeed} // }; // program.SetFeedDictionary(feedDictionary); // switch ((LavorazioniEnumOperazioni)operazione.OperationType) // { // default: // { // EngravingText(moveCollection, GetTextProfiles(), ProfonditaLavorazione, SicurezzaZ, InizioLavorazioneZ); // } break; // } // var mm = base.GetFinalProgram(moveCollection); // foreach (var variable in mm) // { // program.AddMoveAction(variable); // } // program.ActiveAsseC(false); // return program; //} private static void EngravingText(MoveActionCollection moveCollection, IEnumerable <Profile2D> profiles, double ProfonditaLavorazione, double SicurezzaZ, double InizioLavorazioneZ) { if (CheckValueHelper.GreatherThan(new[] { new KeyValuePair <double, double>(SicurezzaZ, InizioLavorazioneZ - ProfonditaLavorazione), }) ) { return; } if (profiles == null || profiles.Count() == 0) { return; } var zLavoro = InizioLavorazioneZ - ProfonditaLavorazione; var firstElement = profiles.First().Source.FirstOrDefault(); if (firstElement == null) { return; } var attacPoint = firstElement.GetFirstPnt(); if (attacPoint == null) { return; } moveCollection.AddLinearMove(MoveType.Rapid, AxisAbilited.Xy, attacPoint.X, attacPoint.Y, null); foreach (var profile2D in profiles) { var element = profile2D.Source; var p = Geometry.Entity.Profile2D.ParseArcIn2DProfile(profile2D); var source = p.Source; // arc parsingg moveCollection.AddLinearMove(MoveType.Rapid, AxisAbilited.Z, null, null, SicurezzaZ); if (source[0] is Line2D) { var firstMove = ((Line2D)source[0]).Start; moveCollection.AddLinearMove(MoveType.Rapid, AxisAbilited.Xy, firstMove.X, firstMove.Y, null); moveCollection.AddLinearMove(MoveType.PlungeFeed, AxisAbilited.Z, null, null, zLavoro); } foreach (var entity2D in source) { if (entity2D is Line2D) { var line = entity2D as Line2D; moveCollection.AddLinearMove(MoveType.Work, AxisAbilited.Xy, line.End.X, line.End.Y, null); } else if (entity2D is Arc2D) { // implementare archi var arc = entity2D as Arc2D; moveCollection.AddLinearMove(MoveType.Work, AxisAbilited.Xy, arc.Start.X, arc.Start.Y, null); moveCollection.AddArcMove(AxisAbilited.Xy, arc.End.X, arc.End.Y, null, arc.Radius, arc.ClockWise, arc.Center); } } moveCollection.AddLinearMove(MoveType.Rapid, AxisAbilited.Z, null, null, SicurezzaZ); } }