Author a Transform with Flex
The previous tutorials leveraged message-to-message transforms that are included with Tangram Pro™. But, if a component software interface needs a transform that is currently not included, a Tangram Pro™ user can define their own with Flex. In the broadest terms, a transform is like a function that accepts a data structure as input, modifies its values, and outputs a new data structure.
This tutorial provides a high level overview for users to add support for their own transforms in Tangram Pro™.
Flex Documentation is available at Flex Docs. For this tutorial, example Flex code is provided.
You'll learn how to:
- Add support for your own transform using the Flex authorship feature.
Step 1: Create Your Own Transform
Click the Flex link in the left navigation menu.
Create a Package by clicking the New button in the upper left. Choose a name and ensure you select your team from the drop down.
Click + Create Package.
Create a File by hovering over your package in the left side file viewer, clicking the
...
icon, and then New File.Enter the name "Transform.flex" and click + Create File.
Paste the following code below the module name.
flexmessage struct PositionUS {latitudeDegrees : float64;longitudeDegrees : float64;altitudeFeet : float32;}message struct PositionMetric {latitudeRadians : float64;longitudeRadians : float64;altitudeMeters : float32;}transform US_to_Metric(i : PositionUS) -> PositionMetric {let pi : float64 = 3.14159265359;PositionMetric {latitudeRadians = pi * (i.latitudeDegrees / 180.0);longitudeRadians = pi * (i.longitudeDegrees / 180.0);altitudeMeters = i.altitudeFeet / 3.28084;};}The first message
PositionUS
represents values in degrees and feet. The second messagePositionMetric
represents values in radians and meters. The transformUS_to_Metric
defines the relationship between these messages, takingPositionUS
as input and outputtingPositionMetric
. Areturn
keyword doesn't need to be included because the last expression of a transform is implicitly returned.Save the file by clicking the gear button in the upper-right and selecting Save File or alternatively pressing the hot-key
Ctrl + S
/Cmd + S
.Publish your new package by selecting the
...
button next to your package name in the left panel and then choosing Publish Package.
Step 2: Build A Component Based Design Using the New Transform
For a refresher on building a Component Based Design go to Visualize a Component Based System Design
- Go to the Component Library
- Create a new component and call it "FlexTransformWorkspace".
- Add an implementation and then click Open Workspace.
- Within the workspace, click the Component Library icon on the left menu and add a new component called "PositionReporter".
- Add a port and select your new Flex package (
[YourPackageName]::v1
) from the drop down. For this component, add the following messages:PositionUS
- Out
- Click Next, add an implementation and drag it into your workspace.
- Add another component called "PositionReceiver" and give it the following port interface:
PositionMetric
- In
- Click Next, add an implementation and drag it into your workspace.
- Connect the components together by clicking the Make connection icon of PositionReporter first, and then PositionReceiver.
- Click + New Connection.
- Choose
PositionUS
for the first port, andPositionMetric
for the second. You should see the text "Transform is available". This is your Flex Transform! - Click Done.
Step 3: Generate Transpiler Code
- Click the Workflows icon on the left menu.
- Create a new workflow. Call it "Transpiler".
- Select your new workflow and click + Tasks.
- Drag the Transform plugin into the right area.
- Click the gear icon of the Transform plugin, select configuration "Generate Transpiler Code" and click Done.
- Exit the Workflow Editor by clicking the Close button on the top right.
- Run the workflow to generate code to transform between Flex representations of message types from your Flex module.
- Download the generated code. Extract and open the package.
- Navigate to the
transforms/gen
folder. You should see files calledTransform.cpp
andmy_transform.cpp
. These were generated as a result of the transform that you defined in your .flex file. - Open
Transform.cpp
. Take a look at the file and see that there is a C++ function called "US_to_Metric" that represents your Flex transform. Themy_transform.cpp
file can be used to execute the "US_to_Metric" function.
Further Exploration
- Go to Flex, view the Package Manager, and open the package called
Transforms::LmcpV3MavlinkV23::v1
. Review each of its Flex files to see additional transform examples. These transforms convert LMCP messages to MAVLink messages. - Open your Flex file, and add another transform to convert in the other direction "Metric_to_US". This time converting radians to degrees, and meters to feet. Publish the changed Flex specification. Update your components to use the new version and change the In/Out directions. Remove the connection between components, and reconnect them in the other direction. Generate Transpiler code and see how the changes you made to Flex affect the resulting C++ function.
Cheers!
By completing this tutorial you learned how to:
- Use Tangram Pro™ to define and use a custom transform definition to build component-based systems.
- Generate code with these user-defined Flex packages.
note
Check out Discuss, our Tangram Flex community and find out more about Flex Authorship in Tangram Pro™.