The task was to prove that we could develop a system with which a designer of fiber optic amplifiers could assemble and wire icons from a palette to represent a novel design and have that design automatically converted to two text tables: one presenting the interconnections and the parameters of each component and the second showing the initial energy at each connection at each wavelength of interest. Icons, palettes, and wiring were all native to LabVIEW, so that was our development tool of choice. In only twenty-three hours of work we built a prototype and used it to build the following demonstration model.You may find it easier to follow the text descriptions if you pop-up this image and Figure 3 in new windows with the links provided.
Let's start with a quick overview of the hierarchy of this prototype, shown in Figure 2, and then get into the details.
The top item, with the generic icon, is simply a container for the project. It makes it easy to keep all the pieces together and, for instance, to form a library file for moving the project to another computer or even another platform with the "Save Development Distribution" option. The second row contains the sample design (on the left) and a data viewer (on the right). The data viewer converts the component data from its stored form to a human readable form using the component-specific subVIs in the next row. The third row contains the optical components themselves, the five on the left intended for building design diagrams. The fourth row contains an "Intelligent" or "LabVIEW 2-style" Global that captures the connection matrix. The three icons in the lower left that include the LabVIEW control symbol are "Type Def."s that maintain consistency among the various VIs if any of the common data structures are redefined. The remaining icon in the fifth row is another Intelligent Global that captures the power spectrum at each connection point.
Recall that the GUI is supposed to deliver two data structures to the simulation kernel: a connection matrix and a map of the initial optical power at each connection point. We have dedicated an intelligent global to each of these structures.
The connection matrix is supposed to show all the components on the diagram, all the connections between them, and all the parameters of each component. Figure 3 shows the front panel of Connection Matrix.vi after running the Figure 1 example .
The array labelled "connections" presents the required data.
Near the center of the array is a column listing three line sources (the light bulbs in Figure 1), three WDMs (the cross-coupled fibers (Xs)), and one filter (the S-shaped rainbow). The second row of the array contains a non-physical "backsplice" component, which incorporates the two "elbow macaroni" icons, that allows the GUI to handle closed loops (as discussed below).
The interconnections are represented in the first four columns. (At this stage in the project, we did not have the full specification of the format of the tabular data of the connection matrix shown in Figure 1 of the main page.) According to the client's specification, components can have up to two inputs and up to two outputs. The first two columns represent the inputs and the second two the outputs. Connections are assigned non-negative integer numbers. Since the first row has three "-1" entries, only one terminal, an output, of that component is connected to anything. That particular connection (numbered "0") is shared with the first input in the fifth row, so the output of the line source connects to the upper input of a WDM. Connection 0 is the blue line between icons in the upper left corner of the diagram. With some difficulty, you can verify that the array does capture the connections in Figure 1, including the "backsplice" connecting the output of the filter to the lower input of the WDM that shows 0.03 crosscoupling.
The final requirement on the connection matrix was that it capture all the parameters of each component. Since different types of component will have different combinations of parameters, I formed the parameters of each component type into a structure, flattened that structure to a string using the built-in LabVIEW primitive, and stored those strings in the matrix. The strings in Figure 3 (right column) are not very intelligible, hence the need for the Data Viewer. Figure 4 shows that the spectrum defined for the filter (left panel) is the spectrum captured (right panel).
(The astute LabVIEWer will notice that Example.vi has finished running but Display Filter.vi is currently running as a subVI [to Viewer.vi] and perhaps also that Example.vi has warnings, contrary to the design philosophy of . These warnings state that some recommended terminals are not connected (as you can readily verify in Figure 1) and are exactly those that the ground and termination icons on the final palette were included to suppress.)
Figure 5 shows the standard operation of Connection Matrix.vi.
The description of the current component and its connections (the cluster labeled "connection" near the top of Figure 3) is fed into the VI, with no connection or a -1 at the device instance input. The size of the connections array is sent back to the component as its ID number and then the new description is appended to the array.
Edge Data.vi (Figure 6) works in a similar way to allow both new edges and new wavelengths to be added to the structure it reports, fulfilling the second part of the data contract.
Normal components have internal wiring similar to Figure 7, for the WDM. (Pardon the red "4.x". These images were captured with LabVIEW 5.1 without updating the VIs from version 4.1.)
The component asks for new connection numbers for its outputs and posts them to any component to which it is connected. It reads the numbers of the connections at its inputs, flattens its parameters to a string, and posts all this information to the Connection Matrix. Data flow considerations will not allow a component to do anything until its inputs are satisfied. Optical Sources have no inputs, so they can run early, supply their outputs to other components (e.g., the upper left WDM in Figure 1), which can then supply other components. Connections ripple through the diagram.
Except for loops!
In Figure 1, the upper right WDM supplies a signal to the filter but also gets a signal from the filter. Neither can run until the other does.
To get around this problem, I included two non-physical components, the ones with icons like elbow macaroni. Functionally, they are a single component, which I called a backsplice (Boy Scout ropes course is showing).
The left pseudo-component has no inputs, so it can run anytime and satisfy one terminal of the WDM. As shown in Figure 8, it passes its device instance number to the other pseudo-component, which requests the earlier connection record rather than a new one from the Connection Matrix global, and completes it with the missing information that wasn't available when the left pseudo-component ran. The pair of pseudo-components allows the data flow constraints to handle loops just fine.
Note that the only reason for flattening the device instance to a string is to distinguish that connection by color from the real connections in the design.