IADS - Programming User Guide
IADS - Programming User Guide
User Guide
Jul 2020
Curtiss-Wright Document SSD-IADS-140
©2020 Curtiss-Wright
All rights reserved.
IADS Programming
User Guide
Table of Contents
1. Programming Resources ....................................................................... 4
1.1 Overview .................................................................................................. 4
2. Custom ActiveX Display Plugins .......................................................... 4
2.1 Creating an IADS custom ActiveX control using C# VS2015.................. 4
2.1.1 Adding properties to your new display using C# VS2015 ..................... 12
2.1.2 Debugging your new display in IADS using C# VS2015 ....................... 15
2.2 Creating an IADS custom ActiveX control using C++ VS2015 ............ 16
2.2.1 Adding properties to your new display using C++ VS2015 .................. 23
2.2.2 Debugging your new display in IADS using C++ VS2015 ................... 29
2.3 Adding your new display to IADS .......................................................... 32
2.4 IADS demo model control project.......................................................... 34
3. Custom Derived Functions .................................................................. 35
3.1 Creating a custom derived function using C# VS2015 .......................... 35
3.1.1 Debugging your new function in IADS .................................................. 43
3.2 Creating a custom derived function using C++ VS2015 ....................... 45
3.2.1 Debugging your new function in C++ VS2015 ..................................... 57
3.2.2 Deploying your new function in C++ VS2015 ...................................... 59
3.3 Accessing your new function in IADS .................................................... 61
3.4 Advanced Topics .................................................................................... 64
3.4.1 Initialization and execution of your custom function............................. 64
3.4.2 Returning multiple results from your custom function .......................... 67
4. Custom Plugins..................................................................................... 73
4.1 Creating a custom export plugin using C++ VS2015 ........................... 73
4.1.1 Adding IADS Interface files ................................................................... 83
4.1.2 Adding IDataExportPlugin code and your export code ........................ 88
4.1.3 Make your DLL self-register for use in IADS ........................................ 90
4.1.4 Debugging your new plugin in IADS ..................................................... 92
5. Application Programming Interfaces ................................................ 93
5.1 IADS Configuration File API................................................................. 93
5.1.1 Configuration Interface ......................................................................... 93
5.1.2 Collection Interfaces .............................................................................. 94
5.1.3 General Purpose Query Interface ........................................................ 103
5.2 IADS Data File API ............................................................................. 104
6. IADS Automation Interfaces ............................................................ 105
6.1 IADS Data Export Scripts .................................................................... 105
6.2 IADS Data File Reader in Visual Basic............................................... 105
7. IADS Data Processing........................................................................ 106
7.1 IADS Real Time Data Source Interface ............................................... 106
7.1.1 Data Source Specification.................................................................... 106
7.1.2 IADS Server Setup................................................................................ 109
7.1.3 Testing the data source using IADS Real Time Station ....................... 114
7.1.4 Troubleshooting ................................................................................... 124
7.2 IADS Command Interface .................................................................... 125
7.2.1 IADS Commander ................................................................................ 126
7.2.2 The CDS Command Server .................................................................. 136
7.2.3 Initialization Commands and Information ........................................... 139
7.2.4 Data Acquisition Commands and Information .................................... 143
7.2.5 Stopping Data Command and Information .......................................... 148
7.2.6 Time Information ................................................................................. 149
7.2.7 Archiving Commands and Information ................................................ 150
7.2.8 Nulling Commands and Information ................................................... 153
7.2.9 Data Compression Commands and Information ................................. 154
7.2.10 Run State Information .......................................................................... 157
7.2.11 Data Source Information ..................................................................... 158
7.2.12 System-wide Information ..................................................................... 159
7.2.13 Startup IADS Command Line Options ................................................. 162
7.3 IADS Server (CDS) Data Throughput Performance Testing............... 163
7.3.1 Overview .............................................................................................. 163
7.3.2 To run the data throughput test ........................................................... 163
8. Other ................................................................................................... 166
8.1 Iadsread Matlab Extension .................................................................. 166
8.2 Iadsread for Python ............................................................................. 169
APPENDIX A ...................................................................................................... 180
APPENDIX B ...................................................................................................... 182
APPENDIX C ...................................................................................................... 184
APPENDIX D...................................................................................................... 186
APPENDIX E ...................................................................................................... 187
1. Programming Resources
This guide details methods to programmatically extend IADS by using step by step
examples many of which have working projects with source code that are available for download
from the IADS Web site.
1.1 Overview
IADS provides programmatic extension to the core system using several
techniques. Within the IADS Client, plug-ins can be written using Microsoft COM technology,
including new displays, additions to the derived computational engine and custom data export
extensions. The IADS Client also extends an automation interface for easy scripting. For access
to external data and configuration files IADS provides a set of COM based libraries which can be
linked into your programs. Finally, for data processing, IADS includes a standard Ethernet
protocol for custom real time data interfaces and a command and control interface for real time
operation.
2) In the New Project dialog that appears, choose the Other Languages > Visual C# tier and
click the Class Library option. At this point, please read the next step before you finish
completing the dialog. There are some important considerations when choosing the proper
project name.
3) The project name you choose will become part of the display identifier name (also known as
the ProgID, see note below). When it comes time to use your control in IADS, users will
insert your new control into the “Display Builder” toolbox based solely upon its name (more
on this later). Plan on creating many displays in one “project” (most common and easier to
manage the code). Choose a general project name like “AircraftGauges” or
“FluidSystemDisplays”. One way to look at it is that the project name is akin to the “Genus”
of your display, so shoot for generality. Consider prefixing the project name with your
organization like “NASA” or “Lockheed”, as it may easier for users to locate your control the
“Display Builder” list (i.e. NasaFluidSystemDisplays or LockheedAircraftGauges).
Note: Microsoft refers to your display’s name as its “ProgID” (also known as the Program
ID). This is the string equivalent of your GUID (Global Unique Identifier) for the function.
These Ids are placed in the Microsoft registry (directly from your project’s “.rgs” file),
allowing your object to be created without any knowledge of the location of your “Dll” on
the file system. Of course, this assumes that it is registered using the “regsvr32” program
(consult the Microsoft documentation).
Now, in the fields at the bottom of the dialog, enter the project name, location, and the
solution name.
4) After pressing OK, the project will be ready for editing. Before we begin, delete the
Class1.cs file. We will not need the file.
5) Right-click on your project in the Solution Explorer and choose Add > New Item.
6) In the “Add New Item” dialog select User Control. Enter the name of your display in the
field and click the Add button.
7) Visual Studio now displays the “Design” view of the display and shows a blank form. You
can use the Visual Studio “Toolbox” to add a visual object. Drop a ProgressBar into the
form; it is located under the “Common Controls” tier in the Toolbox.
8) Now that we are done adding components, we will need to do some work in the code section.
Go to the Solution Explorer and right-click on your “displays.cs” file. Select View Code. In
your “displays.cs” file, add the following using clauses:
using System.Reflection;
using System.Runtime.InteropServices;
using Microsoft.Win32;
10) Add the following methods to perform the COM registration functions. COM is the interface
method that IADS will use to send/receive data, save, and load your display. The registration
mechanism is the manner in which IADS will identify your display after it is installed on a
PC. If you skip this step, you will not be able to see your display in the IADS Display
Builder dialog.
[ComRegisterFunctionAttribute]
public static void RegisterFunction(Type t)
{
Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(@"CLSID\{" +
t.GUID.ToString().ToUpper() + @"}Programmable");
Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(@"CLSID\{" +
t.GUID.ToString().ToUpper() + @"}\Control");
}
[ComUnregisterFunctionAttribute]
public static void UnregisterFunction(Type t)
{
Microsoft.Win32.Registry.ClassesRoot.DeleteSubKey(@"CLSID\{" +
t.GUID.ToString().ToUpper() + @"}Programmable");
Microsoft.Win32.Registry.ClassesRoot.DeleteSubKey(@"CLSID\{" +
t.GUID.ToString().ToUpper() + @"}\Control");
}
The RegisterFunction is called when the display is registered during the execution of the
RegAsm utility. The UnregisterFunction is called when a display is unregistered. For more
information on registering a display before use, consult the online Microsoft documentation.
11) Ensure the display is compiled with the necessary COM code so that it can communicate
with IADS. In the “Project” drop down menu, select Properties.
12) Under the “Build” tab scroll down to the bottom and check the Register for COM interop
option.
13) After this step is complete, save your work and continue onto the next section.
1) Add a public interface to the class. This is the interface which we will put all our properties
that we want to expose to the user. In this example, we have added the Value property to
provide access to the Value property of the .Net ProgressBar control.
public interface IProgressBar
{
int Value {set; get;}
}
3) The next step is to implement the created code for each new property we add. In this
example, we will focus on the set and get functions for the “Value” property.
4) For the set function, we will need to capture the incoming value and push it into the progress
bar object. Once that is complete, our progress bar should redraw and display the new value.
Please be aware that the value from the outside might be pushed on this display at a very high
frequency. It might be prudent to add code to determine if the incoming property value is
different than the existing value of a property and forgo the setting on the progress bar. This
is vital optimization you might need to consider when building more complex displays. For
this simple example, we will skip this step. The get function is easy to implement. Simply
return the value of our progress bar that we have created for this property.
5) At this point you can modify the code in the display to perform your specific needs.
6) See section 2.3 to add your new display to IADS.
1) In the development environment, place a break point in one of the “Set” method for testing.
In Visual Studio, select the Project > Properties drop down menu. In the “Debug” tab, set
the “Start external program” field to the IADS application executable (Iads.exe). The exe is
located in the “C:\Program Files\Iads” directory. Build your project and click the “Go”
command IADS will start.
2) Drag-n-drop your display onto the new Analysis Window as explained in section 2.3. Once
that is complete, save your configuration. Choose a parameter from the Parameter Tool and
drop it onto the display. After the parameter is attached to a property, your break point should
now hit in the debugger. You can now step through your drawing code if necessary.
2) In the New Project dialog that appears, choose the Visual C++ > ATL tier and click the
ATL Project option. At this point, please read the next step before you finish completing the
dialog. There are some important considerations when choosing the proper project name.
3) The project name you choose will become part of the display identifier name (aka ProgID,
see note below). When it comes time to use your control in IADS, users will insert your new
control into the “Display Builder” toolbox based solely upon its name (more on this later).
Plan on creating many displays in one “project” (most common and easier to manage the
code). Choose a general project name like “AircraftGauges” or “FluidSystemDisplays”. One
way to look at it is that the project name is akin to the “Genus” of your display, so shoot for
generality. Consider prefixing the project name with your organization like “NASA” or
“Lockheed”, as it may easier for users to locate your control the “Display Builder” list (i.e.
NasaFluidSystemDisplays or LockheedAircraftGauges).
Note: Microsoft refers to your function’s name as its “ProgID” (aka Program ID). This is the
string equivalent of your GUID (Global Unique Identifier) for the function. These Ids are
placed in the Microsoft registry (directly from your project’s “.rgs” file), allowing your
object to be created without any knowledge of the location of your “Dll” on the file system.
Of course, this assumes that it is registered using the “regsvr32” program (consult the
Microsoft documentation).
Now, in the fields at the bottom of the dialog, enter the project name, location, and the
solution name.
4) After pressing OK, the “ATL Project Wizard” dialog will appear as below.
5) Click the Next button in the Wizard. On the new wizard page, ensure that the “Dynamic Link
Library (DLL)” is checked. Every display that runs in IADS is of
type DLL because it allows for maximum speed in displaying graphics. Press the Finish
button and the Wizard will set up your project.
6) Next, go to the “ClassView” tab in Visual Studio’s workspace and right-click on the project
name. Choose Add > Class.
7) Upon adding a new class you will be presented with a dialog. Click the ATL tier and ATL
Control as shown below. When that is complete, press the Add button.
8) On the first tab, enter the name of your display in the “Short Name” field. The wizard will fill
out the rest of the tab automatically. For this example, I used “DisplayName” as the short
name. The name entered will be combined with your project name and will present the final
display name inside of IADS (ProjectName.FunctionName) as explained on page 1. See the
“ProgID” field in your dialog for your final IADS display name. Warning: Newer Visual
Studio versions do not automatically populate the ProgID field. Please ensure the ProgID
field contains your specific ProjectName.FunctionName text. If not, please type in the
appropriate text manually. Press “Next” to continue.
9) On the next tab (“Options”), leave everything as default (Standard control, Apartment, Dual,
Yes, and no other options checked). This will allow you to take full control of a “blank
canvas” and draw your display using low level graphics libraries such as GDI/GDI+ or
OpenGL. On the other hand, if you need to create a “dialog based” display containing typical
dialog elements such as text boxes, drop down lists, etc you will need to select the
“Composite control” choice.
The remaining options are basically “COM speak”. If want understand these options fully,
you will have to consult the Microsoft documentation. The most notable remaining option is
“Interface”. In order to create a real compliant ActiveX “display”, you must choose “Dual”
interface. This will enable IADS (and other programs) to interface to your control using the
“IDispatch” interface, which allows a loosely coupled, “on the fly” communication. This also
happens to be the primary (simplistic) way that IADS gets data to your control. More on this
subject later.
10) On the next tab (“Interfaces”), leave all of the default choices and select “Next”. Again, these
options are more “COM speak” and include standard interfaces in which the Wizard will
implement for you automatically. If you want more background information, consult the
Microsoft documentation.
11) On the next tab (“Appearance”), select the “Windowed Only” checkbox if you plan on using
OpenGL; otherwise uncheck it. “Windowed Only” will ensure that we have a window to
create an OpenGL context upon. For GDI based displays, we want to attempt to draw
“without a window” for speed and resource considerations. Leave the other settings as
default (later discuss the speed benefits of de-selecting the “Normalize DC” checkbox).
Remember, OpenGL = “Windowed Only”. Don’t worry, this can be easily changed later if
you make a mistake (as can almost anything).
12) On the next tab (“Stock Properties”), leave all the options empty and select “Next”. These
options are display properties that the Wizard will implement for you automatically.
Generally, each property will be added after Wizard is complete. If you want more
background information, consult the Microsoft documentation.
After clicking “Finish”, the Wizard will auto-create most of the code needed for your new
display. Examine your “Solution Explorer” view. It should now contain the new display
object by name.
2) In the Add Property Wizard, set the property type to the desired data type (double in this
example) and the name of the property (Roll in this example) and click Next.
3) In the last page of the Add Property Wizard, leave all the options as default except the
helpstring field. This helpstring will be displayed in the IADS properties sheet when the user
is setting the property, try to provide a descriptive (but short) sentence for your new property.
4) When you are complete, press the “Finish” button. This will auto-create code to implement a
property named “Roll” within your new project. Repeat this process (starting from step 1) for
every property that you want to add to the display.
5) Going back to your “Solution Explorer”, you will see the new property code inserted into
your display’s .cpp file.
6) The next step is to implement the code created for each new property we added with the Add
Property Wizard. Thus, in our example property “Roll”, we will need to focus in on the
put_Roll and get_Roll functions. In preparation, we will need to add a class member variable
for each new property. For the Roll property, add a new class member variable to the .h
display class named “mRoll” with the same data type as the property (double in this
example). Do not forget to set this new member variable mRoll to 0.0 in the “FinalConstruct”
function which is also part of the .h class.
7) For the put_Roll function, we will need to capture the incoming value and store it in a class
member variable. Once that is complete, we will call a function named “FireViewChange”
that will let our display know it needs to be redrawn. When the redraw function (OnDraw) is
called, we will then use the value contained in the class member variable to draw the display.
In addition, we will set a variable called m_bRequiresSave to TRUE, telling IADS that we
wish to save our display. This is a vital step to ensure your display is saved within IADS
when a property is changed. Notice that we only perform this code if the incoming property
value is different than the existing value of the property. The get_Roll function is easy to
implement. Simply return the value of our class member variable that we have created for
this property.
8) Now, when all of your properties are implemented, add your “drawing code” to the
“OnDraw” function. The OnDraw function is where you will take all the values of your class
member variables and actually draw the display content. See the sample projects for
examples in both GDI and OpenGL.
3) For every property to “save”, add it to the “BEGIN_PROP_MAP” area of the code as below.
The number corresponds to the property id that is defined by the wizard in the “.idl” file of
the project. Examine your “.idl” file from the “Solution Explorer” tab of the workspace for
the correct number. Properties in your “PROP_MAP” will get saved by IADS and reloaded
when the display is created in a saved Analysis Window.
4) At this point, you can begin modifying the code in the display to perform your specific needs.
5) See section 2.3 to add your new display to IADS.
2) In Visual Studio, select the Project > Properties drop down menu. Under the “Configuration
Properties > Debugging” tier, pick “Iads.exe” as your “Command”. The Iads.exe is located in
your “C:\Program Files\Iads” directory. Build your project and click on the “Go” command.
IADS will start.
3) Drag-n-Drop your display to the new Analysis Window as in section. Your break point
should now hit in the debugger. You can now step through your rendering code if necessary.
1) In Visual Studio, select the “Project->Properties” drop down menu. Make sure that the
“Configuration” dropdown is set to “Release”. Under the “Configuration Properties > C/C++
> Code Generation” tier, set the “Runtime Library” to “Multi-threaded (/MT)”.
2) Once you have made these changes to your project, you should rebuild your ‘solution’. Make
sure once again that your current configuration is set to “Release” and then select the Build >
Rebuild Solution drop down menu option. After this step is complete, your control dll
should be in your project “Release” folder. It should now be ready to deploy on another
system.
The control dll will need to be copied to the other PC and ‘registered’. In order to register the
dll, you will have to run the ‘regsvr32.exe’ program. One easy way to accomplish this is to
double click on the dll in Windows Explorer. When asked what program to execute on the
dll, navigate to the Windows\System32 directory and choose the regsvr32.exe file. This
procedure may be different if the operating system is a 64 version. Please consult the online
documentation for specifics.
If the dll fails to register at this point, we’ve most likely failed to statically link the needed
dlls. We can investigate which dlls are missing by using the “Dependency Walker” tool. The
Dependency Walker program is located within the Microsoft Visual Studio\Common\Tools
directory and is named “Depends.exe”. Copy Depends.exe from your development PC to the
target PC and run the program. From the File drop down menu select Open and choose your
control dll. Examine the module list in the bottom window pane. Any missing dependent dlls
should show up with a question mark. Search for those dll names on the net and find out their
purpose. It might help you narrow down what solution setting you have missed. It is also
possible that the missing dll is a private library that you are using, in which case you will
need to either static link or copy that dll to the target machine as well.
The “Display Builder” dialog will appear with icons of components that you can use to build
your displays (including your new ActiveX control).
2) Click on the Analysis Window icon (upper left) and hold down the left mouse button to drag
it onto your Desktop.
3) Now let’s add your new control to the “Display Builder”. Click on the second tab in the
display builder named “ActiveX Controls”. This is where all ActiveX displays will reside,
ready to be dropped upon your newly created Analysis Window. Notice that there are only a
select few ActiveX control icons on this tab of the display builder. If the display builder were
to show all of the controls available on your system, the icons would fill several pages of this
size. In order to add your new control, you must “Right-click” on tab (somewhere where
there are no icons). This will activate yet another dialog containing both the “IADS” supplied
ActiveX controls as well an entire list of all the ActiveX controls on your system (including
your newly created one!). Click on the All Controls tab of this new dialog and find your new
control. The name will be ProjectName.ObjectName” as discussed earlier in this tutorial.
Click OK to add your display to the display builder. This only needs to be done once for
each new control that you wish to debug/add in IADS.
Note: If you cannot locate you display in the “All Controls” list, try checking your “.rgs” file
in your VS2015 project in the “workspace” file view. It contains an entry named
VersionIndependentProgID. This is where VS2015 stores your “ProgId” (Program ID) for
the project.
2) In the New Project dialog that appears, choose the “Visual C#” tier and click the Class
Library option. At this point, please read the next step before you finish completing the
dialog. There are some important considerations when choosing the proper project name.
2) Plan on creating many functions in one “project” (most common and easier to manage the
code). The project name should be similar to the “Genus” of your function, so shoot for
generality. Consider prefixing the project name with your organization like “NASA” or
“Lockheed” and the type of functions you will be adding (example: NasaFluidFuncs).
Now, in the fields at the bottom of the dialog, enter the project name, location, and the
solution name.
3) After pressing “OK”, the project will be ready for editing. Rename the Class1.cs file to
reflect our function name. In this example, we will call it ‘MyFunction.cs’.
4) In preparation for the next step, we will need to add another “using” directive. In the code
view, add a line “using System.Runtime.IteropServices”.
5) Now we need to focus on the entire function name as it will appear to the IADS end user.
The format of the function name requires two strings separated by a period (‘.’). It is best
practice to use the Visual Studio project name as the first portion of the name (before the
period). The portion after the period should be your specific function name. For instance,
ProjectName.ClassName, NasaFluidFuncs.FlowRate, or in this tutorial
MyFunctions.MyFunction. We will define that name explicitly by using the “ProgId”
directive. In the code view, type [ProgId(“MyFunctions.MyFunction”)] above your class
definition “public class MyFunction”.
6) The next step is to implement the interface that IADS requires to call your function. To
accomplish this task, we will need to add a reference to the definition file of the interface.
From the Project menu, select Add Reference.
7) In the “Add Reference” dialog, select the COM tab. Scroll down until you see “Iads
Function Interface 1.0 Type Library”. Press OK to add the reference to our project.
8) Now, back in the Solution view, notice that the IadsFunctionLib has been added to our
References section. This reference contains the definition of the IADS custom function
interface. Now, we will need to add the interface to our class definition. First, type a colon ‘:’
after the class name and add the text “IadsFunctionLib.IIadsFunction”. In essence we will
inherit from the interface definition. After this is complete, we can implement the interface.
10) After choosing the “Implement Interface” menu item, Visual Studio automatically writes the
shell of the function we must implement. Within the function, the “ref object dataIn”
argument represents an array of input argument values from the IADS environment. The “ref
object dataOut” represents the single return value that we are allowed to return. For example,
if a user typed a derived equation MyFunction.MyFunction(1,2,Param1), the dataIn object
would be an array of three elements containing the values 1,2, and the value of Param1
respectively. Our job is to take the input values, run some mathematical algorithm, and
produce a single object ‘result’. Discussions on returning multiple results from a single
function call will be touched upon at a later time. For simplicity sake, let us focus on the
multiple in, single out technology.
11) During this next step, we will need to decode the dataIn object and extract the input
parameter values. When that is complete, we can perform our calculation and return the
result. In the code window remove the line of code containing the “throw” statement. Add
the following code it its place:
Array dataInArray = (Array)dataIn;
Double arg1 = Convert.ToDouble(dataInArray.GetValue(0));
Double arg2 = Convert.ToDouble(dataInArray.GetValue(1));
Double arg3 = Convert.ToDouble(dataInArray.GetValue(2));
dataOut = arg1 + arg2 + arg3;
12) Notice in the first line, we cast the ‘dataIn’ array to a C# array type object. This will allow us
to extract each function input argument in the subsequent lines of code. The first argument
passed into this function from IADS is array element 0, the second argument is 1, and so on.
By using the ‘Convert’ object, we can assign each input argument to a temporary variable.
Once these temporary variables are assigned, we can perform our calculation and return our
result. To return a result, simply assign the computed value to the ‘dataOut’ object.
13) At this point, you can begin modifying the code in the function to perform your specific
computation. For more background on how to pass arguments, check their types, and return
values, please refer to the SampleFunction project included with this tutorial. Make sure to
read the comments in the supplied compute functions.
14) Now that your function is basically complete, we must take care of some remaining interop
issues. We must ensure that the function is compiled with the necessary COM code so that it
can communicate with IADS. In the code view, type [ComVisible(true)] above the
ProgId definition line.
15) Under the “Build” tab, scroll down to the bottom and check the Register for COM interop
option. These two last steps are very important. If you forget this step, or the previous
[ComVisible(true)]directive step, the function will remain undefined in IADS
because it will not properly registered on the system.
To debug the function, go to the “Debug” tab in the same dialog and set the “Start external
program” item to the location of the IADS executable, in this case “C:\Program
Files\Iads\ClientWorkstation\Iads.exe”.
16) When all these steps are complete, compile the project, fix any errors and run. In IADS, build
a new derived parameter that calls your new function, and drop the parameter in any display.
If you want to debug your calculation step by step, put a break point in your compute
function. The code will break for each new data point calculated.
2) To run IADS from the debugger, go to the “Debug” tab in the same dialog and set the “Start
external program” item to the location of the IADS executable, in this case “C:\Program
Files\IADS\ClientWorkstation\Iads.exe”.
3) Build your solution again for good measure and click on the Start Debugging command (or
the F5 key); IADS will start. When IADS starts, pick the configuration file you wish to use
and click Open.
4) After IADS initializes, open the Configuration Tool, ParameterDefaults table (PDT) and
create a derived parameter. If you have already created a derived parameter referencing your
function, click on your equation in the PDT.
Notice that when you “tab out” or finish the equation in the PDT, your function will be
called. At this point you can debug all of the argument types and make sure you are getting
the correct items. If you have an argument error and return an error code from your function,
you will get an error message inside of IADS and the equation text will turn red in color.
After you have checked out the arguments, you can remove the breakpoint and debug the
function with real data.
5) Add a display to the new Analysis Window (i.e., Alphanumeric or Stripchart) as described in
section 3.3. If your parameter is not already attached to a display, drag and drop our new
function into the display. Your break point should now hit in the debugger. You can now step
through your computational code as necessary.
Again, for more background on how to pass arguments, check their types and return values,
please read the comments in the example project.
2) In the New Project dialog that appears, choose the “Visual C++ > ATL” tier and click the
ATL Project option. At this point, please read the next step before you finish completing the
dialog. There are some important considerations when choosing the proper project name.
3) The project name you choose will become part of the function identifier name (aka ProgID,
see inset). When it comes time to use your function in IADS, users will call your new
function in a derived equation based solely upon its ProjectName.ObjectName (we will add
the specific object name later). Plan on creating many functions in one “project” (most
common and easier to manage the code). One way to look at it is that the project name is akin
to the “Genus” of your function, so shoot for generality. Consider prefixing the project name
with your organization like “NASA” or “Lockheed” and the type of functions you will be
adding (example: NasaFluidFuncs).
Now, in the fields at the bottom of the dialog, enter the project name, location, and the
solution name.
After pressing OK, the “ATL Project Wizard” dialog will appear as below.
4) Click the Next button in the Wizard. On the new wizard page, ensure that the “Dynamic Link
Library (DLL)” is checked. Every function that runs in IADS is of type DLL because it
allows for maximum speed in computing calculations. Press the “Finish” button and the
Wizard will set up your project.
5) Next, go to the “ClassView” tab in Visual Studio’s workspace and right-click on the project
name. Choose “Add->Class”.
6) Upon adding a new class you will be presented with a dialog. Click the ATL tier and ATL
Simple Object as shown below. When that is complete, press the Add button.
7) On the first tab, enter the name of your function in the “Short Name” field. The wizard will
fill out the rest of the tab automatically. For this example, I used “FunctionName” as the
short name. The name entered will be combined with your project name and will present the
final function name inside of IADS (ProjectName.FunctionName) as explained on page 1.
See the “ProgID” field in your dialog for your final IADS function name. Warning: Newer
VisualStudio versions do not automatically populate the ProgID field. Please ensure the
ProgID field contains your specific ProjectName.FunctionName text. If not, please type in
the appropriate text manually. Press “Finish” to continue.
8) At this point, the Wizard will automatically create the shell of your function code. All we
need to do now is to take care of the interface portion of the function. Basically, we will need
to implement the defined “IIadsFunction” interface so that the function will be compatible
with the IADS environment.
Download the “Custom Derived Function Helper Classes” on the Curtiss Wright IADS web
site: https://iads.symvionics.com/support/programming-examples/
After you have downloaded the zip file, unzip its contents into your project folder. While
unzipping, you will notice a file called “IadsFunction.idl”. That is the file we will use to
implement the interface.
9) Now let’s add the IadsFunction.idl to the project. Click the View tab at the top menu bar and
select Solution Explorer.
10) Expand you Solution, Right-click on the Project name, and select Add > Existing Item…
11) In the File Name box, type “*.idl” and then the enter key to show the Interface Definition
Language files. Choose “IadsFunction.idl” and then press the OK button to add the file into
your project. This should be the same IadsFunction.idl file that you unzipped in step 9.
12) Due to an apparent bug in Visual Studio 2015 (and earlier), we will have to manually correct
the output of the IadsFunction.idl file. Apparently, Visual Studio attempts to merge this
information into the output of your project’s idl file, but it does seem to work properly.
Right-click on the IadsFunction.idl in your Solution Explorer and select “Properties”.
13) In the Property Pages dialog that appears, select the “All Configurations” drop down in the
upper left-hand corner of the dialog. It is best to also select “All Platforms” in the Platform
drop down. Open the MIDL->Output tier in the left window pane and correct the “Header
File”, “IDD File”, “Proxy File”, and “Type Library” fields using the base name
“IadsFunction”. When you are complete, the dialog should match the picture below. After
confirming the dialog contents, press OK.
14) Now, build your Solution. After the build process is complete, a “typelib” file will be
created. We can use this typelib file to implement the IadsFunction interface. The typelib file
is simply a compiled binary version of the IDL file.
15) Go back to the ClassView tab of the Workspace viewer. Right-click on the “C[your function
name]” class object and then choose “Add->Implement Interface…”
In the Implement Interface dialog, ensure that the IadsFunctionLib<1.0> library is selected in
the “Available type libraries” drop down. When that is complete, you will notice that the
IIadsFunction interface appears in the “Interfaces” list. Select IIadsFunction and press the
“>” button. When IIadsFunction appears in the “Implement Interfaces” list, press Finish.
16) We’re almost done now. At this point we can concentrate on the actual function code (at
last). In the Solution Explorer tab of the Workspace View, locate your “[Function Name].h”
file and click on it to begin edit. Scroll down to almost the end of the source code and locate
the wizard generated code:
STDMETHOD(Compute)( VARIANT * dataIn, VARIANT * dataOut)
{
// Add your function implementation here.
return E_NOTIMPL;
}
Remove this entire function as we are about to inject some example code.
17) In the place of the code you just removed, insert the following example code:
STDMETHOD(Compute)( /*[in]*/ VARIANT* dataIn, /*[out]*/ VARIANT* dataOut )
{
int argCount = dataIn->parray->rgsabound->cElements;
if ( argCount != 3 )
{
return DISP_E_BADPARAMCOUNT;
}
// Third step: Get the actual values of each arg by extracting from
// Final step: Perform your function's purpose and return the output
// value. Because we're returning a number, the return type is VT_R8
// (double) for now. IADS will convert if necessary..
dataOut->vt = VT_R8;
dataOut->dblVal = p1 + p2 + p3;
return S_OK;
}
When that step is complete, your code should like something this:
18) Now, build the solution. After the build is complete you will notice that we have link errors.
This is a continuation of the Visual Studio bug as noted in steps 11 and 12. To correct the
errors, we will need to add the newly created IadsFunction files into the StdAfx.cpp file.
In the Solution Explorer, click on the StdAfx.cpp file and add the following lines to the
source code:
#include “IadsFunction.h”
#include “IadsFunction_i.c”
19) At this point, you can begin modifying the code in the function to perform your specific
computation. For more background on how to pass arguments, check their types, and return
values, please refer to the SampleFunction project included with this tutorial. Be sure to read
the comments in the supplied compute functions.
20) After you are done modifying the code, build the Solution. By building your Solution, the
new dll should be registered so you are ready to run and debug it now inside of IADS. The
next section in the tutorial describes how to debug the function.
If you want to use your function on another PC, you will need to register the dll on that
specific PC. Please consult the web for documentation on “regsvr32.exe” and how to perform
this procedure.
If you want to add another function, simply repeat steps. You can add as many functions to
this project as you would like and they will all be accessible through the same dll (i.e.
MyFunction.FunctionName1, …, MyFunction.FunctionNameN). If you wish to create an
entirely new dll and set of functions, you will need to repeat this entire tutorial using a unique
project name.
Note: See section 3.3 to access your new function in IADS.
2) Go to Project > [ProjectName] Properties drop down menu in Visual Studio, and in the
dialog that appears pick “Iads.exe” as your “Executable for debug session”. The Iads.exe file
is in your “C:\Program Files\Iads\ClientWorkstation” directory. When you are ready to
continue, press the OK button.
3) Build your Solution again for good measure and click the Go command (or the F5 key).
IADS will start. When IADS starts, pick the configuration file you wish to use and click
Open.
4) After IADS initializes, open up the Configuration Tool and create a derived parameter in the
ParameterDefaults table. If you have already created a derived parameter referencing your
function, simply click on your equation in the ParameterDefaults table.
Notice that when you “tab out” or finish the equation in the Parameter Defaults table, your
function will be called. At this point you can debug all of the argument types and make sure
you are getting the correct items. If you have an argument error and return an error code from
your function, notice that you will get an error message inside of IADS and the equation text
will turn red in color. Once you have checked out the arguments, you can remove the
breakpoint and debug the function with live data.
5) Add a display to the new Analysis Window (i.e. Alphanumeric or Stripchart) as described in
the section 3.3. If your parameter isn’t already attached to a display, simply drag and drop
your newly built derived parameter into the display. Your break point should now hit in the
debugger. You can now step through your computational code if necessary.
2) Once you have made these changes to your project, you should rebuild your ‘solution’. Make
sure once again that your current configuration is set to “Release” and then select the Build >
Rebuild Solution drop down menu option. After this step is complete, your function dll
should be in your project “Release” folder. It should now be ready to deploy on another
system.
The function dll will need to be copied to the other PC and ‘registered’. In order to register
the dll, you will have to run the ‘regsvr32.exe’ program. One easy way to accomplish this is
to double click on the dll in Windows Explorer. When asked what program to execute on the
dll, navigate to the Windows\System32 directory and choose the regsvr32.exe file. This
procedure may be different if the operating system is a 64-bit version. Please consult the
online documentation for specifics.
If the dll fails to register at this point, it most likely failed to statically link the needed dlls.
We can investigate which dlls are missing by using the “Dependency Walker” tool. The
Dependency Walker program is located within the Microsoft Visual Studio\Common\Tools
directory and is named “Depends.exe”. Copy Depends.exe from your development PC to the
target PC and run the program. From the File drop down menu select Open and choose your
function dll. Examine the module list in the bottom window pane. Any missing dependent
dlls should show up with a question mark. Search for those dll names on the net and find out
their purpose. It might help you narrow down what solution setting you have missed. It is
also possible that the missing dll is a private library that you are using, in which case you will
need to either static link or copy that dll to the target machine as well.
3) In the Configuration Tool dialog left window pane, click the “+” sign next to the “Data”
folder to open it and then select the ParameterDefaults table. This is the location in IADS
where you will build a new derived parameter to test your function.
4) To add a new derived parameter, for speed, simply copy the last line in the table and then
replace our new values as necessary. Select the last row in the table by clicking on the row
number. After the row is selected, press Ctrl+C to copy and then follow that by a Ctrl+V to
paste. You should now see a copy of the last line placed into a new row. When you are done
the table should look something like this:
5) Click into the first column of the new row. As we go, to proceed to the next cell press the
Tab key.
Do not edit the first column, press the Tab key to start editing the second column. In the
second column, type the name of your test parameter “TestMyFunction”. Once you are done
press the Tab key. Now set the type of the parameter; just leave it “float” (i.e. 4-byte floating
point number). In the future if you are testing an Ascii return value, you will need to set this
type to Ascii.
At this point, keep pressing the Tab key until you arrive at the “DataSourceType” column.
Make sure that is set to “Derived”.
In the next column (DataSourceArgument) you will write your derived equation. Now,
remember from the discussion while creating your function regarding the function name.
Enter the function name followed by the arguments:
MyFunctionGroupName.FunctionName( 5.0, 10.0, 30.0 )
If you want some variety to your test data, you can use something like this:
MyFunctionGroupName.FunctionName( Rand()*5.0, Rand()*10.0, Rand()*30.0 )
Or if you already have specific input parameters in mind, you can do something like this:
MyFunctionGroupName.FunctionName( Param1, Param2, Param3 )
In the next field (UpdateRate), type the sample rate that you desire to update your function. If
your equation is based off of other parameters, the sample rate will be automatically
computed and placed into this field when you Tab out of the cell.
Just for safe measure, press the Tab key until you get to the “FilterActive” column. Make
sure that it is set to “No”. We don’t want a filter to be affecting our output at this time, or it
could lead to confusion.
After these steps are complete, click the Save button in the Configuration Tool toolbar.
Your new parameter will now be available in the Parameter Tool.
To run the function, drop the parameter into any display.
6) To build a test display, create an empty Analysis Window by dragging the icon from your
Display Builder onto your Desktop.
7) Now add the “Alphanumeric” display to the Analysis Window you just created using the
same drag-n-drop process; you should see the new display in the Analysis Window when
complete. The Alphanumeric is a very simple text display that will be easy to view the
equation output results.
Note: Use your cursor to hint on icons on the Display Builder to see which type of display
they are.
8) Ok, now for the parameter attachment to the display. Click on the Parameter Tool button in
the IADS Dashboard (bottom right hand corner of screen). The Parameter Tool dialog will
appear. The Parameter Tool dialog contains a list of all your available parameters in the
configuration. Now all we need to do is find our parameter.
9) In the top text field (quick find box), start typing the parameter name. I used the name
“TestMyParameter”, if you have done the same then type “TestMy”. You will notice that the
window at the bottom opens as soon as it finds your parameter. Keep typing until you see the
full parameter appears. Once it is visible, click on the parameter name and drag the parameter
into the display on the Analysis Window. As soon as you drop the parameter, data should
appear. This is the actual output of your function!
10) After your initial checkout is complete, you can move on to displays such as the Stripchart
that will show history and allow you to examine the data point by point for discrepancies.
Simply repeat the drag-n-drop process using the Stripchart icon (instead of the Analysis
Window icon) in the Display Builder (step 6). Make sure to save the configuration for later.
Extending this logic, each “instance” of your function called from within IADS is a
completely independent unit of code, akin to a C++ object with member variables and
corresponding code. In essence, each derived parameter is running a fully independent object.
Obviously, this is necessary if your function maintains states such as “last value” or perhaps a
specific “matrix” input file that is required and chosen by the user via the function’s input
arguments. In reality, your function can be called from many different derived parameters
simultaneously, each with their own unique set of input arguments, and possibly computing at
different times within the data. Because of this wide variety of possibilities, be aware that any
reference to “static” or “global” variables should be considered carefully. Global variables will
allow you to “share” information between multiple instances of your function, but you will have
to be very careful about the timing considerations. If you do decide to venture down this path,
please do post your scenario to the IADS Google Group. In general, avoid all use of global
variables and instead, use member variables within the class to hold any necessary state
information.
Now let’s examine the initialization stage in more detail. The function name (i.e. ProgID)
within the derived equation is used to call the “CoCreateInstance” function in the Microsoft
COM libraries to create your object. Once your object is created within IADS, the
“FinalConstruct” method is called. In this method, you can put any initialization needed that is
independent of the input values to your function. This most likely would be limited to things
such as setting member variables to a known initial value.
For instance, say you were building a function allowed a user to specify a number of data
points to “buffer” before computing a result. Of course, you will need a member variable in the
class to hold this buffer. During the FinalConstruct, you would set your member variable buffer
pointer to NULL, but you would not allocate the memory. At this point in the initialization, you
don’t have any of the argument values from the user’s equation, thus you don’t know how large
to allocate the buffer. In the next paragraph, we will discuss a way to solve this issue.
After your FinalConstruct function is called, IADS then calls the “Compute” function
within your object. The main purpose of this first call to your Compute function is to validate the
equation input variables. Understand that the custom function interface is flexible enough to
allow any number of input arguments, and each argument could be a different type (float, ascii,
blob, etc). It is at this exact time, the very first call to your Compute function, which you will
need to check the number and types of your input arguments. In fact, IADS will only listen to
your input argument error return codes on the first call to your function. Since we only want this
code to execute on the first call to the Compute function (and never again), a Boolean member
variable can be used to solve the problem. Simply add a member variable to your class and
initialize it to false in the FinalConstruct.
The secondary purpose of this first Compute function call is to give you an opportunity to
initialize any further variables (such as buffers, etc). Now, inside the Compute function you can
check the Boolean member variable’s value, perform your argument checks and buffer
initialization, then set the member variable so the code is not triggered again. See the example
code snippet below or refer to the SimpleFunction2.
Now that the initialization stage of your function is complete, IADS will call your
function as data is required. This we will refer to as the “computation stage”. For each data value
needed, IADS will call your Compute function with all the necessary input data. Your custom
function will perform the processing and return a single value (the answer). This single answer
will then be returned to the derived parameter, buffered to limit redundant computation, and be
provided to a display (or other consumer).
The sample code in SampleFunction2.h will show you how to handle the various types of
input data (float, string, etc). It will also show you how to return these different types as your
custom function result. This will allow you to create custom functions to return data for almost
any situation. Again, if you need more help on this subject don’t hesitate to post a question to the
IADS Google group. For more advanced topics, such as returning multiple values from your
custom function, please continue to the next section.
When a function needs to output multiple answers in a single computation, we can simply
output an “array” of answers. This array type output is referred to in IADS as a BLOB (binary
large object). Once the array/blob is output from your custom function, it can then be returned as
a blob type parameter and the individual values in the array can be extracted using another
derived function called “Decom”. In summary, we simply return an array of answers (however
many required by the individual function), and then we can extract each value in its own unique
derived parameter using the Decom function. Now, let’s go more into detail about this technique.
First of all, we will need to create an array to output our five results. IADS requires that
this data array be allocated using Microsoft’s “SafeArray” mechanism, so we need to add a
pointer of type SAFEARRAY to our class. In this case, I used “mSA” as the member variable
name.
Now we will need to allocate the memory for this array. Carrying on the initialization
discussion from the last section, we will perform the allocation in the Compute function within
the “first time only” portion of the function. To create the array, we will simply call the
SafeArrayCreateVector function with the type VT_UI1 (byte) and the number of bytes required.
Now let’s focus in on the actual “size in bytes” required by the allocation. To do this
properly, we have to describe in more detail the actual structure of the blob. In a blob, the first 4
bytes of the array is a number specifying the total length of the blob (in bytes).
With this fact in mind, the equation to compute the total length of allocation needed is:
BlobSizeInBytes = sizeof( unsigned __int32 ) + TotalSizeOfDataPortionInBytes
Or
BlobSizeInBytes = 4 + TotalSizeOfDataPortionInBytes
Or in our example using 5 floating point numbers (4 bytes per number)
BlobSizeInBytes = sizeof( unsigned __int32 ) + sizeof( float ) * 5
At this point, you should have the return blob/array allocated, so now let’s examine how
to update our values in the array and return the results. First, we will need to access the array
pointer within the SAFEARRAY. To do this, we simply call the SafeArrayAccessData function.
Second, let’s set the blob size into the array. To do this, we simply cast the pointer
returned from the SafeArrayAccessData to a type unsigned __int32* and then set the value to the
total number of bytes in the blob. The total number of bytes in our example is 24 (4 bytes for the
size field + 20 bytes for the 5 float values).
Now we can inject our computed results into the array. To do this, we need a pointer to
the type of variable we are going to store. We also need to make sure that the pointer starts at the
proper location in the array (past the BlobSizeInBytes field we just set above).
Instead of setting each value individually, you may want to simply call another function
to compute the results and pass in the output array pointer. You can then set the return values
from within that function and also keep all of your “calculation” code separate from the
“interface” code. This is a much cleaner approach overall.
After we are complete, this is how the blob layout will appear in memory (zero based
index):
Once you have completed setting the return values into the array, it is now time to return
the blob to IADS. All we need to do here is call SafeArrayUnaccessData, set the dataOut->vt to
VT_ARRAY|VT_UI1 (i.e. an array of bytes), and assign the dataOut->parray variable to our
SafeArray member variable (mSA). To finish the function and return the value to IADS, we
simply return S_OK from the Compute function.
At this point in time, we can now test the function. To proceed, we will need to build a
derived equation to call your new function. We will also need to build derived functions to
extract the results from the blob. Compile your project and clean up any errors. When that is
done run IADS, and open up the Configuration Tool. Open the ParameterDefaults table and add
a parameter that calls your new function.
Notice in the figure above that the “ParamType” column is set to “blob”. This is an
essential step that you can’t forget. If the ParamType is not set to “blob” for the derived
parameter, you will most likely get random return results or zero while attempting to extract the
5 embedded values.
Now, scroll over to the DataSourceType column, and set it to “Derived”. In the
DataSourceArgument column, type an equation that calls your new function. To debug the
equation, you might want to start with a set of known input values (constants). After completing
the equation, save your configuration. We can now actually test the raw output of the custom
function.
At this time, if you wish to see the raw output of your function you can drop your newly
created derived parameter into the “IadsBusMessageDisplays.BlobViewer” display. If you
Right-click on the ActiveX Controls tab of the Display Builder in IADS, you can add the Blob
Viewer to your available displays list. Once that is complete, drag and drop the Blob Viewer
display into an Analysis Window. After the display appears, drop your new derived parameter
into the display. Notice that the Blob Viewer only shows the “payload” portion of your blob. The
size field in the blob has been stripped by IADS. This is to be expected, so don’t be alarmed.
Each 4 bytes in the display is a single 32-bit float return value. Bytes 0 .. 3 show the first
return value, bytes 4..7 show the second, and so on. Note that since our blob has a total of 5
return values, there is an extra 4-byte field at the end containing all CD values. This is an artifact
of the display and not actually in the blob itself. This issue should be fixed in a new version of
IADS soon, so you can safely ignore it for now.
Now that we know our blob is successful, we can continue on and actually extract each
individual value. When this step is complete, we can drop each individual return value into its
own display, or use these return values as an input into another derived equation. After
extraction, it will simply be “yet another derived parameter” and you can treat it like any other
parameter in the system.
To extract the individual values from the blob, we need to create one derived equation per
value. Each derived equation will use the “Decom” function to do the extraction work. Now,
return to the Configuration Tool and ParameterDefaults table to add 5 more derived parameters.
For each derived parameter, you must set the “ParamType” column to the type of the extracted
value. In our case, we packed 5 floating point values (32 bits each) into the blob, so the
ParamType must be set to “float”. If you skip this step you will again most likely get random
values or zero.
At this point we’re almost done. All we need to do is to write the extraction equations
using our blob parameter as the input. Scroll over to the DataSource column and set it to
“Derived”. In the DataSourceArguement column, add the following equation:
Decom( MyMultipleOutParam, 0, 4, 0, 31, 1, TRUE, FALSE )
The equation looks a little cryptic so, let’s go over the Decom function arguments:
FuntionName: Decom
Arguments: 8
ArgumentList: InputDataParam, ByteOffset, NumBytes, StartBit, StopBit, DataTypeToReturn,
Signed, ReverseBytes
DataTypeToReturn -> { Integer=0, IEEEFloat=1, 1750Float=2, CharString=3, Array=4 }
Signed -> { False=0, True=1 } or just use TRUE/FALSE
ReverseBytes -> { False=0, True=1 }
Example Usage to extract a 4 byte IEEEFloat: Decom( MyIntParameter, 0, 4, 0, 31, 1, TRUE,
FALSE )
Basically, the Decom function is an all-purpose blob field extractor which can convert the
bit patterns extracted into any available type in IADS. With this in mind, let’s focus back on
extracting our values.
Decom( MyMultipleOutParam, 0, 4, 0, 31, 1, TRUE, FALSE )
The first argument of the Decom function is the blob source parameter. In this case, we
use the derived parameter that produces packed answers from our custom function. This should
be the same parameter we dropped into the Blob Viewer above.
The second argument is the “starting byte offset” of the item we wish to extract within
the blob. The byte offset is simply the number of bytes from the start of the payload section of
the blob (remember to now ignore the 4 byte size field). Since we are defining the equation for
the first return value, the starting byte offset will be zero (all the offsets are zero based in this
equation).
The third argument is the number of bytes to extract. In this case, the size of the return
value is 4 (4-byte floating point number). If you had chosen to pack double precision floating
point values (8 bytes each), this argument would be set to 8.
The fourth argument is the “starting bit offset” of the data within bytes identified in
arguments 2 and 3. In this case, we want all the bits so we simply specify bit 0. Likewise, the
fifth argument is the “ending bit offset” of the data identified in arguments 2 and 3. Again, we
want the full 32 bits, so we will specify 31.
The sixth argument is the actual “data type” that we want to return from the function. In
this case it is an IEEE float, so we will specify 1. The seventh and eighth arguments are simply
the signed flag and whether we need to reverse the bytes before data type conversion. We will
specify TRUE and FALSE respectively.
Now that we understand the Decom function in general, let’s simplify our task. Since all
of our return values are all of the exact same type and size, we can generalize our equations as
such:
Decom( MyMultipleOutParam, index*sizeof(returnValue), sizeof(returnValue), 0,
sizeof(returnValue)*8-1, DataType, TRUE, FALSE )
Or for our specific example
Decom( MyMultipleOutParam, index*4, 4, 0, 31, 1, TRUE, FALSE )
Where index goes from 0 to 4 (0 being our first item and 4 being our fifth item)
Using this generalization, we can easily write all of the functions needed:
When you are finished writing all of the extraction equations, your ParameterDefaults
table should look similar to the above figure. Make sure to save your configuration upon
completion.
Now, all that is left is to drop the individual parameter into displays and test. If you have
any questions, please don’t hesitate to post them to the IADS Google group.
4. Custom Plugins
4.1 Creating a custom export plugin using C++ VS2015
The SampleExportPluginVS2005 demonstration project is available for download from
the Curtiss Wright IADS web site at the following location:
https://iads.symvionics.com/support/programming-examples/
It provides the necessary starter code for your new project. Once your plugin is complete
and registered on the IADS Client machine, it will appear on the Stripchart’s Data Export menu.
Note- on line 250 of the CSVFile.h in the exportdatagroup function ::OutputDebugString("Failed
to create parameter"); you must change to ::OutputDebugString(L"Failed to create
parameter");The L is needed because of the project settings of Unicode vs multibyte characters.
It is important to build a new project rather than simply reusing the sample project
developed by SYMVIOINCS. The reason for this is that each export plugin project has its own
unique ID called a GUID that is placed in the Windows Registry. If more than one group uses
the sample project for their own, they cannot register on the same machine. Therefore, this
tutorial is presented as you the user are creating a new DLL project called MyExportPlugin.dll.
Further on we will show how to copy and paste code from the sample project so that you can
concentrate solely on your export code and not the interfacing between it and the outer IADS
Client shell. Remember to ensure that the bitness of your project and therefore the compiled
plugin is set to match the bitness of your IADS client (x64, x86).
2) In the New Project dialog that appears, choose the “Visual C++ > ATL” tier and click the
ATL Project option. At this point, please read the next step before you finish completing the
dialog. There are some important considerations when choosing the proper project name.
3) The project name you choose will become part of the display identifier name (aka ProgID,
see step 10). When it comes time to use your plugin in IADS, users will register your DLL
which automatically insert itself into the correct registry position and then be available from
the IADS Stripchart’s Right-click menu. The menu display name will come from your plugin
(more on this later). Plan on creating many plugins in one “project” (most common and
easier to manage the code). Choose a general project name like “NasaExportPlugins” or
“BA609ExportPlugins”. Think of the project name like a library name, and your plugins are
the books.
Now, in the fields at the bottom of the dialog, enter the project name, location, and the
solution name.
4) After pressing OK, the “ATL Project Wizard” dialog will appear as below.
5) Click the Next button in the Wizard. On the new wizard page, ensure that the “Dynamic Link
Library (DLL)” is checked. Every plugin that runs in IADS is of type DLL. Press the
“Finish” button and the Wizard will create your project.
6) In the this step we will setup a couple optional project-wide settings that make it easier to
work with provided IADS source code and eliminate warnings. Right-click on the project and
select properties from the menu. Click on the General tab and change the “Character Set”
option to “Use Multi-Byte Character Set”.
7) Again, from the Project/Properties menu select C/C++, Preprocessor and add the following
definition “_CRT_SECURE_NO_WARNINGS”
8) Now we will add our actual export object. Go to the “Class View” tab in Visual Studio’s
workspace and right-click on the project name. Choose Add > Class. At this point we are
adding our first export plugin
9) Upon adding a new class you will be presented with a dialog. Click the ATL tier and ATL
Simple Object as shown below. When that is complete, press the Add button.
10) On the first tab, enter the name of your display in the “Short Name” field. The wizard will fill
out the rest of the tab automatically. For this example, I used “CSVFile” as the short name.
Notice that CSVFile.h and CSVFile.cpp will be created by the wizard and will be the source
code files that you will edit with your own export code. The name entered will be combined
with your project name and will form the final “ProgId” as shown. Press “Next” to continue.
The ProgID is not populated automatically using in VS2015. You must input this manually.
It should be in the form ProjectName.ClassName or in this case
MySampleExportPlugin.CSVFile.
11) On the next tab (“Options”), leave everything as default (Apartment, Dual, Yes, and no other
options checked). Any other dialogue boxes can be left in default.
The remaining options are basically “COM speak”. More information about these options
can be found in the Microsoft documentation. At this point your project can compile and
register your DLL successfully, although it does not do anything yet.
Now we need to compile the newly added IDL files to generate the output files needed in the
export source code we will be editing. IDL files are compiled by a program called “MIDL”
(Microsoft’s IDL compiler). This is accomplished by setting up the configuration of each file in
the following manner:
1) Right-click on the “iads.idl” file and select Properties.
2) Click on the MIDL tier in the dialog and select the Output option.
3) Change the default names from MyExportPlugin to the name of the IDL file as shown in the
following example.
4) Repeat this step for the “IadsTime.idl file”.
5) The “iads.idl” file includes the “IadsTime.idl file” so you may need to set the path for the
MIDL compiler as shown:
6) Make sure and compile each file individually to run MIDL and create the needed output files:
Note: iads_p.c and iadstime_p.c and are created but are not used.
7) Add the MIDL generate files to the “stdafx.c” source code file. Adding these files here will
allow access to the needed global variables in your export source code. Once complete,
rebuild to ensure no errors.
8) Add the IADS IDL interface file includes into your IDL file and change your export interface
to derive from IDataExportPlugin instead of IDispatch that was generated by the wizard.
import "IadsTime.idl";
import "Iads.idl"
and
interface ICSVFile : IDataExportPlugin{
9) Just as in step 4 you may need to set the MIDL path property so that your IDL knows to the
location of the “iads.idl” and IadsTime.idl files.
10) At this point all the necessary external files have been added to your project, however it will
not compile until we add the routines that are expected by the IDataExportPlugin interface.
2) Modify the string argument in the plugins-add call. This will become the actual display name
that appears in Iads on the Right-click menu.
3) Next add the “mIads” member variable to the public section of your class in CSVFile.h.
2) After building the solution, you can use regedit to verify that the registration code worked
properly by putting the ProgId into the HKEY_LOCAL_MACHINE/Symvionics,
Inc./IADS/ClientWorkstation/Addins registry hive.
3) Finally, you can run IADS (requires version 7 or greater) and verify that MyExportPlugin
was added to the Stripchart Data Export menu as shown here.
Before you can run Iads in debug mode to verify your plugin was added to the program
please complete the next section, 5.1.4.
In Visual Studio, select Project > Properties drop down menu. In the “Debugging” tier, pick
“Iads.exe” as your “Command”. It is in your “C:\Program Files\Iads\ClientWorkstation”
directory. Build your project and click the “Go” command. IADS will start. If you have built
a x64 plugin you’re the iads client will be in C:\Program
Files\IADS\ClientWorkstation\iads.exe. If you compiled a x86 version you will have to use
the 32 bit Iads client which is located within C:\Program Files
(x86)\IADS\ClientWorkstation\iads.exe.
2) Right-click on the Stripchart and select the Properties option and then the Data Export
option. Select “My Export Plugin” to hit your breakpoint in your code in the
“PerformDataExport routine.
ParameterSets Collection
IADS allows multiple Parameter Sets to be defined and enabled for processing. The
ParameterSets collection is used to return ParameterSet Item which in turn contains a
ParameterDefaults collection (see the “ParameterDefaults Collection“ section below) . Following
are the functions in the ParameterSets collection:
Method Return Arguments Description
Count Out long* Gets the number of IParameterSet Items within the
collection.
Add In BSTR Add a new IParameterSet Item to this collection. Add a
ParameterSet by name
In BSTR The group name of the IParameterSet Item to add to
this collection.
RemoveAll None VOID Remove all IParameterSet Items from this collection.
Item In VARIANT Return an IParameterSet Item by name (string) or
index number (0..Count). IndexOrName
Out IParameterSet** Return value, reference to the specified IParameterSet
Item. Returns a Set object by name (string) or index
number (0..Count)
SaveTable None VOID Save changes to this Collection
ParameterSet Item
The Parameter Set item contains the Set name, the Group name, and an IsActive boolean
if the set is active in IADS. It also contains the ParameterDefaults collection for further
processing of Parameter information.
Method Return Arguments Description
SetName Out BSTR* Get the Parameter Set name
SetName In BSTR Set the Parameter Set Name
Group Out BSTR* Get Parameter Group name
Group In BSTR Set Parameter Group name
IsActive Out VARIANT_BOOL* Get Parameter Set Active
IsActive In VARIANT_BOOL Set Parameter Set is active
ParameterDefaults Out IParameterDefaults* Get Parameter Defaults collection
ParameterDefaults Collection
The ParameterDefaults Collection holds all the available Parameter Items. It returns
ParameterDefault Item which contains all the available properties for each parameter.
Method Return Arguments Description
Count Out long* Gets the number of IParameterDefault items within the
collection.
Add In BSTR Add a new IParameterDefault Item to this collection, this is
the Parameter Name
In IadsDataType This is the inherent type of the parameter
In Double This is the sample rate of the parameter
Out IParameterDefault* Return value, reference to the newly added IParameterDefault
* Item.
Remove In VARIANT IParameterDefault Item by index or name from this collection
RemoveAll None VOID Remove all IParameterDefault items from this collection.
Item In VARIANT Return an IParameterdefault Item by name (string) or index
number
SetName In BSTR* Return the IParameterSet name that this parameter belongs to
SaveTable None VOID Save changes to this collection
ParameterDefault Item
The Parameter item is returned from the ParameterDefaults collection. Following are the
Methods in the ParameterDefaults collection along with their return value, or input argument and
description
Method Return Argument Type Description
Name Out BSTR* Get parameter name
Name In BSTR Set parameter name
DataType Out IadsDataType* Get parameter data type
DataType In IadsDataType Set parameter data type
Group Out BSTR* Get parameter group name
Group In BSTR Set parameter group name
SubGroup out BSTR* Get parameter subgroup name
SubGroup In BSTR Set parameter subgroup name
ShortName Out BSTR* Get parameter short name
ShortName In BSTR Set parameter short name
LongName Out SBSTR* Get parameter long name
LongName In BSTR Set parameter long name
Events Collection
Method Return Arguments Description
Count Out long* Gets the number of IEvent Items within the collection.
Add In BSTR Add a new IEvent Item to this collection by parameter name.
In BSTR IRIG time at threshold break.
Out IEvent** Return value reference to the newly added IEvent Item.
Remove In VARIANT Remove IEvent Item by index or name from this collection
RemoveAll None VOID Remove all IEvent Items from this collection.
Item In VARIANT Return an IEvent Item by name (string) or index number
(0..Count). IndexOrName
Out IThreshold** Return value, reference to the specified IEvent Item. Returns a
Set object by name (string) or index number (0..Count)
SaveTable None VOID Save changes to this Collection
Event Item
Method Return Argument Description
Group Out BSTR* Get the group name
Group In BSTR Set the group name
SubGroup Out BSTR* Get subgroup name
SubGroup In BSTR Set subgroup name
User Out BSTR* Get user name
User In BSTR Set user name
IrigTime Out BSTR* Get IRIG time
IrigTime In BSTR Set IRIG time
Name Out BSTR* Get the comment
Name In BSTR Set a comment
PropBag Out BSTR* Get property bag
PropBag In BSTR Set the property bag
Thresholds Collection
Threshold Item
Method Return Argument Description
Group Out BSTR* Get the group name
Group In BSTR Set the group name
SubGroup Out BSTR* Get subgroup name
SubGroup In BSTR Set subgroup name
User Out BSTR* Get user name
User In BSTR Set user name
Level Out IadsThresholdLevel* Get Threshold Level
Level In IadsThresholdLevel Set Threshold Level
AnalysisWindowName Out BSTR* Get property bag
AnalysisWindowName In BSTR Set the property bag
DisplayType Out BSTR* Get property bag
DisplayType In BSTR Set the property bag
ParameterName Out BSTR* Get property bag
ParameterName In BSTR Set the property bag
IrigTimeAtBreak Out BSTR* Get IRIG time at threshold break
IrigTimeAtBreak In BSTR Set IRIG time at threshold break
ValueAtBreak Out double* Get value at time break
ValueAtBreak In double Set IRIG time
DisplayName Out BSTR* Get display name
DisplayName In BSTR Set the display name
Comment Out BSTR* Get the comment
Comment In BSTR Set a comment
PropBag Out BSTR* Get property bag
PropBag In BSTR Set the property bag
Selections Collection
Method Return Arguments Description
Count Out long* Gets the number of ISelection Items within the collection.
Add In BSTR Add a new ISelection Item to this collection by parameter
name
In BSTR IRIG time of selection.
In Double Value of selection
Out ISelection** Return value reference to the newly added ISelection Item.
Selection Item
Method Return Argument Description
Group Out BSTR* Get the group name
Group In BSTR Set the group name
SubGroup Out BSTR* Get subgroup name
SubGroup In BSTR Set subgroup name
User Out BSTR* Get user name
User In BSTR Set user name
IrigTime Out BSTR* Get IRIG Time
IrigTime In BSTR Set IRIG Time
Value Out double* Get Selection Value
Value In double Set Selection Value
Parameter Out BSTR* Get Parameter name
Parameter In BSTR Set Parameter Name
Filter Out BSTR* Get Filter
Filter In BSTR Set Filter
Display Out BSTR* Get Display Name
Display In BSTR Set Display Name
Comment Out BSTR* Get Comment
Comment In BSTR Set Comment
PropBag Out BSTR* Get property bag
PropBag In BSTRS Set the property bag
TestPoints Collection
Method Return Arguments Description
Count Out long* Gets the number of ITestpoint Items within the collection.
Add In BSTR Add a new ITestpoint Item to this collection by test point string.
In BSTR The start time of the test point
In BSTR The stop time of the test point
Out ITestpoint** Return value reference to the newly added ITestpoint Item.
Remove In VARIANT Remove ITestpoint Item by index or name from this collection
RemoveAll None VOID Remove all ITestpoint Items from this collection.
Item In VARIANT Return an IThreshold Item by name (string) or index number
(0..Count). IndexOrName
Out IThreshold** Return value, reference to the specified IThreshold Item. Returns
the Item by name (string) or index number (0..Count)
SaveTable None VOID Save changes to this Collection
TestPoint Item
Method Return Argument Description
Group Out BSTR* Get the group name
PlannedTestPoints Collection
Method Return Arguments Description
Count Out long* Gets the number of IPlannedtestpoints Items within the
collection.
Add In BSTR Add a new IPlannedTestpoint Item to this collection by
unique testpoint string
Out IPlannedTestpoint** Return value reference to the newly added
IPlannedTestpoint Item.
Remove In VARIANT Remove IParameterSet object by index or name from
this collection
RemoveAll None VOID Remove all IParameterSet Items from this collection.
Item In VARIANT Return an IParameterSet Item by name (string) or
index number (0..Count). IndexOrName
Out IParameterSet** Return value, reference to the specified IParameterSet
Item. Returns a Set object by name (string) or index
number (0..Count)
SaveTable None VOID Save changes to this Collection
PlannedTestPoint Item
Method Return Argument Description
Group Out BSTR* Get the group name
Group In BSTR Set the group name
SubGroup Out BSTR* Get subgroup name
SubGroup In BSTR Set Subgroup name
User Out BSTR* Get User name
User In BSTR Set User name
Testpoint Out BSTR* Get Testpoint
Testpoint In BSTR Set Testpoint (This is a user defined format)
Description Out BSTR* Get Description
Description In BSTR Set Description
Maneuver Out BSTR* Get Maneuver name
Maneuver In BSTR Set the Maneuver name
AircraftConfig Out BSTR* Get the Aircraft Configuration (This is a user defined
setting)
shown above. Note usage of the list type. This will create a dropdown list in the
configuration tool for easier user entry.
10) Delete * from BogusDesktops where Group = 'Flutter' - Delete every row from the
BogusDesktops table where the field value is Flutter
11) Delete * from BogusDesktops where System.RowNumber = 3 - Delete using "built-in"
unique system id or row number
functionality another feature of the data source should be to allow reconnections from the IADS
Server without having to restart the data source application.
Handshake Protocol
Upon initial connection to the data source, the IADS Server expects to receive two
handshake messages describing aspects of the data source environment. First a one-byte message
is expected that defines the byte order of all subsequent messages. The codes to specify the byte
order are as follows:
Little Endian = 1
Big Endian = 2
Secondly a four-byte message is expected defining the code of the format of all
subsequent data packets. The data packets must not vary from this specified format and must also
conform to formatting specifications as defined in the next two sections. There are currently two
supported packet formats with the following codes:
Tag/value pair format = 100
Tag/size/value format = 101
Note: Tag/size/value format only supports Little Endian byte order.
Data Packet Header Format
Each data packet from the data source has a header that contains various record and status
information followed by a body that contains tag/value pairs. Each header contains 8 32-bit
fields (32 bytes) described as follows:
Field Name Description
Field 0 Message Size Total size of header and body (Field 0 non-inclusive)
Field 1 Sequence Number Message sequence counter
Field 2 Packets Sent Total number of data packets sent to IADS Server
Field 3 Data loss/Overflow Total number of data loss/overflow occurrences
Field 4-7 Dummy Currently unused fields
Except for field 0 (Message Size) and field 1 (Sequence Number) all other fields are
essentially unused or optional fields used to describe additional data source status.
Calculating the Message Size field consists of adding the remaining portion of the header
(28 bytes) to the entire size of the packet body. For example, if the packet body size is 1200
bytes then the Message Size field should contain the value 1228.
See Appendix C for a block diagram of the message format including the header.
Data Packet Body Format
Currently there are two supported data packet body formats. The first packet body format
(code 100) contains sets of tag/value pairs consisting of 16-bit tag fields and 32-bit value fields.
A tag is an integer that uniquely identifies a particular parameter. The values are the data
associated with each tag instance. The format of a single tag/value pair in 32-bit form is as
follows:
Tag1 (16-bit)
Tag2 (16-bit)
Value1 (32-bit)
Value2 (32-bit)
The body consists of (n) consecutive sets of these tag/value pairs. Therefore, the size of
each message will consist of 28 bytes of header (message size field is non-inclusive) plus (n)
times 12 bytes of body. This also means there are a total of (n) times 2 parameters per message.
The second supported packet body format (code 101) contains sets of tag/size/value sets
consisting of 32-bit fields containing the integer parameter identifier followed by the data unit
size in bytes followed by the data value. The format of a single tag/size/value set is as follows:
Tag (32-bit)
Size (32-bit)
Value (number of bytes specified in Size field)
The body consists of (n) consecutive sets of these tag/size/value sets. Therefore, the size
of each message will consist of 28 bytes of header (message size field is non-inclusive) plus (n)
times (8 + size) bytes of body where size is the size in bytes of the data associated with each
particular tag. Currently this interface does not support variable size data for a particular tag.
This also means there are a total of (n) parameters per message.
See Appendix C for a block diagram of the supported message formats.
Packet Content Notes
A primary requirement for parameters contained within the stream of data packets is that
the order of the data samples coming out of the data source be chronological (time sequential) for
a particular parameter. Each periodic parameter (i.e. parameter with sample rate greater than 0) is
expected to have a consistent interval (with allowances for some minor rubber-banding) in the
data stream correlating to the sample rate specified in the parameter definition file. No pre-
alignment of data across parameters is assumed (i.e. no manipulation of the data is required prior
to entering IADS).
Time parameters are required to be part of the data stream. Ideally the sample rate of the
time parameters should be greater than or equal to the highest sample rate of the data parameters.
The time words should be interleaved in the data packets such that each sample of a particular
data parameter has a unique time stamp. The following is an example that illustrates a valid
time/data sequence inside a packet where P1 and P2 are samples from 2 different data parameters
and P2 is half the rate of P1. T1 and T2 are the upper and lower words respectively from the time
parameter (see the section on “Time Parameters” below for more detail on time word format):
T1/T2/P1/T1/T2/P1/P2/T1/T2/P1/T1/T2/P1/P2/T1/T2/P1/T1/T2/P1/P2…
Low sample rates on time parameters can have side effects. Since IADS is basically a
data driven system the update rates of the IADS Client displays can be affected by the sample
rate of the time parameters. Time parameter rates lower than about 50 samples per second may
show a ‘stuttering’ behavior on the client displays. See the section on “Time Parameters” below
for more detail on time parameters.
BLOB data can be identified as binary data of any size aligned on byte boundaries.
There is also extended information that can be added to parameter definition entries. The
general format of these extended entries is as follows:
Key = Value
Key is a reserved keyword that is recognized by the IADS Server to represent a specific
piece of parameter information and Value is the value associated with the keyword. Currently
there are two supported extended information keywords: “DataSize=n” and “SystemParamType
= type” the latter of which is described further in Section 7.1.3.
Currently the IADS Server does not support variable sized samples within a single tag.
See Appendix D for an example Parameter Definition file.
System Parameters
Following are parameters needed for the IADS Server to fully operate properly. These are
system-based parameters used for processing other data parameters or for presenting status
information. There are two types of system parameters, time parameters and decom status
parameters. Time parameters are required to be included as part of the overall parameter set but
decom status parameters are optional. The following subsections describe these parameter types:
Time Parameters
Time is represented as a 64-bit word in units of nanoseconds consisting of the time offset
from the beginning of the year. As an example, if IRIG time is set at 001:01:00:00.000 then the
64-bit time value would be 3600000000000 (i.e. one hour offset from the beginning of the year).
The protocol required to transfer time via the data packets consists of splitting the time word into
two 32-bit words. The upper 32-bit word must be identified in the parameter definitions file by
appending the SystemParamType = MajorTime to the entry of the parameter to be used as the
high order time word. The lower 32-bit word must be identified by appending SystemParamType
= MinorTime to the parameter definition file entry of the parameter to be used as the low order
time word. The sequence of the time words in the packet should be the upper time word followed
by the lower time word. See the data flow example in the previous section “Packet Content
Notes” where the upper word is represented as T1 and the lower word is represented as T2.
Ideally the sample rate of the time parameters should be greater than or equal to the
highest sample rate of the data parameters. The time words should be interleaved in the data
packets such that each sample of a particular data parameter has a unique time stamp.
Low sample rates on time parameters can have side effects. Since IADS is basically a
data driven system the IADS Client display update rates can be affected by the sample rate of the
time parameters. Time parameter rates lower than about 50 samples per second may show a
‘stuttering’ behavior on the client displays.
4 Param3 50.0 2
5 Param4 50.0 2
6 TimeUpperWord 1000.0 1 SystemParamType = MajorTime
7 TimeLowerWord 1000.0 1 SystemParamType = MinorTime
is typical of decom-based systems. This provides a more complex example showing how to
populate packets using differing sample rates. To setup a project for build, the
IadsDS_DecomStyle.cpp should be the only cpp file where the Excluded From Build
property is set to No. The parameter definition file associated with this program is named
IadsDS.prn.DecomStyle and located in the main project directory. Note that this program
applies packet format 100 (tag/tag/value/value).
3) Blob Style (IadsDS_BlobStyle.cpp) - This program sends one Blob parameter along with
time words to the IADS Server. The Blob parameter contains four floating point parameters.
To setup a project for build, the IadsDS_BlobStyle.cpp should be the only cpp file where the
Excluded From Build property is set to No. The parameter definition file associated with this
program is named IadsDS.prn.BlobStyle and located in the main project directory. Note that
this program applies packet format 101 (tag/size/value).
7.1.3 Testing the data source using IADS Real Time Station
To test the data source interface, we recommend using the IADS Real Time Station (RT
Station) product in order to perform communication protocol and data flow verification
activities. RT Station is an installable application that includes both the IADS Server and IADS
Client display subsystems so that data from the data source program can be delivered and viewed
in IADS.
The RT Station installation package is available either by purchasing the product from
Curtiss Wright (Part numbers are IADS-TELEM-RTSTATION-1 or IADS-TELEM-BASE-TPP)
or by requesting the IADS Data Source Developers Kit (IADS-TELEM-DEV)
Running RT Station
Running RT Station brings up a start wizard that will guide you through the process of
selecting setup information that describes how to connect to the data source program and specify
the parameter definition file. The startup steps are as follows:
1) Make sure the data source program is running and waiting to connect to IADS.
2) Double click the IADS Real Time Station icon on the Windows desktop.
3) On the Choose Data Source page select the IADS Custom option from the dropdown menu
in the Data Source field. Click Next to continue.
4) On the Choose Data Host page enter the name or IP address of the computer running the data
source program in the Host Name entry. This can be entered manually or selected via the
browse button on the right of the entry. The PortId entry defaults to 49000 which is the initial
setup in the example data source program. This field can be edited to specify the port id that
is available on the data source for connection. Click Next to continue.
5) On the Choose PRN File page select the parameter definition file that contains the parameter
specifications of the data source output. There is a browse button available on the right of the
entry to assist in locating the file. If you are running one of the sample programs the
matching parameter definition files are in the IADS Data Source project location. Click Next
to continue.
6) On the Choose Data Directory page select the destination folder for your IADS data storage
files. A browse button is available on the right of the entry to assist in locating the directory.
Click Next to continue.
7) On the Choose IADS Config File page select the Create new Config file option. This will
automatically create a new IADS Configuration File from scratch that contains the
parameters specified in the parameter definition file you selected earlier in the wizard. Click
Next to continue.
8) On the Start Data Acquisition page review the settings and click Finish to start IADS.
At this point RT Station will connect to the data source and start ingesting and processing
data packets. The IADS Client application will then be launched and you will be prompted to
startup the client via the IADS Log On dialog. Select the predefined user name User1 and
desktop name Desktop1 then click the Log On button (This step is automatic if User1 and
Desktop1 are the only options.) This user and desktop setup contains a blank Analysis
Window (Window1) which acts as a palette for data displays to be added.
2) On the Display Builder dialog click the Data Displays tab. A selection of display types is
presented.
3) On the Data Displays tab click on the Vertical Stripchart icon then hold down the left
mouse button and drag onto Window1. This will create a new instance of a Stripchart display
inside the window.
2) On the Parameter Tool select a parameter then hold down the left mouse button and drag
onto the Stripchart display. Select Value in the popup options after dropping the parameter
onto the display (i.e. releasing the left mouse button).
The following are example windows showing data from the three sample programs contained
in the IADS Data Source project:
Simulator Style
Decom Style
Blob Style
More detail on display types and general client functionality can be found in the IADS
Client Help system which can be accessed via the lower right-most button on the Dashboard.
7.1.4 Troubleshooting
Validating Time
When the IADS Server connects to the data source and starts receiving packets it goes
through a brief period of verifying that time parameter values are increasing at the expected
increment. A common problem with a new data source interface is that the IADS Server may not
successfully validate time during startup because the time values are not increasing at an
increment based on the time word sample rate. For example, if the rate of the time parameter is
1000 samples per second the IADS Server will expect time value increments of 1 millisecond per
sample. Any time decrements or increments over 2x the expected rate will cause a validation
failure. If time does not successfully validate a dialog containing possible reasons for failure will
pop up as follows:
also valuable for obtaining more detail on invalid time sequence errors (see reason 2 above). An
example format of the “timeOut0.txt” file is as follows:
001:00:00:00.020 (86400020000000)
001:00:00:00.040 (86400040000000)
001:00:00:00.060 (86400060000000)
001:00:00:00.080 (86400080000000)
001:00:00:00.100 (86400100000000)
The 1st column is the IRIG representation of the time values and the 2nd column is the
64-bit integer representation of the values (in nanoseconds). In this example the time is
incrementing by 20 milliseconds per sample which should correspond to a 50 sample per second
rate for the time parameters specified in the parameter definitions file
For further troubleshooting assistance please zip up the entire Logs folder located in the
IADS data directory and send to [email protected] to help in analyzing the issue.
Connection Information
Field Entry/Selection
Connection Port 58003
Connection Type TCP/IP
Protocol Overview
• Fixed length message packet of 2000 ASCII characters
• Client performs a send on the socket of the full 2000 characters regardless of the message
type
• The IADS Commander server performs the function and sends back a status string
• Client performs a receive on the socket to retrieve the response message
• Argument strings cannot contain spaces
CreateProcess
Description: Create a process on a local or remote computer.
Behavior: The IADS Commander will run the process given the process name (not
recommended) or the PID if the process name is empty.
Request Message
“Message: CreateProcess\nProcessName: \nArguments: \nWorkingDirectory: \n”
Request Message Arguments
Arg1 (ProcessName) – Full path and name of the process.
Arg2 (Arguments) – User specified arguments passed to the process.
Arg3 (WorkingDirectory) – Windows will start the process with this as its working directory.
Response Messages
1 "Message: Acknowledge\nProcessStatus: Stopped\n”
2 "Message: Acknowledge\nProcessStatus: Running\nPID: \n”
TerminateProcess
Description: Terminate a process on a local or remote computer. Use of the PID argument is
recommended.
Behavior: The Commander will hard terminate the process specified by the process name (not
recommended) or the PID. Be careful with this call because it kills the process without notifying
it.
Request Message
“Message: TerminateProcess\nPID: \nProcessName: \nExitCode: \n”
Request Message Arguments
Arg1 (PID) – Kill process by the process ID.
Arg2 (ProcessName) – Kill Process by Process name (use caution with duplicate running
processes).
Arg3 (ExitCode) – User specified arguments passed to the process.
Response Messages
1 "Message: Acknowledge\nProcessStatus: Stopped\n
2 "Message: Acknowledge\nProcessStatus: Running\nPID: \n
ForwardMessage
Description: Send a message from the currently connected Commander to another running on a
different computer.
Behavior: The Commander will forward the message onto the Commander running on the
remote computer specified by the Host argument.
Request Message
“Message: ForwardMessage\nHost: \nRemoteMessage: \n”
Request Message Arguments
Arg1 (Host) – Host with running commander to forward the message to.
Arg2 (RemoteMessage) – Message to forward.
Response Messages
1 "Message: Acknowledge\nForwardMessage: %s\n”
2 - Error "Message: Acknowledge\nForwardMessage: Unable to Parse Message\n”
ProcessStatus
Description: Determine if a process is running on a remote machine. Use of the PID argument is
highly recommended.
Behavior: If the ProcessName argument is empty, the PID argument is used to identify the
process.
Request Message
“Message: ProcessStatus\nHost: \nRemoteMessage: \n”
Request Message Arguments
Arg1 (ProcessName) – Name of the process to get status on. Use Caution with this argument
because multiple versions of the same application may be running.
Arg2 (PID) – Process ID of the process to get status on.
Response Messages
1 "Message: Acknowledge\nProcessStatus: Running\nVER: 1\n”
2 "Message: Acknowledge\nProcessStatus: Stopped\nVER: 1\n”
3 "Message: Acknowledge\nNumRet: \n”
4 - Error “Message: Acknowledge\nProcessStatus: Unknown Process”
5 -Error "Message: Acknowledge\nProcessInfo: PID is invalid\n”
6 - Error "Message: Acknowledge\nProcessSearch: Unknown ProcessName\n”
ProcessSearch
Description: Find all processes given a process name and return the PID and Command line
arguments for each.
Behavior: The Commander will search the process table for all occurrences of the process name.
Request Message
“Message: ProcessSearch\nProcessName: \n”
Request Message Arguments
Arg1 (ProcessName) – Name of the process to get status for. Use Caution with this argument
because multiple versions of the same application may be running.
Arg2 (PID) – Process ID of the process to get status on.
Response Messages
1 "Message: Acknowledge\nNumRet: 0\n”
2 "Message: Acknowledge\nNumRet: \nCmdArgs%d: \n\nPID%d: \n”
3 - Error “Message: Acknowledge\nProcessSearch: Unknown ProcessName\n”
TransferFile
Description: Transfer a file from one computer to another.
Behavior: Transfers configuration and various startup files.
Request Message
“Message: TransferFile\nNameAndPath: \nFileSize: \n”
Request Message Arguments
Arg1 (NameAndPath) - The location to write the file on the destination machine.
Arg2 (FileSize) - The total file size that will be transferred.
Response Messages
1 "Message: Acknowledge\nTransferStatus: Success creating file\n"
2 "Message: Acknowledge\nTransferStatus: Success transferring file\n"
3 - Error "Message: Acknowledge\nTransferFile: FileName is empty\n"
4 - Error "Message: Acknowledge\nTransferFile: FileSize is Empty\n"
5 - Error "Message: Acknowledge\nTransferStatus: File Size is less than or equal to zero\n"
6 - Error "Message: Acknowledge\nTransferStatus: Error creating file\n"
7 - Error "Message: Acknowledge\nTransferStatus: Unable to allocate file transfer buffer\n"
8 - Error "Message: Acknowledge\nTransferStatus: Unable to Recv file transfer buffer\n”
9 - Error "Message: Acknowledge\nTransferStatus: Error transferring file\n"
WritePermission
Description: Get the file permission for the given file.
Behavior: The Commander will return the permission of the given file.
Request Message
“Message: WritePermission\nNameAndPath: \n"
Request Message Arguments
Arg1 (NameAndPath) – Absolute file name and path. Please note that the entire message is
limited to 2000 characters.
Response Messages
1 "Message: Acknowledge\nWritePermission: ReadOnly\n"
2 "Message: Acknowledge\nWritePermission: Writeable\n”
3 - Error "Message: Acknowledge\nWritePermission: Filename is empty\n"
TempPath
Description: Get the Windows temporary path for a remote machine.
Behavior: The Commander will return the Windows temporary path for the remote computer.
Request Message
“Message: TempPath\n”
Request Message Arguments
None
Response Messages
1 "Message: Acknowledge\nTempPath: <temporary path>\n"
SystemInfo
Description: Get certain Windows system information.
Behavior: The Commander will return certain system information for the remote computer.
Request Message
“Message: SystemInfo\n”
Request Message Arguments
None
Response Messages
1 " Message: Acknowledge\nSystemInfo: <disk size> <disk free> <total memory> <total
memory used> <total physical memory> <physical memory used> <number of CPUs>
<space separated list of CPU percentages>n"
ProcessInfo
Description: Get certain Windows process information.
Behavior: The Commander will return the percentage CPU used for the process given the
process name (not recommended) or the PID if the process name is empty.
Request Message
“Message: ProcessInfo\n"
Request Message Arguments
None
Response Messages
1 "Message: Acknowledge\nProcessStatus: Stopped\n”
2 "Message: Acknowledge\nProcessInfo: <percentage cpu used>\n”
3 - Error "Message: Acknowledge\nProcessInfo: Error with allocation\n”
4 - Error "Message: Acknowledge\nProcessInfo: Process name is empty\n”
5 - Error "Message: Acknowledge\nProcessInfo: PID is invalid\n”
PathIsDirectory
Description: Check if the path sent from the Client is an actual path on the remote machine.
Behavior: The Commander will return True if the path string sent by the Client is an actual path
on the remote machine, otherwise False.
Request Message
“Message: "Message: PathIsDirectory\nPath: \n”
Request Message Arguments
Arg1 (Path) – The path string to verify on the remote machine.
Response Messages
1 "Message: Acknowledge\nPathIsDirectory: True\n”
2 "Message: Acknowledge\nPathIsDirectory: False\n”
3 - Error "Message: Acknowledge\nPathIsDirectory: Invalid Path\n”
MakeDirectory
Description: Create the directory given the path sent from the Client.
Behavior: The Commander will return Success if the path was created on the remote machine,
otherwise Failure.
Request Message
"Message: MakeDirectory\nPath: \n”
Request Message Arguments
Arg1 (Path) – Path string to of directory to create on the remote machine.
Response Messages
1 "Message: Acknowledge\nMakeDirectory: SUCCESS\n”
2 "Message: Acknowledge\nMakeDirectory: FAILURE\n”
3 - Error "Message: Acknowledge\nMakeDirectory: Invalid Path\n”
DirectoryHasData
Description: Check if the path sent from the Client already contains IADS data.
Behavior: The Commander will return True if the Path has data contained within in it, otherwise
False.
Request Message
“Message: DirectoryHasData\nPath: \n”
Request Message Arguments
Arg1 (Path) – Path string of directory to create on the remote machine.
Response Messages
1 "Message: Acknowledge\nDirectoryHasData: True\n”
2 "Message: Acknowledge\nDirectoryHasData: False\n”
3 - Error "Message: Acknowledge\nDirectoryHasData: Invalid Path\n”
GetNextFreeDirectoryName
Description: The Commander will return a sequential backup directory name.
Behavior: The Commander will check the file system for the next available directory with a
number appended to the name.
Request Message
“Message: GetNextFreeDirectoryName\nPath: \n”
Request Message Arguments
Arg1 (Path) – Path string of directory to create on the remote machine.
Response Messages
1 "Message: Acknowledge\nGetNextFreeDirectoryName: <next free directory name>\n”
2 "Message: Acknowledge\nGetNextFreeDirectoryName: FAILURE\n”
3 - Error "Message: Acknowledge\nGetNextFreeDirectoryName: Invalid Path\n”
FileExists
Description: The Commander will check if the file already exists on the remote machine.
Behavior: The Commander will check the existence of the file sent from the Client on the remote
computer.
Request Message
“Message: FileExists\nPath: \n"
Request Message Arguments
Arg1 (File) – File name and path to check for existence on the remote machine.
Response Messages
1 "Message: Acknowledge\nFileExists: TRUE\n”
2 "Message: Acknowledge\nFileExists: FALSE\n”
3 - Error "Message: Acknowledge\nFileExists: Unable to determine if file specified\n”
exit( 1 ) ;
}
printf("- Client Connected...\n\n" ) ;
Setup Information
Field Entry/Selection
Connection Port 58001
Connection Type TCP/IP
Protocol
• Client performs a send on the socket
• The CDS Command Server performs the function and sends back a response message
• Client performs a receive on the socket to retrieve the response message
• The CDS does not guarantee a response message to be null terminated.
Archiving
StartDataArchiving Start data archiving
StartDataArchivingWithAppend Start data archiving with append
StopDataArchiving Stop data archiving
ResetDataArchiving Reset data archiving
ResetDataArchivingWithAppend Reset data archiving with append
IsDataArchiving Return data archiving status
Nulling
StartAircraftNulling Start aircraft nulling
IsAircraftNulling Return aircraft nulling status
StartWeaponsBayNulling Start weapons bay nulling
IsWeaponsBayNulling Return weapons bay nulling status
Data Compression
StartDataCompression Start data compression
IsDataCompressionRunning Return state of process
GetDataCompressionStatus Return data compression status
GetDataCompressionError Return information from the process
StopDataCompression Stop data compression
Shutdown
Shutdown Shutdown CDS
Run State
GetCdsStartInfo Return status of CDS start command
GetCdsStopInfo Return status of CDS stop command
GetPredictedAggRate Return predicted aggregate rate
Data Source Information
GetSys500Info Not yet documented
GetSys500DecomStatus Not yet documented
GetOmegaInfo Return Omega information
GetOmegaDecomStatus Return Omega decom status
GetVistaInfo Not yet documented
GetVistaDecomStatus Not yet documented
GetS6200 Not yet documented
GetS6200DecomStatus Not yet documented
GetMCSInfo Not yet documented
GetMCSDecomStatus Not yet documented
GetCustomDSInfo Not yet documented
GetCustomDSDecomStatus Not yet documented
GetDataInterfaceInfo Not yet documented
GetDecomStatus Not yet documented
StartConnectTest
Description: Command the CDS to begin a connect test to the upstream data source computer.
Behavior: The CDS will send a response message before the connect test is initiated. A failure
condition is triggered if the CDS had already initiated a connect test in the past when the
command is received. This message is not necessary for the CDS to successfully run.
Subsequently use the “IsCdsDataSourceConnectTestComplete” to determine the state of the
connect test.
Request Message
“StartConnectTest”
Response Messages
1 "StartConnectTest ok”
2 - Error "StartConnectTest failure Connect Test is already running”
IsCdsDataSourceConnectTestCompleted
Description: Check if a CDS connect test has been completed.
Behavior: The CDS will send a response message of true if the connect test has completed,
otherwise false.
Request Message
"IsCdsDataSourceConnectTestCompleted"
Response Messages
1 “IsCdsDataSourceConnectTestCompleted ok <true, false>”
GetCdsDataSourceConnectTestInfoString
Description: Get information on the results of the CDS connect test.
Behavior: The CDS will send a response message with information about the connect test that
was performed. Use this to obtain more detail on the connect test results.
Request Message
"GetCdsDataSourceConnectTestInfoString"
Response Messages
1 “GetCdsDataSourceConnectTestInfoString ok <information string>”
2 “GetCdsDataSourceConnectTestInfoString ok NULL”
GetCdsDataSourceConnectTestResult
Description: Get information on the results of the CDS connect test.
Behavior: The CDS will send a response message with results on the connect test that was
performed. Use this after sensing the connect test has completed to determine whether the
connect test succeeded (true) or failed (false) along with additional information upon failure.
Request Message
"GetCdsDataSourceConnectTestResult"
Response Messages
1 “GetCdsDataSourceConnectTestResult ok false <code> <failure result string>”
2 “GetCdsDataSourceConnectTestResult ok <true, false>”
Note: Response message 2 can be false only if command is sent prior to completion of connect
test.
GetCdsDataSourceConnectTestResult message process:
1) The Client sends the GetCdsDataSourceConnectTestResult message.
2) The CDS receives the message and returns the connect test result string.
3) The Client receives the message.
GetCdsInitInfo
Description: The Client sends this command to retrieve CDS initialization state information,
specifically status on initialization completion and success.
Behavior: The CDS will send an ok token followed by two value strings of either “true” or
“false”. The first specifies status on initialization completion and the second states the
initialization success result.
Request Message
"GetCdsInitInfo"
Response Messages
1 “GetCdsInitInfo ok <true, false> <true, false>” Example: “GetCdsInitInfo ok true true”
GetCdsInitInfoString
Description: The Client sends this command to retrieve the CDS initialization information string.
This may provide more detail on the results of the initialization performed.
Behavior: The CDS will send an ok token followed by either a NULL string if nothing is
available or the information string.
Request Message
"GetCdsInitInfoString"
Response Messages
1 “GetCdsInitInfoString ok <Information string>”
2 “GetCdsInitInfoString ok NULL”
StartConfigValidationFromFile
Description: Start the configuration validation process.
Behavior: The CDS will send an Ok or Failure Response message immediately upon receipt of
this command. A failure condition is triggered when the CDS is already in an active data
acquisition state when the command is received. Additional messages will need to be sent to
query validation state and results. This step is mandatory in order for the CDS to operate
properly.
Request Message
“StartConfigValidationFromFile”
Response Messages
1 “StartConfigValidationFromFile ok”
2 - Error “StartConfigValidationFromFile failure CDS currently running”
IsValidationComplete
Description: The Client sends this command to check the completion state of the config
validation process.
Behavior: The CDS will send an Ok string followed by a true or false string depending if the
validation is complete or not.
Request Message
“IsValidationComplete”
Response Messages
1 “IsValidationComplete ok <true, false>”
GetConfigValidateInfo
Description: The Client sends this command to retrieve status whether the CDS has successfully
performed validation.
Behavior: The CDS will send an Ok string followed by a true or false string depending if the
config successfully validated or not.
Request Message
“GetConfigValidateInfo”
Response Messages
1 “GetConfigValidateInfo ok <true, false>”
GetValidationStatusString
Description: The Client sends this command to retrieve the result string from the validation
process. Typically, this is used to obtain additional information when validation failures occur.
Behavior: The CDS will send an Ok string followed by either NULL if no status string is
available or the validation string.
Request Message
“GetValidationStatusString”
Response Messages
1 “GetValidationStatusString ok <status string>”
2 - Error “GetValidationStatusString ok NULL”
Request Message
“RestartCds”
Response Messages
1 “RestartCds ok”
2 - Error “RestartCds failure Data is already running”
created using the original name populated with the archive support files from the original folder
and new archive data files will be created.
Behavior: The CDS will send an Ok token with nothing following on success otherwise a failure
token is sent. The CDS will send the response message before the reset is initiated in order not to
block the requestor. A failure condition is triggered if the CDS is not in an active data acquisition
state when the command is received.
Request Message
“ResetCdsWithSave”
Response Messages
1 “ResetCdsWithSave ok”
2 - Error “ResetCdsWithSave failure Data is already running”
Message Process:
1) The Client sends the “ResetCdsWithSave” message.
2) The CDS receives the message and returns a response before initiating the reset.
3) The Client receives the message.
ResetCdsWithoutSave
Description: The Client sends this command to perform a CDS reset. On a reset the CDS stays in
a running state but suspends the data acquisition connection while flushing all data to disk
following by resuming the data acquisition process and reapplying time validation. Config file
validation is not performed. The currently saved data will be discarded and the archive files will
be truncated.
Behavior: The CDS will send an Ok token with nothing following on success otherwise a failure
token is sent. The CDS will send the response message before the reset is performed in order to
not block the requestor. A failure condition is triggered if the CDS is not in an active data
acquisition state when the command is received.
Request Message
“ResetCdsWithoutSave”
Response Messages
1 “ResetCdsWithoutSave ok”
2 - Error “ResetCdsWithoutSave ok failure Data is already running”
validation is not performed. All subsequent data archiving will be appended to the existing
archive files.
Behavior: The CDS will send an Ok token with nothing following on success otherwise a failure
token is sent. The CDS will delay sending the response message until after the reset is completed
blocking the requester in the process. A failure condition is triggered if the CDS is not in an
active data acquisition state when the command is received.
Request Message
“ResetCdsWithAppendBlocked” (Reset performed before response)
Response Messages
1 “ResetCdsWithAppendBlocked ok”
2 - Error “ResetCdsWithAppendBlocked failure Data is already running”
ResetCdsWithoutSaveBlocked
Description: The Client sends this command to perform a CDS reset. On a reset the CDS stays in
a running state but suspends the data acquisition connection while flushing all data to disk
following by resuming the data acquisition process and reapplying time validation. Config file
validation is not performed. The currently saved data will be discarded and the archive files will
be truncated.
Behavior: The CDS will send an Ok token with nothing following on success otherwise a failure
token is sent. The CDS will send the response message after the reset is performed blocking the
requestor in the process. A failure condition is triggered if the CDS is not in an active data
acquisition state when the command is received.
Request Message
“ResetCdsWithoutSaveBlocked”
Response Messages
1 “ResetCdsWithoutSaveBlocked ok”
2 - Error “ResetCdsWithoutSaveBlocked failure Data is already running”
Response Messages
1 “GetCdsDataGatherInfoString ok <information string>”
2 “GetCdsDataGatherInfoString ok NULL”
Request Message
“GetCdsTimeValidationInfoString”
Response Messages
1 “GetCdsTimeValidationInfoString ok NULL”
2 “GetCdsTimeValidationInfoString ok <information string>”
ResetDataArchiving
Description: This commands the CDS to stop data archiving followed by restarting data
archiving. Any saved data will be discarded and the archive data files will be truncated.
Behavior: The CDS will send an “ok” token after data archiving has been fully stopped and the
restart of data archiving has been initiated.
Request Message
“ResetDataArchiving”
Response Messages
1 “ResetDataArchiving ok Data archiving is now active”
Message Process:
Description: This commands the CDS to start Weapons Bay nulling. The CDS will collect 15
seconds worth of data for all parameters within the Weapons Bay nulling group, compute the
average value over that time span then calculate the bias based on the difference between the
baseline and average values and update the config with the results.
Behavior: The CDS will send an “ok” token on success otherwise a failure token is sent. The
CDS will send the response after initiating the nulling process in order to not block the requestor.
A failure condition is triggered if the CDS is unable to initiate the nulling process due to system
error.
Request Message
“StartWeaponsBayNulling”
Response Messages
1 “StartWeaponsBayNulling ok Nulling sequence is now started”
2 - Error “StartWeaponsBayNulling failure Nulling sequence could not be started”
Response Messages
1 “StartDataCompression ok Starting”
2 - Error “StartDataCompression failure Already Running”
Description: This command will cause the CDS to return the data compression error string.
Behavior: The CDS will return a “True” token followed by the error string if an error did occur;
otherwise a “False” token is sent indicating no error.
Request Message
“GetDataCompressionError”
Response Messages
1 “GetDataCompressionError ok True <Error String>”
2 “GetDataCompressionError ok False”
2) The CDS sends a response message before shutting down and exiting.
3) The Requestor receives the message.
Request Message
“GetPredictedAggRate”
Response Messages
1 “GetPredictedAggRate ok <Predicted Aggregate Rate>”
Description: This commands the CDS to return the total number of decom status streams as
defined by the upstream data sources.
Behavior: The CDS will return an “ok” token followed by the number of decom status streams.
Data Source Specific: Not currently
Request Message
“GetNumDecomStreams”
Response Messages
1 “GetNumDecomStreams ok <Total decom status streams>”
exit( 1 ) ;
}
char responsee[500] ;
delete clientSocket;
Undocumented Messages
Message Description
StartStatistics Not released
StopStatistics Not released
IsStaticsOn Not released
IsStaticsConnected Not released
GetParameterStatOverflows Not released
GetBeloBoxInfo Obsolete
GetBeloBoxDecomStatus Obsolete
IADS CDS:
Argument
/startupFile FILEPATH
For example:
/startupFile ….\IADS\ComputeDataServer\CDS.ComputeDataServer.iadsStartupFile
7.3.1 Overview
The CdsStress kit is available for download on the Curtiss Wright IADS website at
https://iads.symvionics.com/support/programming-examples/ Data Processing Examples: 3. CDS
Performance Analysis Program and includes:
1) CdsStress.exe - The simulated data source program. It easily allows increasing the data
throughput, the number of parameters and the sample rate mix to efficiently simulate a real-
world data scenario; it automatically creates the IADS Configuration file (the IADS
database) and the CDS parameter definitions (PRN) files used by the CDS.
2) parmInfo.txt -The input file to the CdsStress program for setting up the various data output
rates. This file is edited by the user to set the data throughput rate of the CdsStress program.
3) iadsCDS.init - The input file to set the CDS run-time properties settings.
Note: This kit does not include the IADS Server (ComputeDataServer.exe) or IADS Client
(Iads.exe) executables.
4) Double-click on the shortcut to run the CdsStress program. The IADS Configuration file and
PRN file will output to the CdsFiles directory.
5) Modify the “LOCATION1” property in the iadsCDS.init file to point to the correct data
archive file path.
LOCATION1 = C:/CdsFiles/IadsOutputFiles
POSTFLIGHTCONFIG = C:/CdsFiles/IadsOutputFiles/pfConfig
6) Modify the “DATALOCATION” property to point to the PC that the CdsStress program is
running on (The ”Port Id” does not need to be modified).
DATALOCATION = Pat3600 49000
7) Run the CDS. The CDS uses the property settings in the IadsCds.init file to locate the prn
and config files; and connect to the CdsStress data source program. Enter a “20” on the CDS
screen to validate the IADS Configuration. Once complete, enter a “30” to start real time. If
everything is setup correctly then the CDS will start receiving data and validate time.
The primary test is to run the system and monitor CDS memory usage. Because the CDS is
designed to use memory on a demand basis any overrun conditions are determined by an ever
increasing memory usage on the Server PC which can be monitored by using the Windows
Task Manager. Each test may take up to an hour before memory usage stabilizes.
Another test is to connect an IADS Client to the CDS and examine the IRIG time on the
dashboard with time output of the CdsStress program and verify that they continue to match.
8) Enter a “99” on the CDS menu and the application will shut down. This may take a few
minutes to close the archive files. The CdsStress program will then be ready for another
connect, therefore it can continue to run. However it will need to be re-launched if another
data throughput set is setup in the parmInfo.txt file.
8. Other
8.1 Iadsread Matlab Extension
The iadsread.mexw32 and iadsread.mexw64 MEX-files are included as part of the IADS
installation at \Program Files (x86)\Iads\MatlabExtention. The iadsread function allows you to
programmatically access your IADS archive data so you can write Matlab programs to read in
and process the IADS flight data.
To set the path in Matlab to your IADS Matlab Extension directory:
1) Run Matlab.
2) Click the File drop down > Set Path...
3) In the Set Path dialog, click the Add Folder button.
4) Navigate to C:\ProgramFiles\Iads\MatlabExtention and click OK.
5) Click the Save button.
6) Click the Close button.
To verify the iadsread function is available in Matlab:
In Matlab, enter iadsread in the Command Window. It should respond: ??? iadsread: Minimum
four inputs required. This is correct! The error occurs because the function call arguments are not
complete; follow the instructions below to setup the iadsread function. If ??? Undefined function
or variable 'iadsread' is returned, verify the path you have set and saved in Matlab is the
MatlabExtention directory that contains your iadsread.mexw32/64 or the iadsread.dll. If the error
still occurs, the version of Matlab you are using (pre 7.1) does not recognize the
iadsread.mexw32 file. Rename the iadsread.mexw32 to iadsread.dll. For more information on
this subject go to: http://www.mathworks.com/access/helpdesk/help/techdoc/rn/f26-998197.html
To use the iadsread function:
In Matlab, enter the iadsread function with a required minimum of four inputs (with the
exception of the iadsread( 'DataDirectory' )
Syntax
Variable = iadsread( 'DataDirectory or ServerName$PortId', 'IrigStartTime', 'IrigEndTime' or
NumSeconds, 'ParameterNameList (Comma Separated)', [optional arguments..] )
Examples
Data = iadsread('D:\PostTestData\TestSet','001:00:05:05',5,'AB1001X,AB1002X,AB1003X')
Data =
iadsread('D:\PostTestData\TestSet','001:00:05:05',5,'AB1001X,AB1002X,AB1003X','Decimatio
nFactor',4,'ReturnTimeVector',1)
Notice that all 5 parameters are combined into 1 matrix called Data. That is because only 1
variable was assigned to the result of iadsread, Data = iadsread(...). To create 3 separate vectors,
define the left hand side of the equation as such: [AB1001X,AB1001X,AB1001X] = iadsread(...)
This string defines the end time of the data that you are interested in. The Irig time string format
is DDD:HH:MM:SS.MS Another alternative is to specify a "scalar" number of seconds from the
start time.
Argument 4 - 'Parameter(s) or SQL statement (required)'
This string defines a list of parameter(s), comma separated (with no spaces between the commas)
that you want to import data from. The Parameter name is that defined in the Parameter Defaults
Table.
SQL Statement - 'select <ColumnName or Comma Separated ColumnNames> from
<TableName> where <Conditional Statement>'
The "where <Conditional Statement>" statement is Optional. In this format, the <ColumnName>
and <TableName> refers to the name of the column in any IADS log or table in the
Configuration Tool.
Optional Arguments - Start of Matlab Style (optional settings)
1. 'DecimationFactor', factor 1..N (Defaults to 1 which denotes no decimation). This gives you
the ability to reduce the amount of data from the actual parameter’s update rate. If not
defined, it defaults to 1 (no decimation). The decimation is always based on the largest
sample rate of the parameters defined in Argument 4. For example, if you wanted a matrix of
data that represents half of the original data, you would enter 2. Decimation only removes
data points using a "Decimal Sub-Sample' of your original data (i.e. skips every N points).
No other interpolation method (such as linear or bspline interpolation) is currently used. Be
aware, if you use this option, you do have the possibility of removing data that is important
to your analysis. This argument used in the example is: 'DecimationFactor',4
2. 'OutputSampleRate', sampleRate (Defaults to highest sample rate of parameters chosen.
Trumps DecimationFactor). Similar to Decimation factor above, but specifies the exact
output sample rate desired. For example, 'OutputSampleRate',50
3. 'ReturnDataAtSameSR', 0=False 1=True (Defaults to True) Controls whether the data is
interpreted to same sample rate as defined by DecimationFactor or OutputSampleRate. By
default, the iadsread function "squares off" the data to same sample rate making it easier to
analyze. If this option is set to 0 (False) then each vector is output at its native sample rate
and thus the lengths of each vector may vary. In this state, the interpolation/correlation is left
to the user code.
4. 'ReturnTimeVector', 0=False 1=True (Defaults to False) Controls whether a time vector is
returned along with the data vector(s). The vector contains current time for each element of
the corresponding data vector elements.
5. 'ExceptionOnNoData', 0=False 1=True (Defaults to True). Determines whether iadsread
throws an error/exception if it is unable to get data for a given parameter. If False, returns
empty Vector or if Matrix fills column with NaN.
Note: For additional information on the iadsread function see the Howto.m file at
\ProgramFiles\Iads\MatlabExtention.
Argument 2 - IrigStartTime
This string argument is the start time of the data that you want to import. The format of the string
is IRIG time in the format “DDD:HH:MM:SS.MS” this is a 3 digit day (0-364), a two digit hour
(0-23), a two digit minute (0-59), a two digit second (0-59), and a partial second (MS) up to 9
digits long. This time will most likely be obtained from your flight notes or the IADS
EventMarker Log. This interface also has the ability to supply you with your
TestPoint/Maneuver start/end times for each flight. Let me know if you have any other ideas.
Argument 4 - ParameterNameList
This string argument is a list of comma separated parameter names that you want to import data
from. For example, you could import some aircraft "Wing" parameters by defining a list like:
"AW0001X,AW0002X,AW0003X". Notice the name is the "Parameter" name defined in the
config file's "ParameterDefaults Table" (usually the parameter code)
Note: All filtering and nulling that was set in the ParameterDefaults entry for the specified
parameter is applied before the data is returned to Matlab. Spike detection and wild point
corrections are *not* applied as of this date. We may consider having this as an option.
One more option is being considered for next build: *The DataGroupName option will allow you
to access a group of parameters defined in your config file under the DataGroup table.
StartTime, StopTime, DataDir, FlightId, TestId, TailId. The results inside of the ArchiveInfo
variable is a double dimension array. The first row contains all of the property names (as
described in the last sentence). The second row contains all the values of these properties. Please
recall the VB accesses array using the Array (Row, Column) format, with zero based index
values.
Example:
ArchiveInfo[0][0] is the first row first value (which in this case is the property name
"StartTime")
ArchiveInfo[0][1] is the first row second value (which in this case is the property name
"StopTime")
ArchiveInfo[0][2] is the first row third value (which in this case is the property name
"DataDirectory") etc.. and now for the actual values of these properties for your specific flight...
ArchiveInfo[1][0] is the second row first value (which in my case is the value
"001:00:00:00.000")
ArchiveInfo[1][1] is the second row second value (which in my case is the value
"001:02:00:00.000")
ArchiveInfo[1][2] is the second row third value (which in my case is the value
"D:\PostFlightData\Demo") and so on..
Now, let's say you want to know what parameters are available in an archive... To achieve this,
we put a '?' (Question Mark) in the ParameterList (argument number 4)
My line looks like this > IadsDataInterfaces.iadsread( "D:\PostFlightData\Demo", "", 0, "?" )
(iadsread ignores contents of arguments 2 & 3)
Type the line below into your script editor inserting your own dir into the <Insert Your Data
Directory Here> text
ParameterList = IadsDataInterfaces.iadsread("<Paste Your Data Directory Here>", "", "", "?")
The system should respond with the list of parameters defined in your ParameterDefaults table
ParameterList will be an array of Strings containing all the parameters. In my case:
ParameterList[0] = "DV1"
ParameterList[1] = "IABALT"
ParameterList[2] = "IIIALT"
ParameterList[3] = "IATASP", etc
You can use the UBound and a for loop to iterate though the parameters:
For index = 0 To UBound(ParameterList)
ParamName = ParameterList(index)
Next
Or by using the For Each statement:
For Each Param In ParameterList
ParamName = Param
Next
Another helpful tool is the ability to look at the settings of an individual parameter. It's just a
small difference from the last line. Put a "?" (Question Mark) in the ParameterList (argument
number 4) then a <space> then the parameter name you want more information about... My line
looks like this -> InfoOnIABALT = IadsDataInterfaces.iadsread("D:\PostFlightData\Demo", "",
0, "? IABALT")
iadsread returns an array much like the previous 'ArchiveInfo' above with the first row
containing the 'ColumnName' and the second row containing the actual value of the column.
Again, the array is accessed InfoOnIABALT( Row, Column ) with zero based indices
InfoOnIABALT[0][0] = "ParameterDefaults" InfoOnIABALT[1][0] = "STRUCTURES"
InfoOnIABALT[0][1] = "Parameter" InfoOnIABALT[1][1] = "PF5032"
InfoOnIABALT[0][2] = "ParamType" InfoOnIABALT[1][2] = "float"
InfoOnIABALT[0][3] = "ParamGroup" InfoOnIABALT[1][3] = "LOADS"
InfoOnIABALT[0][4] = "ParamSubGroup" InfoOnIABALT[1][4] = "Door - Misc"
InfoOnIABALT[0][5] = "ShortName" InfoOnIABALT[1][5] = "LIRCM Bay Pressure"
InfoOnIABALT[0][6] = "LongName" InfoOnIABALT[1][6] = "LIRCM Bay Pressure"
InfoOnIABALT[0][7] = "Units" InfoOnIABALT[1][7] = "psi"
InfoOnIABALT[0][8] = "Color" InfoOnIABALT[1][8] = 16711680
InfoOnIABALT[0][9] = "Width" InfoOnIABALT[1][9] = 1
InfoOnIABALT[0][10] = "DataSourceType" InfoOnIABALT[1][10] = "Tpp"
InfoOnIABALT[0][11] = "DataSourceArguement" InfoOnIABALT[1][11] = "1"
InfoOnIABALT[0][12] = "UpdateRate" InfoOnIABALT[1][12] = "49.3213"
InfoOnIABALT[0][13] = "LLNegative" InfoOnIABALT[1][13] = "-1000"
InfoOnIABALT[0][14] = "LLPositive" InfoOnIABALT[1][14] = "1686"
(values continue...)
Okay, now to extract actual flight data from an IADS archive. Type in the following code. We
need the output from this statement for a reasonable StartTime
ArchiveInfo = IadsDataInterfaces.iadsread("<Paste Your Data Directory Here>")
iadsread returns the values in ArchiveInfo. Recall from a previous time that ArchiveInfo is a
double dimension array with the column names in the first row and values in the second. My data
returns:
ArchiveInfo[0][0] = "StartTime" ArchiveInfo[1][0] = "318:17:37:52.393"
ArchiveInfo[0][1] = "StopTime" ArchiveInfo[1][1] = "318:21:58:51.518"
ArchiveInfo[0][2] = "DataDir" ArchiveInfo[1][2] = "D:\PostFlightData\Demo"
ArchiveInfo[0][3] = "Flight" ArchiveInfo[1][3] = "100"
ArchiveInfo[0][4] = "Test" ArchiveInfo[1][4] = "100-ABC"
ArchiveInfo[0][5] = "Tail" ArchiveInfo[1][5] = "001"
ArchiveInfo[0][6] = "Date" ArchiveInfo[1][6] = "11/14/1998"
Just as an example, let's read the first 5.5 seconds of data from a couple of parameters. Use the
"StartTime" string of "318:17:37:52.393" obtained from ArchiveInfo[1][0] above as the value of
argument 1. Your second argument should be 5.5 (or any number of seconds). Your third
argument should be a list of comma separated parameter names. Pick parameter names from the
list returned above...My line looks something like this ->
Data = IadsDataInterfaces.iadsread( "D:\PostFlightData\Demo", "318:17:37:52.393", 5.5,
"Sweep,SineWave10Hz,SineWave20Hz,SineWave30Hz,SineWave40Hz" )
Type the line below into your script editor inserting your own dir, StartTime, and parameter list.
Data = IadsDataInterfaces.iadsread( "<Insert Your Data Directory Here>", "<Insert StartTime
String Here>", 5.5, "<Your Parameter List Comma Separated>" )
Hint: If you have an error getting data at this StartTime, add a couple of minutes to your start
time. Sometimes data for a given parameter starts later than others...Alternatively, if you knew
the actual StartTime and EndTime of your data, you could use it to define your data of interest.
My line looks something like this:
Data = IadsDataInterfaces.iadsread("D:\PostFlightData\Demo", "318:17:40:53.393",
"318:17:40:54.393", "Sweep,SineWave10Hz,SineWave20Hz,SineWave30Hz,SineWave40Hz",
"DecimationFactor,2")
I requested one second of data from the parameters defined in my list, and I wanted the data at
DecimationFactor of 2 (giving me every other point from the data).
Data = IadsDataInterfaces.iadsread("<Insert Your Data Dir Here>", "<Insert StartTime Here>",
"<Insert EndTime Here>", "<Your Parameter List Comma Separated>, "DecimationFactor,2")
If all is well, you will get the data requested in matrix form (double dimension array
row,column) with the number of columns matching the number of parameters you have
requested and each row being the set of data values.
In my example:
Data[0][0] = FirstValueOfSweepParam
Data[0][1] = FirstValueOfSineWave10HzParam
Data[0][2] = FirstValueOfSineWave20HzParam
Data[0][3] = FirstValueOfSineWave30HzParam
Data[0][4] = FirstValueOfSineWave40HzParam
Data[1][0] = SecondValueOfSweepParam
Data[1][1] = SecondValueOfSineWave10HzParam
Data[1][2] = SecondValueOfSineWave20HzParam
Data[1][3] = SecondValueOfSineWave30HzParam
Data[1][4] = SecondValueOfSineWave40HzParam
And so on....
Let's say that along with data you also want the current value of time. You could do that with the
"ReturnTimeVector" optional argument as follows:
DataWithTimeAsFirstVector = IadsDataInterfaces.iadsread( "<Insert Your Data Dir Here>",
"<Insert StartTime Here>", "<Insert EndTime Here>", "<Your Parameter List Comma
Separated>", "DecimationFactor,2,ReturnTimeVector,1" )
The first column DataWithTimeAsFirstVector(0..N,0) will be filled with the actual time stamp of
elapsed seconds since midnight. If you want an ascii IRIG time representation simply add
"TimeFormat,1" to the optional last argument like so:
DataWithTimeAsFirstVector = IadsDataInterfaces.iadsread( "<Insert Your Data Dir Here>",
"<Insert StartTime Here>", "<Insert EndTime Here>", "<Your Parameter List Comma
Separated>", "DecimationFactor,2,ReturnTimeVector,1,TimeFormat,1")
Notice that all parameters are combined into 1 matrix called 'Data'. That's because the interface
only allows one variable to the result of iadsread Data = iadsread(..). If you want the data in
separate vectors, you would have to call the iadsread function 3 times. Here is an example below
how to create 3 separate vectors
a = IadsDataInterfaces.iadsread("D:\PostFlightData\Demo", "318:17:40:53.393", 20, "Sweep")
b = IadsDataInterfaces.iadsread("D:\PostFlightData\Demo", "318:17:40:53.393", 20,
"SineWave10Hz")
c = IadsDataInterfaces.iadsread("D:\PostFlightData\Demo", "318:17:40:53.393", 20,
"SineWave20Hz")
The vector 'a' will contain data from the 'Sweep' parameter, 'b' from the 'SineWave10Hz'
parameter, and 'c' from 'SineWave20Hz'
Unlike the multiple parameter requests, these single parameter requests return a single
dimensional array. The data is accessed as:
a(0), a(1), a(2), etc...
To loop through all the values would be similar to the ParameterList above:
For index = 0 To UBound(a)
Value = a(index)
Next
In other words, we don't have to worry about the double dimension (row,column) anymore, but
there are other things to consider.
If for example a, b, and c had different sample rates, we would probably get different amounts of
data in each case. Lining up the values to perform computations will be a difficult task, so be
aware of this fact. When parameters are combined into a matrix, IADS handles this issue by up-
sampling all the parameter to the highest rate in the list (unless overridden by the
'OutputSampleRate' or 'DecimationFactor' optional argument. So, if you want separate vectors,
try using the "OutputSampleRate" option to force matching rates (recommend to upsample to
highest rate).
Writing a program to analyze data should be fairly simple, maybe something like this:
Read in the data from IADS
Data = iadsread("D:\PostFlightData\Demo", "318:17:40:53.393", "318:17:40:54.393",
"Sweep,SineWave10Hz,SineWave20Hz,SineWave30Hz,SineWave40Hz")
Call my analysis function with the data matrix obtained from IADS
b = myAnalysisFunction(Data)
Now output the results
That should be it for the basics; let's continue on with more advanced subjects.
Here is another example of accessing data sequentially. Say you just wanted to stream through
the entire flight worth of data for a number of parameters and plot them. What you have to do it
call iadsread at least once with a valid start time (and you must use the NumSeconds option in
argument 3). In you next call to iadsread, you leave the StartTime string (argument 2) blank.
This will tell iadsread that you wish to continue reading at the point you left off last. In the
example below, the first call will read 10.0 seconds at time 318:17:40:53. Each sequential call
with '' as the argument 3 value will return the next sequential 10.0 seconds of data.
In order to make this work on your system, you'll have to modify arguments 1,2 & 4 to the
correct values for your archive.
SweepData = IadsDataInterfaces.iadsread("D:\PostFlightData\Demo", "318:17:40:53", 10.0,
"Sweep")
For index = 0 to 100
plot( SweepData )
MsgBox "Press ok for next Plot"
' Notice that the second argument "IrigStartTime" is a blank string. This will read the next
SweepData = IadsDataInterfaces.iadsread("D:\PostFlightData\Demo", "", 10.0, "Sweep")
Next
Here is yet another example of accessing data sequentially. Say you just wanted to stream
through the entire flight while connected to the IADS CDS or a Post Test Data Server. It is very
similar to the last example except you'll leave the 'StartTime' field as an empty string and set the
1st argument (DataDirectory or ServerName$PortId) to the CDS or Post Test Data Server
machine name and portId. Don't forget to separate the ServerName and PortId by a $ (dollar
sign). The default portId of the IADS CDS is 58000, so unless you have modified it in the setup
bag this should work.
In order to make this work on your system, you'll have to modify arguments 1 & 4 to the correct
values for your system setup.
Sub TestRealTime2()
For j = 1 to 100
Press_Alt = IadsDataInterfaces.iadsread( "IADS-CDS$58000", "", 2.0, "SineWave0-250" )
plot( Press_Alt )
WScript.Sleep 10 ' Allow a little time for the new data. This line may need to be modified
for the scripting environment used
end
End Sub
***New and advanced stuff to query info from the config file***
There is now a new capability to query any piece of information in configuration file through the
use of an SQL statement. To achieve this, we must first explain how write a simple SQL
statement.
The basic format is: 'select <ColumnName or Comma Seperated ColumnNames> from
<TableName> where <Conditional Statement> (The 'where' statement is optional). In this
format, the <ColumnName> refers to the name of the column in any IADS log or in any
ConfigTool window... Likewise, the <TableName> refers to the actual name of the log name or
'Table' name in the ConfigTool. This is a simple and very useful example that extracts every
column from every row in the 'EventMarkerLog' table. If we want to get every row and column,
we must use a 'wildcard' (an '*') for the column name, as well as no 'where' clause....
EventMarkerLogContents = IadsDataInterfaces.iadsread("D:\PostFlightData\Demo", "", 0, "?
select * from EventMarkerLog")
iadsread returns:
5x2 array with field names in row 0 ( EventMarkerLogContents[0][0) ..
EventMarkerLogContents[0][5) ):
Group
SubGroup
User
Time
Comment
PropertyBag
Examining the second row of the matrix (i.e. the first row of the EventMarkerLog)
EventMarkerLogContents[1][0) .. EventMarkerLogContents[1][5)
Shows:
Group: "LOADS"
SubGroup: "Maneuver Quality"
User: "IadsUser2"
Time: "001:12:40:29.011"
Comment: "E1 APU Start"
PropertyBag: "Each field can be accessed using the proper array index.
EventMarkerLogContents[1][3) would return the time of the event or "010:12:40:29.011"
What if we were only concerned with the 'Time' column information? Let's limit our output to
only the "Time" column like so:
TimeOfEvent = IadsDataInterfaces.iadsread( "D:\PostFlightData\Demo", "", 0, "? select Time
from EventMarkerLog" )
ColumnName = TimeOfEvent(0,0)
Time = TimeOfEvent(1,0)
iadsread returns:
Time
012:17:49:29.011
Now even more useful... What if we were only concerned with the 'Time' column information
when a certain comment occurred?
Let's assume that we had a Comment in our 'EventMarkerLog' table that always contained the
word 'Takeoff' and corresponded to the takeoff time of the aircraft. Let's limit our output to only
the 'Time' column when the 'Comment' contained the word 'Takeoff'. Ok, this is where the
'where' clause comes into play. It is a conditional statement that will allow you to filter through
the many rows of a table/log and find the specific row that you need. The query would look
something like:
TimeOfSpecificEvent = IadsDataInterfaces.iadsread( "D:\PostFlightData\Demo", "", 0, "? select
Time from EventMarkerLog where Comment = '*Takeoff*' " )
ColumnName = TimeOfSpecificEvent(0,0)
Time = TimeOfSpecificEvent(1,0)
Look at the 'where' clause above.... where Comment = '*Takeoff*'.... Confusing, isn't it? First of
all, the IADS SQL query statement requires that all strings in the 'where' clause be single
quoted... so we need two single quotes around the where clause 'Takeoff' string. We also need to
use a 'Wildcard' match, placing asterisks '*' around the word 'Takeoff'. This tells iadsread to
match any comment that has 'Takeoff' anywhere in it... (i.e. 'E10 Takeoff …' matches)
iadsread returns:
Time
012:18:41:19.247
MyParameterList = "Param1,Param2,Param3,Param4"
Done = False
On Error Resume Next
While ( Not(Done) )
Err.Clear()
End
Err.Clear()
On Error Goto 0
APPENDIX A
IADS Configuration Table Reference
Name Description Type
AircraftReferences Used by Parameter Identification Flat
Aircraft Properties Aircraft properties table Flat
ActualFlutterTestPointsLog Completed flutter test points Flat
ActualLoadsTestPointsLog Completed Loads test points Flat
AnalysisLog Location of saved analysis results Flat
AnalysisWindows User created Analysis Windows Hierarchical
AttachedDataDisplays List of displays attached to AWs Hierarchical
FlutterSummaryLog Ongoing collection of flutter results Flat
DataStorageInformation Data Information from a real-time test Flat
CurrentFlightInformation Table of the current flight test Flat
Classifications List of available classifications Flat
GroupDefinitions List of available classification strings Flat
PredefinedComments Pre-defined event marker strings Flat
Constants User defined constants Flat
DataDisplays List of used data displays Hierarchical
DataStorageLog Information on data archive set Flat
DataDropOutLog Not Currently used Flat
DisplayDefaults Data display defaults Flat
Desktops User defined Desktops Hierarchical
ExtendedDesktopInfo Additional Desktop information Flat
Envelopes User defined envelopes Flat
ReferenceCurves User defined reference envelopes Flat
EventMarkerLog User created event markers Flat
HardCopyLog <blank> Flat
HardCopyBanners <blank> Flat
LogBehavior Log behavior settings Flat
LoadsSummaryLog User created loads information Flat
TableUpdateBehavior Table update behavior properties Flat
ModalDefinitions User defined mode ranges and titles Flat
ParameterDefaultsState List of parameter default sets Hierarchical
ParameterDefaults List of all user defined parameters Flat
ParametersSavedInDisplays Parameters saved in defined displays Hierarchical
PlannedLoadsTestPoints User defined planned loads test points Flat
PlannedFlutterTestPoints User defined planned flutter points Flat
AlphaNumeric List of Alphanumeric displays Flat
AlphaNumericTable List of AlphaNumericTable displays Flat
Annunciator List of Annunciator displays Flat
FrequencyResponsePlot List of Frequency response displays Flat
DisplayLabel List of Display Label displays Flat
DisplayFolder List of Display Folder displays Flat
CrossPlot List of Cross Plot displays Flat
DisplayTab List of Display Tab displays Flat
FlutterSummaryPlot List of Flutter Summary Plot displays Flat
FrequencyPlot List of Frequency Plot displays Flat
LoadsSummaryPlot List of Loads Summary Plot displays Flat
NyquistPlot List of Nyquist Plot displays Flat
Slider List of Slider displays Flat
Stripchart List of Stripchart displays Flat
APPENDIX B
IADS Data Types Enumerated
IADS Data Types
iadsInteger 0 Integer data type.
iadsDiscrete 1 Discrete data type.
iadsFloatingPoint 2 Floating point data type.
iadsLong 3 Long data type.
iadsUnsignedLong 4 Unsigned long data type.
iadsDouble 5 Double data type.
iadsAscii 6 ASCII data type.
iadsBlob 7 Binary data type
IADS Data Source Type
iadsTpp 1 TPP data source
iadsDerived 2 Derived data source
iadsIap 3 Derived data source.
On/Off enumeration
iadsOn 0 On setting
iadsOff 1 Off setting
Yes/No enumeration
iadsYes 0 Yes setting
iadsNo 1 No setting
Filter algorithms
iadsFilterNone 0 No filter algorithm
iadsButterworthFilter 1 Butterworth filter
iadsEllipticFilter 2 Elliptic filter
Filter pass types
iadsLowPass 1 Low pass filter
iadsHighPass 2 High pass filter
iadsBandPass 3 Band pass filter
Data correction methods
iadsDataCorrectionNone 0 No data correction
iadsDefaultValue 1 Default value
iadsLastValue 2 Last value
Null corrections
iadsNullCorrectionNo 0 No null correction
iadsNullCorrectionYes 1 Use null correction
iadsNullEquationInput 2 Equation input correction
iadsNullEquationResult 3 Equation result correction
Null group enumeration
iadsAircraftGroup 1 Aircraft group
iadsWeaponsGroup 2 Weapons group
Spike detection method
iadsSpikeDetectionMehodNone 0 No spike detection
iadsSlopeChange 1 Slope change detection
iadsAbsoluteChange 2 Absolute change detection
IADS compute types Enum Value Description
iadsAutoSpectrum 0 Auto spectrum compute type
iadsPsd 1 PSD compute type
iadsPhaseMagnitude 2 Phase magnitude compute type
iadsPhaseReal 3 Phase real compute type
iadsPhaseImaginary 4 Phase imaginary compute type
APPENDIX C
IADS Interface Message Format 1
APPENDIX D
Sample Parameter Definition File
1 TimeUpperWord 1000.0 1 SystemParamType = MajorTime
2 TimeLowerWord 1000.0 1 SystemParamType = MinorTime
3 PARAMETER1 12.330334596 2
4 PARAMETER2 24.6606691919 2
5 PARAMETER3 49.3213383838 2
6 PARAMETER4 98.6426767677 2
7 PARAMETER5 197.285353535 2
8 PARAMETER6 394.570707071 2
9 PARAMETER7 789.141414141 2
10 PARAMETERBLOB 10.0 7 DataSize = 92
100 DECOMSTATUS 789.141414141 1 SystemParamType = DecomStatus
APPENDIX E
31-6 5 4 3 2 1 0
SF(n+1)STAT- SF(n)STAT SF2STAT SF2STAT SF1STAT SF1STAT FSTAT FSTAT