Skip to main content

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

  1. Click the Flex link in the left navigation menu.

  2. 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.

  3. Click + Create Package.

  4. Create a File by hovering over your package in the left side file viewer, clicking the ... icon, and then New File.

  5. Enter the name "Transform.flex" and click + Create File.

  6. Paste the following code below the module name.

    flex
    message 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 message PositionMetric represents values in radians and meters. The transform US_to_Metric defines the relationship between these messages, taking PositionUS as input and outputting PositionMetric. A return keyword doesn't need to be included because the last expression of a transform is implicitly returned.

  7. 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.

  8. 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

  1. Go to the Component Library
  2. Create a new component and call it "FlexTransformWorkspace".
  3. Add an implementation and then click Open Workspace.
  4. Within the workspace, click the Component Library icon on the left menu and add a new component called "PositionReporter".
  5. Add a port and select your new Flex package ([YourPackageName]::v1) from the drop down. For this component, add the following messages:
    • PositionUS - Out
  6. Click Next, add an implementation and drag it into your workspace.
  7. Add another component called "PositionReceiver" and give it the following port interface:
    • PositionMetric - In
  8. Click Next, add an implementation and drag it into your workspace.
  9. Connect the components together by clicking the Make connection icon of PositionReporter first, and then PositionReceiver.
  10. Click + New Connection.
  11. Choose PositionUS for the first port, and PositionMetric for the second. You should see the text "Transform is available". This is your Flex Transform!
  12. Click Done.

Step 3: Generate Transpiler Code

  1. Click the Workflows icon on the left menu.
  2. Create a new workflow. Call it "Transpiler".
  3. Select your new workflow and click + Tasks.
  4. Drag the Transform plugin into the right area.
  5. Click the gear icon of the Transform plugin, select configuration "Generate Transpiler Code" and click Done.
  6. Exit the Workflow Editor by clicking the Close button on the top right.
  7. Run the workflow to generate code to transform between Flex representations of message types from your Flex module.
  8. Download the generated code. Extract and open the package.
  9. Navigate to the transforms/gen folder. You should see files called Transform.cpp and my_transform.cpp. These were generated as a result of the transform that you defined in your .flex file.
  10. 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. The my_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™.