/// <summary>
        /// Convert the list of components in to a list of reels
        /// </summary>
        /// <param name="componentList">Components to distribute over the reels</param>
        /// <returns>List of reels with the components</returns>
        private static List <Reel> ComponentsToReels(List <PnpComponent> componentList, int speed)
        {
            List <Reel> tempReelList = new List <Reel>();
            List <Reel> result       = new List <Reel>();

            while (componentList.Count != 0)
            {
                PnpComponent        curComponent       = componentList[0];
                List <PnpComponent> matchingComponents = componentList.FindAll(comp_ => (comp_.Comment == curComponent.Comment) && (comp_.ManufacturerPartNumber == curComponent.ManufacturerPartNumber));
                //Find all components of the same type (footprint and comment/value are the same)
                componentList.RemoveAll(comp => matchingComponents.Contains(comp));
                Reel newReel = new Reel(matchingComponents, speed); //make a reel from the components
                tempReelList.Add(newReel);
            }
            while (tempReelList.Count != 0)
            {
                string manufacturerPartNumber = tempReelList[0].Components[0].ManufacturerPartNumber;
                //Find all matching footprints
                List <Reel> similarReels = tempReelList.FindAll(reel => reel.Components[0].ManufacturerPartNumber == manufacturerPartNumber); //make a list of all reels who share the footprint
                tempReelList.RemoveAll(reel => similarReels.Contains(reel));
                Footprint reelFootprint = DatabaseOperations.GetFootprint(manufacturerPartNumber);
                if (reelFootprint != null)
                {
                    foreach (Reel reel in similarReels)
                    {
                        reel.Footprint = reelFootprint;
                    }
                }
                result.AddRange(similarReels);
            }
            return(result);
        }
        /// <summary>
        /// Returns a string to save the PNPcomponents of the reels in the reelList
        /// </summary>
        /// <param name="reelList">List of all reels with the components to save</param>
        /// <param name="included">Is the reel scheduled to be placed in the stacks</param>
        /// <returns>String that represents the components in the savefile</returns>
        private static string SaveStringComponents(List <Reel> reelList, bool included)
        {
            StringBuilder sbResult = new StringBuilder();

            //TO DO: make foreach
            for (int reelIndex = 0; reelIndex < reelList.Count; reelIndex++)
            {
                List <PnpComponent> componentList = reelList[reelIndex].Components;
                for (int componentIndex = 0; componentIndex < componentList.Count; componentIndex++)
                {
                    PnpComponent component = componentList[componentIndex];
                    sbResult.AppendFormat("Designator={0},manufacturer part number={1},X={2},Y={3},Rotation={4},Layer={5},comment={6},include={7}{8}",
                                          new object[] { component.Designator, component.ManufacturerPartNumber,
                                                         component.Location.X, component.Location.Y, component.Location.Rotation, component.Location.Layer,
                                                         component.Comment, included, Environment.NewLine });
                }
            }
            return(sbResult.ToString());
        }
        /// <summary>
        /// Load a pick and place project from the project.path
        /// </summary>
        /// <param name="project">Project to load data to</param>
        /// <exception cref="PickAndPlace.FileOperationsException">Thrown when data is missing or when a line could not be decoded</exception>
        public static void LoadProject(PnpProject project)
        {
            List <PnpComponent> includedComponents = new List <PnpComponent>();
            List <PnpComponent> excludedComponents = new List <PnpComponent>();

            //project.stackListers = new List<StackList>();
            using (StreamReader reader = new StreamReader(project.Path))
            {
                while (!reader.EndOfStream)
                {
                    string curLine = reader.ReadLine();
                    //# is a line with comment
                    if (curLine.StartsWith("#") || String.IsNullOrWhiteSpace(curLine))
                    {
                        continue;
                    }
                    string[] splitedLine = curLine.Split(new char[] { ',', '=' }, StringSplitOptions.None);
                    switch (splitedLine[0])
                    {
                    case "ProjectName":
                        project.ProjectName = splitedLine[1];
                        break;

                    case "ProjectFolder":
                        project.ProjectFolder = splitedLine[1];
                        break;

                    case "MachineType":
                        project.Machine = (IMachine)Assembly.GetExecutingAssembly().CreateInstance(splitedLine[1]);
                        project.Machine.DefaultSpeed = Convert.ToInt32(splitedLine[3]);
                        for (int i = 5; i < splitedLine.Length; i++)
                        {
                            Nozzle nozzle = PNPconverterTools.StringToNozzle(splitedLine[i]);
                            project.Machine.SetNozzle(i - 5, nozzle);
                        }
                        break;

                    case "originOffsetX":
                        project.HorizontalOriginOffset = float.Parse(splitedLine[1]);
                        project.VerticalOriginOffset   = float.Parse(splitedLine[3]);
                        break;

                    case "boardsX":
                        project.BoardsX = Convert.ToInt32(splitedLine[1]);
                        project.BoardsY = Convert.ToInt32(splitedLine[3]);
                        break;

                    case "distanceX":
                        project.DistanceX = float.Parse(splitedLine[1]);
                        project.DistanceY = float.Parse(splitedLine[3]);
                        break;

                    case "boardDimX":
                        project.BoardWidth  = float.Parse(splitedLine[1]);
                        project.BoardLength = float.Parse(splitedLine[3]);
                        break;

                    case "Designator":
                        //load new component
                        string designator = splitedLine[1];
                        string manufacturerPartNumber_ = splitedLine[3];
                        float  x        = float.Parse(splitedLine[5]);
                        float  y        = float.Parse(splitedLine[7]);
                        int    rotation = Convert.ToInt32(splitedLine[9]);
                        Layer  layer_;
                        if (splitedLine[11] == Layer.Bottom.ToString())
                        {
                            layer_ = Layer.Bottom;
                        }
                        else
                        {
                            layer_ = Layer.Top;
                        }
                        Location     location_ = new Location(x, y, rotation, layer_);
                        string       comment   = splitedLine[13];
                        bool         included  = Convert.ToBoolean(splitedLine[15]);
                        PnpComponent comp      = new PnpComponent(designator, location_, comment, manufacturerPartNumber_);
                        if (included)
                        {
                            includedComponents.Add(comp);
                        }
                        else
                        {
                            excludedComponents.Add(comp);
                        }
                        break;

                    case "Phase":
                        //last part of the file
                        string   remainingLines        = reader.ReadToEnd();
                        string[] remainingLinesSplited = remainingLines.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
                        //1) make reels from the components:

                        project.IncludedReels = ComponentsToReels(includedComponents, project.Machine.DefaultSpeed);
                        project.ExcludedReels = ComponentsToReels(excludedComponents, project.Machine.DefaultSpeed);

                        List <Reel> completeReelList = new List <Reel>(project.IncludedReels);
                        completeReelList.AddRange(project.ExcludedReels);
                        //the completeReelList contains all reels, however these reels where not splited
                        List <Reel> topReels, bottomReels;
                        Reel.SplitReelList(completeReelList, out topReels, out bottomReels);
                        completeReelList.Clear();
                        completeReelList.AddRange(topReels);
                        completeReelList.AddRange(bottomReels);
                        //topReels and bottomReels contain all reels, also the excluded reels
                        //they will be reused later

                        //2) read each line
                        StackList newStackList = new StackList(project.Machine, Convert.ToInt32(splitedLine[1]));
                        newStackList.Name = "stackList";
                        project.StackListers.Add(newStackList);
                        int index = -1;

                        for (int i = 0; i < remainingLinesSplited.Length; i++)
                        {
                            splitedLine = remainingLinesSplited[i].Split(new char[] { '=', ',' });
                            if (splitedLine[0] != "Phase")
                            {
                                index++;     //Stacks are saved in order (starting at reel 0 -> reel n)
                                string designator_ = splitedLine[1];
                                if (String.IsNullOrWhiteSpace(designator_))
                                {
                                    continue;                                             //empty stack
                                }
                                bool locked = Convert.ToBoolean(splitedLine[5]);
                                //find the reel in the completeReelList
                                Reel matchingReel = completeReelList.Find(reel => reel.GetDesignators().Contains(designator_));
                                matchingReel.Speed = Convert.ToInt32(splitedLine[3]);
                                newStackList.AddReel(matchingReel, locked, index);
                                project.ReelsInStackList.Add(matchingReel);
                            }
                            else
                            {
                                //make a new phase
                                //Phase=X (X=phase number)
                                newStackList      = new StackList(project.Machine, Convert.ToInt32(splitedLine[1]));
                                newStackList.Name = "stackList";
                                project.StackListers.Add(newStackList);
                                index = -1;
                            }
                        }
                        //Reusing topReels and bottomReels
                        Reel.SplitReelList(project.ReelsInStackList, out topReels, out bottomReels);
                        project.TopReels    = topReels;
                        project.BottomReels = bottomReels;

                        break;

                    default:
                        throw new FileOperationsException(String.Format("Unable to read file: {0}{2}Problem with reading folowing line:{2}{1}", project.Path, curLine, Environment.NewLine));
                    }
                }
            }
            if (project.StackListers.Count == 0)
            {
                //no phases saved
                project.IncludedReels = ComponentsToReels(includedComponents, project.Machine.DefaultSpeed);
                project.ExcludedReels = ComponentsToReels(excludedComponents, project.Machine.DefaultSpeed);
            }
            if ((project.HorizontalOriginOffset == -1f) || (project.VerticalOriginOffset == -1f) ||
                (project.BoardsX == -1) || (project.BoardsY == -1) ||
                (project.DistanceX == -1f) || (project.DistanceY == -1f) ||
                (project.BoardWidth == -1f) || (project.BoardLength == -1f) ||
                (project.Machine == null))
            {
                throw new FileOperationsException("Not all data was found in the file");
            }
        }
        /// <summary>
        /// Reads both the pnpFile and the bom file and returns a list of reels based on the two files
        /// </summary>
        /// <param name="pnpFilePath">Path to the Pick and place file</param>
        /// <param name="pnpHeaders">Headers used to read the pnp file</param>
        /// <param name="bomFilePath">Path to the BOM file</param>
        /// <param name="bomHeaders">Headers used to read the BOM</param>
        /// <param name="defaultSpeed">Default speed of the reels</param>
        /// <returns>List of reels that was created based on the data in the files</returns>
        /// <exception cref="PickAndPlace.FileOperationsException">Thrown when some data cannot be processed </exception>
        /// <exception cref="PickAndPlace.HeaderNotFoundException">Thrown when one of the header parameters is not found</exception>
        /// <exception cref="PickAndPlace.PnpConversionException">Thrown when the pnp file uses an unknown length unit</exception>
        public static List <Reel> ReadPickAndPlaceFiles(string pnpFilePath, string[] pnpHeaders, string bomFilePath, string[] bomHeaders, int defaultSpeed)
        {
            List <Reel>         result     = new List <Reel>();
            List <PnpComponent> components = new List <PnpComponent>();

            using (StreamReader reader = new StreamReader(pnpFilePath, Encoding.Default))
            {
                //I had the best result with Encoding.Default and Encoding.UTF7 (µ character)
                string   line;
                string[] colNames;
                do
                {
                    line     = reader.ReadLine();
                    colNames = SplitLinePNPfile(line);
                } while (colNames.Length < pnpHeaders.Length);

                //find location of corresponding columns
                int colDesignator = IndexOfHeader(colNames, pnpHeaders[0]);
                int colX          = IndexOfHeader(colNames, pnpHeaders[1]);
                int colY          = IndexOfHeader(colNames, pnpHeaders[2]);
                int colLayer      = IndexOfHeader(colNames, pnpHeaders[3]);
                int colRotation   = IndexOfHeader(colNames, pnpHeaders[4]);
                int colComment    = IndexOfHeader(colNames, pnpHeaders[5]);
                //read the document
                while (!reader.EndOfStream)
                {
                    line = reader.ReadLine();
                    string[] parameters = SplitLinePNPfile(line);
                    //first line is empty (contains "", so string.empty doesn't work)
                    if (parameters.Length == colNames.Length)
                    {
                        float X, Y;
                        int   rotation;
                        Layer layer = Layer.Top;
                        X        = ConvertPnpValue(parameters[colX]);
                        Y        = ConvertPnpValue(parameters[colY]);
                        rotation = (int)Convert.ToDouble(parameters[colRotation]);
                        switch (parameters[colLayer])
                        {
                        case "B":
                        case "BottomLayer":
                            layer = Layer.Bottom;
                            break;

                        case "T":
                        case "TopLayer":
                            layer = Layer.Top;
                            break;

                        default:
                            throw new FileOperationsException("Folowing line contains an unknown layer:" + Environment.NewLine + line);
                        }
                        Location     loc  = new Location(X, Y, rotation, layer);
                        PnpComponent comp = new PnpComponent(parameters[colDesignator], loc, parameters[colComment]);
                        components.Add(comp);
                    }
                }
            }
            using (StreamReader xReader = new StreamReader(bomFilePath))
            {
                string   line           = xReader.ReadLine();
                string[] colNames       = line.Split(','); //unlike the pnp file, the header of the BOM has no " "," "
                int      colDesignators = IndexOfHeader(colNames, bomHeaders[0]);
                int      colMPN         = IndexOfHeader(colNames, bomHeaders[1]);
                int      checkCounter   = 0;
                while (!xReader.EndOfStream)
                {
                    line = xReader.ReadLine();
                    string[] parameters = SplitLinePNPfile(line);
                    if (parameters.Length == colNames.Length)
                    {
                        string[]            designators   = parameters[colDesignators].Split(new string[] { ", " }, StringSplitOptions.RemoveEmptyEntries);
                        List <PnpComponent> bomComponents = new List <PnpComponent>();
                        foreach (string designator in designators)
                        {
                            PnpComponent comp = components.Find(comp_ => comp_.Designator == designator);
                            if (comp == null)
                            {
                                throw new FileOperationsException("folowing designator was not found in the pick and place file: " + designator);
                            }

                            comp.ManufacturerPartNumber = parameters[colMPN];
                            bomComponents.Add(comp);
                            checkCounter++;
                        }
                        Reel reel = new Reel(bomComponents, defaultSpeed);
                        result.Add(reel);
                    }
                }
                if (checkCounter != components.Count)
                {
                    throw new FileOperationsException("The BOM contains more components then the Pick and Place file");
                }
            }
            return(result);
        }
Exemplo n.º 5
0
        public void ExportToFile(string path, BoardSettings boardSettings, StackList phaseStackList)
        {
            StringBuilder sbStackOffset        = new StringBuilder();
            StringBuilder sbFeederSpacing      = new StringBuilder();
            StringBuilder sbComponentLocations = new StringBuilder();
            int           operationNumber      = 1;
            int           curSpeed             = -1;

            for (int index = 0; index < this.totalAmountOfReels_; index++)
            {
                //values for when there is no reel
                float  offsetX         = 0;
                float  offsetY         = 0;
                string comment         = "";
                float  feedSpacingReel = 0;
                Reel   reelWithIntel   = phaseStackList.GetReel(index);
                if (reelWithIntel != null)
                {
                    Footprint reelsFootprint = reelWithIntel.Footprint; //this makes reading the code easier
                    if (reelWithIntel.Footprint.StackType != StackType.Tray18mm)
                    {
                        offsetX = reelsFootprint.OffsetStackX;
                        offsetY = reelsFootprint.OffsetStackY;
                    }
                    else
                    {
                        offsetX = -9.4f + reelsFootprint.Width / 2 + reelsFootprint.OffsetStackX;
                        offsetY = 8.5f - reelsFootprint.Length / 2 + reelsFootprint.OffsetStackY;
                    }
                    comment         = reelsFootprint.ManufacturerPartNumber;
                    feedSpacingReel = reelsFootprint.FeedRate;

                    int speedValue = reelWithIntel.Speed / 10;
                    //1) check if the speed changes
                    if (speedValue != curSpeed)
                    {
                        curSpeed = speedValue;
                        sbComponentLocations.AppendFormat("0,{0},0,0,0,0,0,0,{1}", speedValue, Environment.NewLine);
                    }
                    //set all components
                    for (int i = 0; i < reelWithIntel.Components.Count; i++)
                    {
                        PnpComponent comp = reelWithIntel.Components[i];
                        float        distance;
                        int          nozzleNumber = this.GetNozzleNumber(reelsFootprint.Nozzle);
                        //This should never give -1 and if it does, the machine wil give an error
                        int compRotation;
                        if (comp.Location.Layer == Layer.Top)
                        {
                            distance     = comp.Location.Y;
                            compRotation = ATmMachine.ConvertAngle(comp.Location.Rotation + reelsFootprint.Rotation);
                        }
                        else
                        {
                            //botom
                            distance     = boardSettings.BoardLength - comp.Location.Y;
                            compRotation = ATmMachine.ConvertAngle(180 - (comp.Location.Rotation + reelsFootprint.Rotation));
                        }
                        //%,Head,Stack,X,Y,R,H,skip,Ref,Comment,
                        sbComponentLocations.AppendFormat("{0},{1},{2},{3:0.###},{4:0.###},{5},{6:0.##},0,{7},{8}{9}",
                                                          new object[] { operationNumber, nozzleNumber, index, comp.Location.X, distance,
                                                                         compRotation, reelsFootprint.Height,
                                                                         comp.Designator, reelsFootprint.ManufacturerPartNumber, Environment.NewLine });
                        operationNumber++;
                    }
                }
                //%,StackOffsetCommand,Stack,X,Y,Comment
                sbStackOffset.AppendFormat("65535,1,{0},{1},{2},{3}{4}",
                                           new object[] { index, offsetX, offsetY, comment, Environment.NewLine });
                sbFeederSpacing.AppendFormat("65535,2,{0},{1},{2}", index, feedSpacingReel, Environment.NewLine);
            }
            using (StreamWriter writer = new StreamWriter(path))
            {
                //1) origin offset
                writer.WriteLine("%,OriginOffsetCommand,X,Y,,");
                writer.WriteLine("65535,0,{0:0.##},{1:0.##},", boardSettings.HorizontalOriginOffset, boardSettings.VerticalOriginOffset);
                writer.WriteLine();

                //2) stack offset
                writer.WriteLine("%,StackOffsetCommand,Stack,X,Y,Comment");
                writer.WriteLine(sbStackOffset.ToString());

                //3) Feeder spacing
                writer.WriteLine("%,FeederSpacingCommand,Stack,FeedSpacing,");
                writer.WriteLine(sbFeederSpacing.ToString());

                //4) Board setup
                writer.WriteLine("%,JointedBoardCommand,X,Y,");
                for (int i = 0; i < boardSettings.BoardsX; i++)
                {
                    for (int j = 0; j < boardSettings.BoardsY; j++)
                    {
                        if ((i != 0) || (j != 0))
                        {
                            //skip the first board
                            float Xcoord = i * (boardSettings.BoardWidth + boardSettings.DistanceX);
                            float Ycoord = j * (boardSettings.BoardLength + boardSettings.DistanceY);
                            writer.WriteLine("65535,3,{0:0.##},{1:0.##},", Xcoord, Ycoord);
                        }
                    }
                }
                writer.WriteLine();
                //5) Component locations
                writer.WriteLine("%,Head,Stack,X,Y,R,H,Skip,Ref,Comment,");
                writer.Write(sbComponentLocations.ToString());
            }
        }