Ejemplo n.º 1
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            // Set up solution variables
            List <Kernal.Instruction> instructions = new List <Kernal.Instruction>();
            DateTime now     = DateTime.Now;
            Robot    c_Robot = null;

            // Load Inputs
            if (!DA.GetData(0, ref c_Robot))
            {
                return;
            }
            if (!DA.GetDataList("Instructions", instructions))
            {
                return;
            }

            if (!run | newData)
            {
                //Set Up Tool path
                toolpath     = new Toolpath(instructions, c_Robot);
                this.Message = (toolpath.IsValid) ? "No Errors detected" : "Errors";
                strat        = DateTime.Now;

                if (!toolpath.IsValid)
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Invalid Toolpath");
                    return;
                }

                c_Pose  = toolpath.StartPose;
                newData = false;
            }

            // Out put a full error log
            if (toolpath != null && fullprogramCheck.Checked && !run)
            {
                if (!DA.SetDataList("Full Error Log", toolpath.ErrorLog))
                {
                    return;
                }
                if (!DA.SetDataList("Error Positions", toolpath.ErrorPositions))
                {
                    return;
                }
            }

            if (toolpath != null && run)
            {
                if (c_Pose == null)
                {
                    c_Pose = toolpath.GetPose(DateTime.Now - TimeSpan.FromSeconds(0.1) - strat);
                }

                var pose = toolpath.GetPose(DateTime.Now - strat);

                if (!pose.IsValid)
                {
                    c_Pose.Colors = pose.Colors;
                }
                else
                {
                    c_Pose = pose;
                }

                if ((DateTime.Now - strat - TimeSpan.FromSeconds(1)) > toolpath.duration)
                {
                    run = false;
                    ExpireSolution(true);
                }
            }
            else if (timelineOption.Checked && !run)
            {
                double tValue = 0;
                if (!DA.GetData("*Timeline", ref tValue))
                {
                    return;
                }
                c_Pose = toolpath.GetPose(tValue);
            }
            // DA.SetData("Target", targets[0]);

            if (c_Pose != null)
            {
                // Handle errors
                void SetLogMessages(Robot.Pose Poses, List <string> Log)
                {
                    if (Poses.OverHeadSig)
                    {
                        Log.Add("Close to overhead singularity.");
                    }
                    if (Poses.WristSing)
                    {
                        Log.Add("Close to wrist singularity.");
                    }
                    if (Poses.OutOfReach)
                    {
                        Log.Add("Target out of range.");
                    }
                    if (Poses.OutOfRoation)
                    {
                        Log.Add("Joint out of range.");
                    }
                }

                List <string> log = new List <string>();
                SetLogMessages(c_Pose, log);

                // Set output
                if (flangeCheck.Checked)
                {
                    DA.SetData("Flange", c_Pose.Flange);
                }
                if (anglesCheck.Checked)
                {
                    DA.SetDataList("Angles", c_Pose.Angles);
                }
                if (speedCheck.Checked)
                {
                    DA.SetData("Speed", c_Pose.Speed.TranslationSpeed);
                }
                if (motionCheck.Checked)
                {
                    DA.SetData("Motion", c_Pose.Target.Method.ToString());
                }
                if (externalCheck.Checked)
                {
                    DA.SetData("External", (double)c_Pose.Target.ExtRot);
                }
                //if (showExternal) DA.SetData("External", (double)c_Pose.Target.ExtLin);

                DA.SetDataList("Log", log);

                // Update and display data
                c_Pose.GetBoundingBox(Transform.Identity);

                if (run)
                {
                    ExpireSolution(true);
                }
            }
        }
Ejemplo n.º 2
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            Plane m_baseplane = Plane.WorldXY;

            DA.GetData("Baseplane", ref m_baseplane);

            Plane m_workplane = Plane.WorldXY;

            DA.GetData("Workplane", ref m_workplane);

            Point3d m_point = Point3d.Origin;

            DA.GetData("Point", ref m_point);

            MachineTool m_machine_tool = null;

            DA.GetData("MachineTool", ref m_machine_tool);

            Toolpath m_toolpath = null;

            DA.GetData("Toolpath", ref m_toolpath);

            Mesh m_stock = null;

            DA.GetData("Stock mesh", ref m_stock);

            bool m_reset = false;

            DA.GetData("Reset", ref m_reset);

            Toolpath tpViz = null; int tpVizN = 0;

            if (m_toolpath != null)
            {
                tpViz = m_toolpath.Duplicate();
            }

            // Transform the workpiece and TCP to the G54 work offset
            Transform G54_xform = Transform.PlaneToPlane(Plane.WorldXY, m_workplane);

            m_stock.Transform(G54_xform);

            m_point.Transform(G54_xform);

            if (tpViz != null)
            {
                tpVizN = XFORM(tpViz, G54_xform);
            }

            // Machine coordinates
            var coords = new double[] {
                m_point.X,
                m_point.Y,
                m_point.Z + m_machine_tool.Length
            };

            /*
             * bool is_good;
             * for (int i = 0; i < 3; ++i)
             *  if (!m_limits[i].IncludesParameter(coords[i]))
             *  {
             *      is_good = false;
             *  }
             * is_good = true;
             */

            if (!IsInMachineLimits(coords))
            {
                this.Message = "Out of bounds!";
            }
            else
            {
                this.Message = "";
            }

            if (m_reset)
            {
                m_machine_meshes = new List <Mesh>();
                DA.GetDataList("Machine meshes", m_machine_meshes);

                // Hard-code machine part transformations (could also just move the meshes in place)
                machine_part_xforms[0] = Transform.Translation(new Vector3d(0, 0, -506));
                machine_part_xforms[1] = Transform.Translation(new Vector3d(-508, -254, -506));
                machine_part_xforms[2] = Transform.Translation(new Vector3d(-508, -254, -506));
                machine_part_xforms[3] = Transform.Translation(new Vector3d(0, 0, -101.6));
                machine_part_xforms[4] = Transform.Translation(new Vector3d(0, 0, 0));
            }

            // Hard-code meshes
            meshes[0] =                                      // chassis
                        m_machine_meshes[0].DuplicateMesh();
            meshes[2] =                                      // bed (moves in XY)
                        m_machine_meshes[1].DuplicateMesh();
            meshes[3] =                                      // tower
                        m_machine_meshes[2].DuplicateMesh();
            meshes[4] =                                      //new Mesh();
                        m_machine_meshes[3].DuplicateMesh(); // tool
            meshes[4].Append(
                Mesh.CreateFromCylinder(new Cylinder(new Circle(
                                                         new Plane(
                                                             new Point3d(0, 0, 0),
                                                             -Vector3d.XAxis, Vector3d.YAxis),
                                                         m_machine_tool.Diameter / 2), m_machine_tool.Length), 4, 24));


            // Pre-move all the machine parts in place
            for (int i = 0; i < machine_part_xforms.Length; ++i)
            {
                if (meshes[i] == null)
                {
                    continue;
                }
                meshes[i].Transform(machine_part_xforms[i]);
            }

            // Global transform
            xforms[0] = Transform.PlaneToPlane(Plane.WorldXY, m_baseplane);

            // Convert point to transforms
            xforms[1] = Transform.Translation(new Vector3d(-m_point.X, 0, 0));
            xforms[2] = Transform.Translation(new Vector3d(0, -m_point.Y, 0));
            xforms[3] = Transform.Translation(new Vector3d(0, 0, m_point.Z + m_machine_tool.Length));

            // Transform machine parts
            for (int i = meshes.Length - 1; i >= 0; --i)
            {
                if (meshes[i] == null)
                {
                    continue;
                }
                for (int j = 0; j < axis_relations[i].Length; ++j)
                {
                    meshes[i].Transform(xforms[axis_relations[i][j]]);
                }
            }

            // Transform workpiece
            Transform total = G54_xform;

            for (int i = wp_relations.Length - 1; i >= 0; --i)
            {
                m_stock.Transform(xforms[wp_relations[i]]);
                m_workplane.Transform(xforms[wp_relations[i]]);
                if (tpViz != null)
                {
                    tpVizN = XFORM(tpViz, xforms[wp_relations[i]]);
                }
                total = Transform.Multiply(total, xforms[wp_relations[i]]);
            }

            DA.SetData("Path", new Polyline(tpViz.Paths.SelectMany(x => x.Select(y => y.Plane.Origin))));
            DA.SetData("Toolpath", new GH_Toolpath(tpViz));
            DA.SetData("Work offset", m_workplane);

            DA.SetData("Stock mesh", m_stock);
            DA.SetDataList("Machine meshes", meshes);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            List <object> iToolpaths = new List <object>();
            object        iTool = null;
            Plane         iSafe = Plane.WorldXY;
            double        iRapidZ = 20, iSafeZ = 10;
            bool          iVR       = true;
            string        name      = "Toolpath";
            bool          flipWrist = false;

            DA.GetData("Name", ref name);
            DA.GetDataList("Toolpaths", iToolpaths);
            DA.GetData("Machine Tool", ref iTool);
            DA.GetData("Safety", ref iSafe);
            DA.GetData("RapidZ", ref iRapidZ);
            DA.GetData("SafeZ", ref iSafeZ);
            DA.GetData("VertRetract", ref iVR);
            DA.GetData("FlipWrist", ref flipWrist);

            this.Message = flipWrist.ToString();

            Toolpath tp = new Toolpath();

            tp.Name      = name;
            tp.FlipWrist = flipWrist;

            // Cast tool
            MachineTool mt;

            if (iTool is GH_MachineTool)
            {
                mt = (iTool as GH_MachineTool).Value;
            }
            else
            {
                mt = iTool as MachineTool;
            }
            if (mt == null)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Machine tool could not be cast.");
                return;
            }

            tp.Tool = mt;

            for (int i = 0; i < iToolpaths.Count; ++i)
            {
                Path poly;
                if (iToolpaths[i] is Path)
                {
                    poly = iToolpaths[i] as Path;
                }
                else if (iToolpaths[i] is GH_tasPath)
                {
                    poly = (iToolpaths[i] as GH_tasPath).Value;
                }
                else
                {
                    this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Error in Path wrangling.");
                    continue;
                }

                tp.Paths.Add(poly.Select(x => new Waypoint(x, (int)WaypointType.FEED)).ToList());
            }

            tp.PlaneRetractVertical = iVR;
            tp.RapidZ = iRapidZ;
            tp.SafeZ  = iSafeZ;
            tp.Safety = iSafe;

            DA.SetData("Toolpath", new GH_Toolpath(tp));
        }
Ejemplo n.º 4
0
        public override object Compute()
        {
            if (Paths.Count < 1)
            {
                this.Errors.Add("No paths to process...");
                return(null);
            }

            //List<string> Tools = new List<string>();
            for (int i = 0; i < Paths.Count; ++i)
            {
                if (!Tools.ContainsKey(Paths[i].Tool.Name))
                {
                    this.Errors.Add($"Tool '{Paths[i].Tool.Name}' not found in post-processor tool library.");
                    continue;
                }
            }

            Axes    = new List <AxisValues>();
            Program = new List <string>();
            Errors  = new List <string>();

            //bool HighSpeed = true;

            // Create headers
            Program.Add("%");
            Program.Add("O0001");

            BoundingBox = BoundingBox.Empty;

            if (StockModel != null)
            {
                BoundingBox = StockModel.GetBoundingBox(true);
            }

            CreateHeader();

            Program.Add("");

            Program.Add($"{PreComment} * * * * * WORK PLANE * * * * * {PostComment}");
            Program.Add($"G{GWorkOffset} X{WorkOffset.X} Y{WorkOffset.Y} Z{WorkOffset.Z}");

            /* Old CMS defaults and settings */

            /*
             * Program.Add($"{PreComment} * * * * * VARIABLES * * * * * {PostComment}");
             * Program.Add($"#560 = {GWorkOffset}    {PreComment}ZERO POINT{PostComment}");
             * Program.Add($"#561 = {WorkOffset.X}    {PreComment}OFFSET PROGRAM I X{PostComment}");
             * Program.Add($"#562 = {WorkOffset.Y}    {PreComment}OFFSET PROGRAM I Y{PostComment}");
             * Program.Add($"#563 = {WorkOffset.Z}    {PreComment}OFFSET PROGRAM I Z{PostComment}");
             *
             * Program.Add($"#564 = {MaterialThickness}    {PreComment}EMNE TYKKELSE{PostComment}");
             * Program.Add($"#565 = {SikkerZ}    {PreComment}SIKKER Z)");
             * Program.Add($"#566 = {SikkerZPlanskifte}    {PreComment}SIKKER Z VED PLANSKIFTE{PostComment}");
             * Program.Add($"#563 = #563 + #564");
             * Program.Add($"#569 = {60}");
             *
             * Program.Add("");
             */

            Program.Add("");

            Program.Add($"{PreComment} * * * * * START * * * * * {PostComment}");

            // Init gcode
            Program.Add("G90 G40 G80 G49 G69");

            // Reset offsets to 0
            Program.Add("G92.1 X0 Y0 Z0 B0 C0");

            // CMS pressure clamping closing (unnecessary)
            //Program.Add("M25");

            // Set to mm (G20 is inches)
            Program.Add("G21");

            // Go home. G0 = rapid, G53 = move in absolute coords
            Program.Add("G0 G53 Z0");
            Program.Add("G0 B0 C0");
            //Program.Add("G#560");

            // Set work offset
            //Program.Add("G#560 X#561 Y#562 Z#563");
            Program.Add($"G{GWorkOffset}");


            // Working variables
            int  G_VALUE        = -1;
            int  flags          = 0;
            bool write_feedrate = true;

            // Initialize coordinates
            double[] coords = new double[DOF];
            for (int i = 0; i < DOF; ++i)
            {
                coords[i] = double.MaxValue;
            }

            double[] pCoords = new double[DOF];
            for (int i = 0; i < DOF; ++i)
            {
                pCoords[i] = double.MaxValue;
            }

            int currentFeedrate = 0;
            int tempFeedrate    = int.MaxValue;

            int prevTool = -1;

            for (int i = 0; i < Paths.Count; ++i)
            {
                bool flip = false;
                if (i < m_flipList.Count)
                {
                    flip = m_flipList[i];
                }
                Toolpath TP = Paths[i];

                // Add toolpath info
                // TODO: Add support for tool indexing to the whole thing
                Program.Add("");
                Program.Add("");
                Program.Add($"{PreComment} * * * * * PATH {i:D2} * * * * * {PostComment}");

                Program.Add($"{PreComment} Operation : {TP.Name} {PostComment}");
                Program.Add($"{PreComment} Tool no.  : {Tools[TP.Tool.Name].Number} {PostComment}");
                Program.Add($"{PreComment} Tool des. : {Tools[TP.Tool.Name].Name} {PostComment}");
                Program.Add($"{PreComment} Tool dia. : {Tools[TP.Tool.Name].Diameter} {PostComment}");

                // Tool change
                Program.Add($"M6 T{Tools[TP.Tool.Name].Number}");

                if (TP.Tool.Number != prevTool)
                {
                    // Start spindle
                    Program.Add($"M3 S{Tools[TP.Tool.Name].SpindleSpeed}");
                }
                prevTool = TP.Tool.Number;
                // Not sure what this does...

                /*
                 * Program.Add("#567 = #2255+135.0");
                 * Program.Add("#568 = 0 + SQRT[#567*#567+625]+#566-135");
                 * Program.Add("G#560");
                 *
                 */
                Program.Add("");
                //Program.Add("G0 G53 Z0 B-90");

                if (HighSpeed)
                {
                    Program.Add("G5.1 Q1");
                }

                Program.Add($"G43.4 H{Tools[TP.Tool.Name].OffsetNumber}");


                // If toolpath is planar, lock B and C axes
                if (TP.IsPlanar)
                {
                    Program.Add($"M32 M34");
                }

                // Move to first waypoint
                //Waypoint prev = TP.Paths[0][0];
                //if (prev.Type != (int)WaypointType.RAPID)
                //    throw new Exception("First waypoint must be rapid. Check code.");

                Waypoint prev = new Waypoint(TP.Paths[0][0]);
                prev.Type = (int)WaypointType.RAPID;

                // Calculate B and C values
                //PlaneToCoords(prev.Plane, ref pCoords);
                //if (flip)
                //    FlipWrist(ref pCoords);

                PlaneToCoords(prev.Plane, ref pCoords);

                if (TP.FlipWrist)
                {
                    FlipWrist(ref pCoords);
                }

                // Vector3d axisFirst = prev.Plane.ZAxis;
                //axisFirst.Unitize();

                //prevB = Rhino.RhinoMath.ToDegrees(Math.Acos(axisFirst * Vector3d.ZAxis));
                //prevC = Rhino.RhinoMath.ToDegrees(Math.Atan2(axisFirst.Y, axisFirst.X));

                //Program.Add($"G{(int)prev.Type} X{prev.Plane.Origin.X:F3} Y{prev.Plane.Origin.Y:F3}  Z{prev.Plane.Origin.Z:F3} B{prevB:F3} C{prevC:F3}");
                //Program.Add($"G0 X{prev.Plane.Origin.X:F3} Y{prev.Plane.Origin.Y:F3} B{prevB:F3} C{prevC:F3} Z#568");
                Program.Add($"G0 X{pCoords[0]:F3} Y{pCoords[1]:F3}");
                Program.Add($"G0 B{pCoords[3]:F3} C{pCoords[4]:F3}");
                Program.Add($"G0 Z{pCoords[2]:F3}");

                double diff;
                // Go through waypoints

                for (int j = 0; j < TP.Paths.Count; ++j)
                {
                    // Parse sub-paths
                    WPath Subpath = TP.Paths[j];
                    for (int k = 0; k < Subpath.Count; ++k)
                    {
                        write_feedrate = false;
                        flags          = 0;

                        Waypoint wp = Subpath[k];

                        PlaneToCoords(wp.Plane, ref coords);
                        //if (flip)
                        //    FlipWrist(ref coords);
                        if (TP.FlipWrist)
                        {
                            FlipWrist(ref coords);
                        }

                        // Deal with abrupt 180 to -180 switches
                        diff = coords[4] - pCoords[4];
                        if (diff > 270)
                        {
                            coords[4] -= 360.0;
                        }
                        if (diff < -270)
                        {
                            coords[4] += 360.0;
                        }

                        // Check limits
                        //if (!IsInMachineLimits(coords))
                        //    Errors.Add($"Waypoint outside of machine limits: toolpath {i} subpath {j} waypoint {k} : {wp}, {coords[3]}, {coords[4]}");

                        if (!this.CheckAbsoluteLimits(wp.Plane, TP.Tool))
                        {
                            var temp_pt = GetMachinePosition(wp.Plane, TP.Tool);
                            Errors.Add($"Target {k} in toolpath {j} ({TP.Name}) out of bounds: {temp_pt.X:0.00} {temp_pt.Y:0.00} {temp_pt.Z:0.00}");
                        }

                        // Compose line
                        List <string> Line = new List <string>();

                        #region Parse movement (G code)
                        if (wp.Type != prev.Type || AlwaysWriteGCode)
                        {
                            flags = flags | 1;

                            if (wp.IsRapid())
                            {
                                G_VALUE        = 0;
                                write_feedrate = false;
                                tempFeedrate   = int.MaxValue;
                            }
                            else if (wp.IsArc())
                            {
                                write_feedrate = true;
                                if (wp.IsClockwise())
                                {
                                    G_VALUE = 3;
                                }
                                else
                                {
                                    G_VALUE = 2;
                                }
                            }
                            else
                            {
                                G_VALUE        = 1;
                                write_feedrate = true;
                            }
                        }
                        #endregion

                        #region Parse movement on axes
                        for (int l = 0; l < m_dof; ++l)
                        {
                            if (Math.Abs(coords[l] - pCoords[l]) > 0.001)
                            {
                                flags = flags | (1 << (l + 1));
                            }
                        }
                        #endregion

                        #region Write feedrate if different
                        // If Plunge move, set current feedrate to PlungeRate
                        if (write_feedrate)
                        {
                            if (wp.IsPlunge())
                            {
                                tempFeedrate = Tools[TP.Tool.Name].PlungeRate;
                            }
                            else
                            {
                                tempFeedrate = Tools[TP.Tool.Name].FeedRate;
                            }

                            // If new feedrate is different from old one, write F value
                            write_feedrate = tempFeedrate != currentFeedrate ? true : false;
                        }

                        currentFeedrate = tempFeedrate;
                        #endregion

                        // If it is an arc move, then write I J K values
                        if (wp.IsArc())
                        {
                            flags = flags | (1 << (m_dof + 1));
                        }

                        if (write_feedrate)
                        {
                            flags = flags | (1 << (m_dof + 2));
                        }

                        // If there is no motion, skip this waypoint
                        if ((flags & m_NO_MOTION) < 1)
                        {
                            continue;
                        }

                        Axes.Add(new AxisValues(coords[0], coords[1], coords[2], coords[3], coords[4], currentFeedrate));

                        #region Construct NC code

                        if ((flags & 1) > 0)
                        {
                            Line.Add($"G{G_VALUE:00}");
                        }

                        for (int l = 0; l < m_dof; ++l)
                        {
                            if ((flags & (1 << (1 + l))) > 0)
                            {
                                Line.Add($"{m_axis_id[l]}{coords[l]:F3}");
                            }
                        }

                        if ((flags & (1 << (m_dof + 1))) > 0)
                        {
                            Line.Add($"R{wp.Radius:F3}");
                        }

                        if ((flags & (1 << (m_dof + 2))) > 0)
                        {
                            Line.Add($"F{currentFeedrate}");
                        }

                        #endregion

                        // Add line to program
                        Program.Add(string.Join(" ", Line) + ";");
                        prev = wp;
                        Array.Copy(coords, pCoords, coords.Length);
                    }
                }

                Program.Add("");

                // Stop spindle
                //Program.Add("M5");

                // TODO: Find out what these G codes do
                //Program.Add("G49 G53 G69");
                Program.Add("G49");
                Program.Add("G69");

                if (HighSpeed)
                {
                    Program.Add("G5.1 Q0");
                }

                // TODO: Add another home position here?

                // If toolpath is planar, unlock B and C axes
                if (TP.IsPlanar)
                {
                    Program.Add($"M31 M33");
                }

                //Program.Add("G0 G53 Z0");
                //Program.Add("G0 G53 B-90");


                Program.Add("");
            }

            // Return home
            // TODO: Look at example, find out if G53 is global coords
            // and add if necessary
            //Program.Add("G53");
            Program.Add("G0 G53 Z0");
            Program.Add("M5");

            //if (prevB >= 0)
            //    Program.Add("G0 G53 B90");
            //else if (prevB < 0)
            //    Program.Add("G0 G53 B-90");

            // This is the funny dance
            //Program.Add("G0 G53 B-90");
            //Program.Add("G0 G53 C0");

            Program.Add("G0 G53 B0 C0");
            Program.Add("G92.1 X0 Y0 Z0 B0 C0");


            Program.Add("G0 G53 Y0");
            Program.Add("G0 G53 X0");
            //Program.Add("G0 G53 X-2500");
            //Program.Add("G0 G53 B0");
            //Program.Add("G0 G53 X-2600");

            Program.Add($"{PreComment} * * * * *  END  * * * * * {PostComment}");

            //Program.Add("M7"); // This should be to return the tool, but check
            //Program.Add("");
            Program.Add("M99");
            Program.Add("%");

            return(Program);
        }
Ejemplo n.º 5
0
        public override object Compute()
        {
            if (Paths.Count < 1)
            {
                this.Errors.Add("No paths to process...");
                return(null);
            }

            for (int i = 0; i < Paths.Count; ++i)
            {
                if (!Tools.ContainsKey(Paths[i].Tool.Name))
                {
                    this.Errors.Add(string.Format("Tool '{0}' not found in post-processor tool library.", Paths[i].Tool.Name));
                    continue;
                }
            }

            Program = new List <string>();
            Errors  = new List <string>();
            MachineTool ActiveTool;

            BoundingBox = BoundingBox.Empty;

            if (StockModel != null)
            {
                BoundingBox = StockModel.GetBoundingBox(true);
            }

            // Working variables
            int  G_VALUE        = -1;
            int  flags          = 0;
            bool write_feedrate = true;

            // Initialize coordinates
            double[] coords = new double[DOF];
            for (int i = 0; i < DOF; ++i)
            {
                coords[i] = double.MaxValue;
            }

            double[] pCoords = new double[DOF];
            for (int i = 0; i < DOF; ++i)
            {
                pCoords[i] = double.MaxValue;
            }

            int currentFeedrate = 0;
            int tempFeedrate    = int.MaxValue;

            EOL = " ";

            Program.Add("%");
            //Program.Add($"O01001 ({Name})"); // Program number / name

            CreateHeader();

            //Program.Add("G00 G17 G40 G49 G80 G90 G98;"); // Safety line
            //Program.Add("G00 G53 Z0;"); // Return to machine zero
            Program.Add("G90"); // Return to machine zero
            Program.Add("G64"); // Return to machine zero
            Program.Add("M7");  // Return to machine zero
            Program.Add("M8");  // Return to machine zero

            // Loop through Toolpaths
            for (int i = 0; i < Paths.Count; ++i)
            {
                Toolpath TP = Paths[i];
                ActiveTool = Tools[TP.Tool.Name];

                Program.Add($"{PreComment}----------------------------------------------------------------{PostComment}{EOL}");
                Program.Add($"{PreComment} START Toolpath: {TP.Name} {PostComment}{EOL}");
                Program.Add($"{PreComment}       Tool: {ActiveTool.Name} Diameter: {ActiveTool.Diameter} {PostComment}{EOL}");
                Program.Add($"{PreComment}----------------------------------------------------------------{PostComment}{EOL}");

                // Tool change
                // TODO: Change so that it only changes the tool if necessary, though the machine should ignore this anyway
                Program.Add($"T{Tools[TP.Tool.Name].Number}{EOL}");

                // Move to first waypoint
                Waypoint prev = new Waypoint(TP.Paths[0][0]);
                prev.Type = (int)WaypointType.RAPID;


                Program.Add($"S{TP.Tool.SpindleSpeed}");
                Program.Add("M3");

                //Program.Add($"G00 G90 G21 G54 X{prev.Plane.Origin.X:F3} Y{prev.Plane.Origin.Y:F3} S{TP.Tool.SpindleSpeed} M03{EOL}");
                //Program.Add($"G43 H{Tools[TP.Tool.Name].OffsetNumber:00} M08{EOL}");



                // Loop through subpaths
                for (int j = 0; j < TP.Paths.Count; ++j)
                {
                    WPath Subpath = TP.Paths[j];

                    // Loop through individual waypoints
                    for (int k = 0; k < Subpath.Count; ++k)
                    {
                        // Reset working variables
                        write_feedrate = false;
                        flags          = 0;

                        Waypoint wp = Subpath[k];

                        // Convert waypoint targets to axis coordinates
                        PlaneToCoords(wp.Plane, ref coords);
                        PlaneToCoords(prev.Plane, ref pCoords);

                        // Check limits
                        if (!IsInMachineLimits(coords))
                        {
                            Errors.Add($"Waypoint outside of machine limits: toolpath {i} subpath {j} waypoint {k} : {wp}");
                        }

                        // Compose NC line
                        List <string> Line = new List <string>();


                        #region Parse movement (G code)
                        if (wp.Type != prev.Type || AlwaysWriteGCode || true)
                        {
                            flags = flags | 1;

                            if (wp.IsRapid())
                            {
                                G_VALUE        = 0;
                                write_feedrate = false;
                            }
                            else if (wp.IsArc())
                            {
                                write_feedrate = true;
                                if (wp.IsClockwise())
                                {
                                    G_VALUE = 3;
                                }
                                else
                                {
                                    G_VALUE = 2;
                                }
                            }
                            else
                            {
                                G_VALUE = 1;
                                if (prev.Type == (int)WaypointType.RAPID)
                                {
                                    write_feedrate = true;
                                }
                            }
                        }
                        #endregion

                        #region Write feedrate if different
                        // If Plunge move, set current feedrate to PlungeRate
                        if (wp.IsPlunge())
                        {
                            tempFeedrate = Tools[TP.Tool.Name].PlungeRate;
                        }
                        else
                        {
                            tempFeedrate = Tools[TP.Tool.Name].FeedRate;
                        }

                        // If new feedrate is different from old one, write F value
                        if (tempFeedrate != currentFeedrate)
                        {
                            write_feedrate = true;
                        }

                        currentFeedrate = tempFeedrate;
                        #endregion

                        #region Parse movement on axes
                        for (int l = 0; l < m_dof; ++l)
                        {
                            if (Math.Abs(coords[l] - pCoords[l]) > 0.00001)
                            {
                                flags = flags | (1 << (l + 1));
                            }
                        }
                        #endregion



                        // If it is an arc move, then write I J K values
                        if (wp.IsArc())
                        {
                            flags = flags | (1 << m_dof + 1);
                        }


                        if (write_feedrate)
                        {
                            flags = flags | (1 << m_dof + 2);
                        }

                        // If there is no motion, skip this waypoint
                        if ((flags & m_NO_MOTION) < 1)
                        {
                            continue;
                        }

                        #region Construct NC code

                        if ((flags & 1) > 0)
                        {
                            Line.Add($"G{G_VALUE:0}");
                        }

                        for (int l = 0; l < m_dof; ++l)
                        {
                            //if ((flags & (1 << 1 + l)) > 0)
                            Line.Add($"{m_axis_id[l]}{coords[l]:F3}");
                        }

                        if ((flags & (1 << m_dof + 1)) > 0)
                        {
                            Line.Add($"R{wp.Radius:F3}");
                        }

                        if ((flags & (1 << m_dof + 2)) > 0)
                        {
                            Line.Add($"F{currentFeedrate}");
                        }

                        #endregion

                        // Add line to program
                        Program.Add(string.Join(" ", Line) + EOL);

                        // Update previous waypoint
                        prev = new Waypoint(wp);
                    }
                }


                //Program.Add($"{PreComment}{PostComment}{EOL}");
                //Program.Add($"G53 G49 G0 Z0.{EOL}");
                //Program.Add("G53 X0. Y0.");

                //Program.Add("G0 Z12");

                Program.Add($"{PreComment} ---- END Toolpath: {TP.Name} ---- {PostComment}{EOL}");
            }
            //Program.Add($"G00 Z10.");

            Program.Add($"{PreComment} End of program {PostComment}{EOL}");
            Program.Add($"M9");
            Program.Add($"M5{EOL}"); // Spindle stop
            Program.Add($"M30{EOL}");
            //Program.Add("%");
            return(Program);
        }
Ejemplo n.º 6
0
        public override object Compute()
        {
            if (Paths.Count < 1)
            {
                this.Errors.Add("No paths to process...");
                return(null);
            }

            for (int i = 0; i < Paths.Count; ++i)
            {
                if (!Tools.ContainsKey(Paths[i].Tool.Name))
                {
                    this.Errors.Add(string.Format("Tool '{0}' not found in post-processor tool library.", Paths[i].Tool.Name));
                    continue;
                }
            }

            List <string> Program = new List <string>();

            Errors = new List <string>();

            BoundingBox bbox = BoundingBox.Unset;

            if (StockModel != null)
            {
                bbox = StockModel.GetBoundingBox(true);
            }

            // Create headers
            Program.Add("O01001;"); // Program number / name

            Program.Add($"{PreComment}{PostComment};");
            Program.Add($"{PreComment} Revision      : 1 {PostComment};");
            Program.Add($"{PreComment}{PostComment}");
            Program.Add($"{PreComment} File name      : {Name} {PostComment};");
            Program.Add($"{PreComment} Programmed by  : {Author} {PostComment};");
            Program.Add($"{PreComment} Date           : {Date} {PostComment};");
            Program.Add($"{PreComment} Program length : {ProgramTime} {PostComment}");
            Program.Add($"{PreComment} Bounds min.    : {bbox.Min.X} {bbox.Min.Y} {bbox.Min.Z} {PostComment};");
            Program.Add($"{PreComment} Bounds max.    : {bbox.Max.X} {bbox.Max.Y} {bbox.Max.Z} {PostComment};");
            Program.Add($"{PreComment}{PostComment};");

            Program.Add($"{PreComment}Tool #    Offset #    Name    Diameter    Length {PostComment};");

            foreach (var d in Tools)
            {
                MachineTool mt = d.Value;
                Program.Add($"{PreComment} {mt.Number}    {mt.OffsetNumber}    {mt.Name}    {mt.Diameter:0.0}    {mt.Length:0.000} {PostComment};");
            }
            Program.Add($"{PreComment}{PostComment};");



            Program.Add("G0 Z12");

            // Working variables
            int  G_VALUE        = -1;
            int  flags          = 0;
            bool write_feedrate = true;

            // Initialize coordinates
            double[] coords = new double[DOF];
            for (int i = 0; i < DOF; ++i)
            {
                coords[i] = double.MaxValue;
            }

            double[] pCoords = new double[DOF];
            for (int i = 0; i < DOF; ++i)
            {
                pCoords[i] = double.MaxValue;
            }

            int currentFeedrate = 0;
            int tempFeedrate    = int.MaxValue;

            for (int i = 0; i < Paths.Count; ++i)
            {
                Toolpath TP = Paths[i];

                Program.Add("");

                // Tool change
                Program.Add($"M6 T{Tools[TP.Tool.Name].Number}");

                // Move to first waypoint
                Waypoint prev = new Waypoint(TP.Paths[0][0]);
                prev.Type = (int)WaypointType.RAPID;

                //if (prev.Type != (int)WaypointType.RAPID)
                //    throw new Exception("First waypoint must be rapid. Check code.");

                Program.Add($"G0 X{prev.Plane.Origin.X:F3} Y{prev.Plane.Origin.Y:F3}");


                // Go through waypoints

                for (int j = 0; j < TP.Paths.Count; ++j)
                {
                    // Parse sub-paths
                    WPath Subpath = TP.Paths[j];
                    for (int k = 0; k < Subpath.Count; ++k)
                    {
                        write_feedrate = false;
                        flags          = 0;

                        Waypoint wp = Subpath[k];

                        PlaneToCoords(wp.Plane, ref coords);

                        // Check limits
                        if (!IsInMachineLimits(coords))
                        {
                            Errors.Add($"Waypoint outside of machine limits: toolpath {i} subpath {j} waypoint {k} : {wp}");
                        }

                        // Compose line
                        List <string> Line = new List <string>();

                        if (wp.Type != prev.Type || AlwaysWriteGCode)
                        {
                            flags = flags | 1;
                            if ((wp.Type & 1) == 1)
                            {
                                G_VALUE = 0;
                            }
                            else if ((wp.Type & 4) == 1)
                            {
                                if ((wp.Type & 12) == 1)
                                {
                                    G_VALUE = 3;
                                }
                                else
                                {
                                    G_VALUE = 2;
                                }
                            }
                            else
                            {
                                G_VALUE        = 1;
                                write_feedrate = true;
                            }
                        }

                        #region Parse movement on axes
                        for (int l = 0; l < m_dof; ++l)
                        {
                            if (Math.Abs(coords[l] - pCoords[l]) > 0.00001)
                            {
                                flags = flags | (1 << (l + 1));
                            }
                        }
                        #endregion

                        // If Plunge move, set current feedrate to PlungeRate
                        if (wp.IsPlunge())
                        {
                            tempFeedrate = Tools[TP.Tool.Name].PlungeRate;
                        }
                        else
                        {
                            tempFeedrate = Tools[TP.Tool.Name].FeedRate;
                        }

                        // If new feedrate is different from old one, write F value
                        if (tempFeedrate == currentFeedrate)
                        {
                            write_feedrate = false;
                        }

                        currentFeedrate = tempFeedrate;


                        // If it is an arc move, then write R value
                        if (wp.IsArc())
                        {
                            flags = flags | (1 << 4);
                        }

                        if (write_feedrate)
                        {
                            flags = flags | (1 << 5);
                        }


                        // If there is no motion, skip this waypoint
                        if ((flags & m_NO_MOTION) < 1)
                        {
                            continue;
                        }


                        #region Construct NC code

                        if ((flags & 1) > 0)
                        {
                            Line.Add($"G{G_VALUE:00}");
                        }

                        for (int l = 0; l < m_dof; ++l)
                        {
                            if ((flags & (1 << 1 + l)) > 0)
                            {
                                Line.Add($"{m_axis_id[l]}{coords[l]:F3}");
                            }
                        }

                        if ((flags & (1 << m_dof + 1)) > 0)
                        {
                            Line.Add($"R{wp.Radius:F3}");
                        }

                        if ((flags & (1 << m_dof + 2)) > 0)
                        {
                            Line.Add($"F{currentFeedrate}");
                        }

                        #endregion

                        // Add line to program
                        Program.Add(string.Join(" ", Line));

                        // Update previous waypoint
                        prev = new Waypoint(wp);
                    }
                }


                Program.Add("");


                Program.Add("G0 Z12");

                Program.Add("");
            }

            Program.Add("G0 Z0");
            Program.Add("G0 X0 Y0");

            Program.Add("M30");

            return(Program);
        }
Ejemplo n.º 7
0
        public void BuildSimulation(List <Toolpath> toolpaths)
        {
            m_wp    = new List <Waypoint>();
            m_times = new List <double>();
            m_feeds = new List <double>();

            m_toolpaths      = new List <Toolpath>();
            m_toolpath_times = new List <double>();

            Waypoint cTarget, cPrev;

            cTime = 0;

            cPrev = toolpaths.First().Paths.First().First();
            //m_times.Add(0);

            int feed_index = 0;

            for (int i = 0; i < toolpaths.Count; ++i)
            {
                Toolpath tp = toolpaths[i];

                m_toolpaths.Add(tp);
                m_toolpath_times.Add(cTime);

                for (int j = 0; j < tp.Paths.Count; ++j)
                {
                    for (int k = 0; k < tp.Paths[j].Count; ++k)
                    {
                        cTarget = tp.Paths[j][k];

                        m_wp.Add(cTarget);
                        if (cTarget.IsFeed())
                        {
                            m_feeds.Add(tp.Tool.FeedRate);
                        }
                        else if (cTarget.IsPlunge())
                        {
                            m_feeds.Add(tp.Tool.PlungeRate);
                        }
                        else if (cTarget.IsRapid())
                        {
                            m_feeds.Add(tp.Tool.FeedRate * 2);
                        }
                        else
                        {
                            throw new Exception("F**k!");
                        }

                        cTime += cTarget.Plane.Origin.DistanceTo(cPrev.Plane.Origin) / m_feeds[feed_index];
                        feed_index++;

                        m_times.Add(cTime);
                        cPrev = cTarget;
                    }
                }
            }

            foreach (double d in m_toolpath_times)
            {
            }

            if (m_wp.Count < 1)
            {
                throw new Exception("No waypoints found!");
            }
        }
Ejemplo n.º 8
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            DA.GetData("Calculate", ref this._calc);
            if (!this._calc)
            {
                DA.SetDataList("Targets", this._targets);
                DA.SetData("Path", this._path);
                //DA.SetDataList("Planes", this._planes);
                DA.SetData("debug", this._debug);
                return;
            }
            this._debug   = "";
            this._path    = null;
            this._targets = null;
            this._planes  = null;
            Plane frame_t = new Plane();

            this._toolpaths = new List <Polyline>();
            // collect inputs
            DA.GetData("Workplane", ref this._workplane);
            DA.GetData("External axes", ref this._extern);
            DA.GetData("Configuration", ref this._config);

            if (!DA.GetData("Frame", ref frame_t))
            {
                _frame = Frame.Default;
            }
            //_frame = new Frame(Plane.WorldXY, "tasFrame");
            else
            {
                _frame = new Frame(frame_t, -1, -1, "tasFrame");
            }

            Robots.Grasshopper.GH_Tool toolGH = null;
            DA.GetData("Tool", ref toolGH);
            this._tool = toolGH?.Value;

            this._debug += toolGH.ToString() + "\n";
            this._debug += toolGH.GetType().ToString() + "\n";

            if (this._tool == null)
            {
                this._debug += "Tool conversion failed...\n";
            }
            else
            {
                this._debug += this._tool.ToString() + "\n";
                this._debug += this._tool.GetType().ToString() + "\n";
            }

            // gather and convert, if necessary, input curves
            List <Curve> in_crvs = new List <Curve>();

            if (!DA.GetDataList("Toolpaths", in_crvs))
            {
                return;
            }
            this._toolpaths = tasUtility.CurvesToPolylines(in_crvs, 1.0);

            this._is_drive_surface = DA.GetData("DriveSurface", ref this._drive_surface);

            DA.GetData("Safe Z", ref this._safe_z);
            DA.GetData("Rapid Z", ref this._rapid_z);
            DA.GetData("Feed rate", ref this._feedrate);
            DA.GetData("Rapid rate", ref this._rapidrate);
            DA.GetData("Ramp height", ref this._ramp_height);
            DA.GetData("Tool twist", ref this._tooltwist);
            // /collect inputs

            // set up speeds
            Speed sp_feed  = new Speed(this._feedrate, Math.PI, "feed");
            Speed sp_rapid = new Speed(this._rapidrate, Math.PI, "rapid");

            // rotate workplane to account for tool twist
            Transform rot = Transform.Rotation(this._tooltwist, _workplane.ZAxis, _workplane.Origin);

            _workplane.Transform(rot);

            // init toolpath
            Toolpath prog = new Toolpath();

            prog.External2 = this._extern;
            prog.External1 = this._extern;

            prog.Configuration = (Target.RobotConfigurations) this._config;
            prog.DefFrame      = _frame;

            if (this._tool != null)
            {
                prog.DefTool = this._tool;
            }
            else
            {
                this._debug += "Tool conversion failed again...\n";
            }
            prog.DefSpeed  = sp_rapid;
            prog.DefMotion = Target.Motions.Linear;

            if (this._is_drive_surface)
            {
                prog.InputSurface = this._drive_surface;
            }
            prog.Orientation = Toolpath.ToolOrientation.SurfaceNormal;
            prog.Workplane   = this._workplane;

            for (int i = 0; i < this._toolpaths.Count; ++i)
            {
                if (this._toolpaths[i] == null)
                {
                    continue;
                }

                // lead in
                Polyline ramp = (Polyline)Util.CreateRamp(this._toolpaths[i], this._workplane, this._ramp_height, this._ramp_height * 5);
                Point3d  p    = Util.ProjectToPlane(ramp[0], prog.Workplane);
                prog.CreateTarget(p + prog.Workplane.ZAxis * (this._safe_z + this._rapid_z));
                prog.CreateTarget(p + prog.Workplane.ZAxis * (this._safe_z));

                // machining speed
                prog.DefSpeed  = sp_feed;
                prog.DefMotion = Target.Motions.Linear;

                for (int j = 0; j < ramp.Count; ++j)
                {
                    prog.CreateTarget(ramp[j], Toolpath.ToolOrientation.ZAxis);
                }

                /*
                 * Point3d p = tasUtility.ProjectToPlane(this._toolpaths[i][0], prog.Workplane);
                 * Vector3d d2p = new Vector3d(p - this._toolpaths[i][0]);
                 * Vector3d ramp = new Vector3d(tasUtility.ProjectToPlane(this._toolpaths[i][1], prog.Workplane) - p);
                 * if (ramp.Length < this._ramp_height)
                 *  ramp = new Vector3d(tasUtility.ProjectToPlane(this._toolpaths[i][this._toolpaths[i].Count - 2], prog.Workplane) - p);
                 * ramp.Unitize();
                 * p += ramp * this._ramp_height;
                 * p += prog.Workplane.ZAxis * (this._safe_z + this._rapid_z);
                 * prog.CreateTarget(p, Toolpath.ToolOrientation.ZAxis);
                 * p -= prog.Workplane.ZAxis * this._rapid_z;
                 * p -= d2p;
                 * prog.CreateTarget(p, Toolpath.ToolOrientation.ZAxis);
                 */


                // make toolpath targets
                for (int j = 0; j < this._toolpaths[i].Count; ++j)
                {
                    prog.CreateTarget(this._toolpaths[i][j]);
                }

                // lead out
                Point3d p2 = Util.ProjectToPlane(this._toolpaths[i][this._toolpaths[i].Count - 1], prog.Workplane);
                p2           += prog.Workplane.ZAxis * this._safe_z;
                prog.DefSpeed = sp_rapid;
                prog.CreateTarget(p2, Toolpath.ToolOrientation.ZAxis);
                p2 += prog.Workplane.ZAxis * this._rapid_z;
                //prog.DefSpeed = spr;
                prog.CreateTarget(p2, Toolpath.ToolOrientation.ZAxis);
            }

            // yield toolpath
            this._targets = prog.Targets;
            this._path    = prog.Path();
            this._planes  = prog.Planes;


            DA.SetDataList("Targets", this._targets);
            DA.SetData("Path", this._path);
            //DA.SetDataList("Planes", this._planes);
            DA.SetData("debug", this._debug);
        }