Difference between a CSI and generating transform code

I have a question re: the config settings for an available transform plug in. When I have an available transform plug in, I have the option to generate a CSI or not. I originally thought the transform code was the CSI, but it seems it is something separate. Is that the case? if so, what is the difference?

1 Like

I’ll reply back with a little bit more information, like thoughts on naming these terms something more meaningful, after I think through it. But I think of a CSI as all the code that supports one particular message set. A transform can be thought of as code that converts a message defined by one CSI to a message defined by a different CSI.

I, however, haven’t touched the CSI generation much and would be interested to hear more from someone who worked on code gen.

1 Like

Hi Nathan - and welcome to Discuss! It sounds like they are separate. It also sounds like a CSI is a sort of “component” even though it is the code that supports a particular message set. So, in the workflow config setting for a transform, when I set CSI to “true” is Tangram Pro actually generating two distinct objects…the transform code and the accompanying CSI for that generated transform code?

Yea pretty much. Taking a quick step back, under the hood we have 2 primary workflow plugins that get utilized in the Transform Workflow Code-gen and Flex Transpiler, and several steps that compose these together.

The Code-gen plugin is what is responsible for generating the CSI. It is also responsible for generating the transform “main” app itself.
The Flex Transpiler plugin is what is responsible for taking the flex transform code and transpiling it to the target output language (cpp / java today)

Now to look at how this is applied in the platform:
Say we have some subcomponent A that speaks LMCP::AirVehicleState and another subcomponent B that listens for STANG::InertialState and we have a connection from A -> B

Now temporarily ignoring the transform aspect of this, within the platform we could create a workflow for either of these subcomponents and for CSI generation (ie Code-gen) As Nathan pointed out this would generate the code for either of these message sets: ie if I run Code-gen for subcomponent A then I get the minimal LMCP CSI code for the message(s) within that sub-component (AirVehicleState) This includes code like sterilization libraries, code for any of the types that the AirVehicleState message is dependent upon, and any of the core LMCP library code. The same is true for subcomponent B but instead STANG::Inertial States.

So now going back to our parent component, if we were to create a Transform workflow under the hood the steps involved look something like this

  1. Flex Transpiler : LMCP::AirVehicleState -> STANAG::InertialState (language)
  2. Code-Gen : Transform App LMCP::AirVehicleState -> STANAG::InertialState (language)
  3. If Generate CSI Code-Gen: CSI LMCP::AirVehicleState (language)
  4. If Generate CSI Code-Gen: CSI STANAG::InertialState (language)

step 1: converts / transpiles the flex code for the desired transform into the target language. this is basically just a small library and cant be run on its own
step 2: generates a runnable application that knows how to wire up communication with each of the CSI’s and how to call the generated transform code when a message is received and how to pass off the transformed message to the other csi
step 3/4: When generate CSI for each side of the transform as described earlier

the idea being behind the generate CSI option is that you may already be generating your CSI or you. may have a local copy, or you have a custom CSI but still wish to generate the transform code on its own to be plugged in on your side afterwards.

I might of glossed over some bits but thats the gist of it.


Wow, this is really helpful! Thanks.

So just to confirm…if the Flex Transpiler plugin transpiles to the target output language (either cpp or java) I would assume that if I do chose to generate a CSI with that flex transpiler plugin the CSI will conform to the same target output language.

Correct, the language chosen for Transform workflow/plugin applies to both the transpiled flex code and the CSI code

One further note, initially Fred asked about the “transform” option on the code-gen-3 platform plugin. There’s an unfortunate name overload going on. The TLDR is that the transform option on the code-gen-3 platform plugin will normally not work if you call it directly. It exists only for us to call via the platform internally. Use the transform workflow (not a plugin) if you want a transform. Use the code-gen option if you want a CSI. Do not use the transform option on the code-gen-3 plugin.

The long version:

As Ben List said, there are three programs used to generate a full end-to-end transform: CSI code-gen (used twice), the transpiler, and the main application generator unfortunately itself called a “transform”. These three program are housed in two platform plugins at present. The transpiler gets it’s own plugin, and the main application “transform” is packaged with the CSI code-generator in the code-gen-3-platform-plugin (at present this is further complicated by the code-gen-2-platform-plugin which exists solely to generate LMCP until we migrate that ability to code-gen-3). Within the code-gen-3-platform-plugin, we reference the CSI code-gen ability under the hood with one preset, code-gen and the transform main application generation ability with another preset, transform. When you see the code-gen or transform options in the UI for the code-gen-3 plugin, it’s referring to those two presets. As a user, you’ll only ever use the code-gen preset. Under very specific circumstances the transform preset might work by itself but I don’t think we’ve wired it up that way. If you want the transform main app, just run the transform workflow, which shows up below the list of available plugins last I checked.

Clarifying notes/glossary:
When we refer to code-gen, we typically mean that subset of code generation which is responsible for generating CSIs. Internally you’ll notice this usage in how we have the “code-gen” team and the “transforms” team even though both are actually working on code generation.

The term CSI is something we came up with to replace the term “CAL” because a CAL is OMS specific. A CSI is the library that enables a program to speak a given message set. So in a transform, there are always two CSIs, the CSI for the incoming message set and the CSI for the outgoing message set. A CSI provides the same ability to a computer program that a Spanish class would provide to you were you to be sent on a business trip to Mexico. The CSI has everything the program needs to speak a given message set such as LMCP, STANAG4586, or OMS.


It almost sounds like a CSI is a sort of mini-API for components(?).

1 Like

A CSI is literally the API for a component. :smiley: