Skip to main content

Autonomous UAV Navigation

Scenario

You've just started as an Integration Engineer at SkyShield, a small startup in the electronic warfare space serving the Air Force. SkyShield produces a UAV with an autonomous navigation system. This system consists of a MissionComputer capable of controlling a Sensor, which can identify flying entities and geo-locate them. There's also a SatNav GPS receiver which provides precise location data to the system.

After thorough testing, a susceptibility was found in their SatNav components where the GPS satellite connection can get jammed causing Sensor data to go off track. For the sensor to operate correctly, it needs to know the precise location of the UAV.

To fix this issue, your team is testing an integration with an alternative navigation component produced by Acme Co. which doesn't rely on GPS. In the case where SatNav is jammed, the UAV could fall back to data from Acme's AltNav component, and the Sensor data would stay on track. This allows the mission system to continue operation seamlessly.

However, Acme's components use their own proprietary messages, whereas SkyShield's UAVs use the LMCP standard. Your team is evaluating the effectiveness of an integration tool like Tangram Pro to help them integrate and test these systems.

In this tutorial you'll learn how to:

  • Design a component-based UAV navigation system using LMCP
  • Integrate a proprietary component with LMCP using Flex code
  • Link test applications from a GitHub repository
  • Generate component and transform interfaces
  • Create containers and run applications in them to test the interfaces
Prerequisite

You'll need a GitHub account to complete this tutorial.

Design a UAV Navigation System

1. Create a Project

To begin modeling a system we need to make a project. Projects are used to design component-based systems, generate and run code based on your design. Let's get started!

  1. Go to Projects and click New Project
  2. Enter a Project Name Autonomous UAV
  3. Set the Owner to a team, or keep Personal (You) selected

2. Add UAV Navigation Components

The autonomous UAV system we're modeling uses 3 components to process navigation data. Let's add them to the design.

  1. Add three components using the Add Component button
  2. Double-click on the component's name and enter the following names:
NamePurpose
MissionComputerMain hub for processing mission navigation data
SatNavProvides UAV position and velocity data from GPS satellite
SensorIdentifies flying entities and provides their geo-location

3. Add Transport

Now let's define a transport for this design. The UAV system we're modeling is connected to a ZeroMQ transport, which handles distributing serialized messages between its components.

  1. Click the Transports button and add ZeroMQ

Connections in the design will now default to ZeroMQ.

4. Define Interfaces and Connections

Now let's define which LMCP messages are input or output by these components.

Update SatNav

  1. Click the ... icon in the SatNav component and choose Interface

  2. Select Package OpenUxAS::LMCP::v3

  3. Add the following messages:

    MessageDirection
    AirVehicleStateOutput
  4. Draw a connection from SatNav to MissionComputer by clicking and dragging from the edge of SatNav

  5. Edit the connection and choose Suggested Message AirVehicleState

Update Mission Computer

  1. Edit the Interface for MissionComputer

  2. Choose Interface Package OpenUxAS::LMCP::v3 and add the following messages

    MessageDirection
    GimbalAngleActionOutput
    GimbalScanActionOutput
    AirVehicleStateInput/Output

    Change AirVehicleState from Input to Input/Output

Update Sensor

  1. Edit the Interface for Sensor

  2. Choose Interface Package OpenUxAS::LMCP::v3 and add the following messages

    MessageDirection
    EntityStateOutput
  3. Draw a connection from Sensor to MissionComputer, edit it and choose Suggested Message EntityState

  4. Click Switch Directions and choose the following messages:

    • AirVehicleState
    • GimbalAngleAction
    • GimbalScanAction

Nice work! You design should look similar to this:

UAV Design

tip

Expand the Connections section on the left to quickly examine interface connections.

Group, Layout and Tag

There are additional features available to help you organize and filter your designs. You can group and tag components, and change the direction of the layout.

1. Add a Group

Let's group the components that use LMCP messages for more visual clarity.

  1. Click the Add Group button in the design toolbar and click anywhere on the stage to add it
  2. Double-click on the groups's name and enter LMCP
  3. Drag the MissionComputer, SatNav and Sensor components into the group

The layout automatically adjusts as components are added to or removed from a group

tip

Try collapsing the group by clicking the icon in the top left, and expand by clicking the + icon

2. Adjust Layout

You can change the direction and alignment of connections by clicking the Layout button in the bottom right toolbar.

Layout Direction

3. Add Tags

Tangram Pro also allows you to tag components with a color and label. Let's use tags to designate which UAV version the components belong to.

Add tags to the project

  1. Expand the Tags section in the bottom left
  2. Click the + to add a tag.
  3. Choose a color and enter name uav 1.0
  4. Add another tag with a different color and enter name uav 2.0 (we'll use this later)

Tags

Apply tags to components

  1. Select the MissionComputer component in the design and click the ... button
  2. Click Edit Tags and select uav 1.0
  3. Apply the same tag to the SatNav and Sensor components

Generate Code and Containers

Tangram Pro will generate the interface code needed to support the sending and receiving of the messages that you've selected in the design. This ready-to-run code contains objects that represent your selected messages, but also setter and getter functions for each message, transport libraries, and serialization/deserialization libraries.

1. Connect Repository

There are C++ applications and Dockerfiles hosted in GitHub that we'll use to test the generated interface code against simulated navigation data. First we need to link the components to our autonomous-uav-demo repository to pull in the test applications.

  1. Follow the instructions here: Source Code Integration to connect your GitHub account to Tangram Pro
  2. Return to your project and click Build in the top left menu
  3. Select MissionComputer in the list on the left
  4. Go to the Code tab
  5. Select Host URL https://github.com
  6. Search for the repository named autonomous-uav-demo and click on TangramFlex / autonomous-uav-demo
  7. Keep default branch master
  8. Add the same repository to the other 2 components:
    • SatNav
    • Sensor

Connect Repository

2. Configure Build Actions

Next, choose the code generation options for each component and provide a Dockerfile path.

Configure MissionComputer

  1. Select MissionComputer in the list on the left
  2. Go to the Actions tab
  3. Enable the following:
    • Generate Interface Code: C++
      • Compile Code: all
    • Containerize
      • Include Generated Code
      • Use Dockerfile Path: MissionComputer/Dockerfile
  4. Select the other 2 components and add the same configuration as above, except use these Dockerfile paths:
    • SatNav: SatNav/Dockerfile
    • Sensor: Sensor/Dockerfile

Build Actions

3. Build

Let's generate code!

  1. Click the blue Build button
  2. Grab a cup of coffee and check out the streaming build logs. This may take about 15 minutes to complete as it is generates interface code for each component, and builds container images

Since we've enabled Containerize, Tangram Pro will create a container for each component and copy the generated code into it. The test applications from the GitHub repository we linked earlier will also be copied into the containers.

4. Run a Test

Start a run after the build is complete.

  1. Select Run in the top left menu
  2. Select the completed build
  3. Click the Run button to spin up the containers

Tangram Pro will spin up the container images created during the build, and display each container's execution via system logs. It may take a minute before they're all running.

What happens in the containers?

  1. The ZeroMQ container starts a proxy service
  2. The 3 component containers connect to ZeroMQ and each run a C++ application that was pulled from the connected repository https://github.com/TangramFlex/autonomous-uav-demo/
  3. MissionComputer streams UAV position updates to the console using data provided by SatNav
  4. SatNav gets jammed every 20 seconds for 10 seconds and you should see the output change to Jammed: 1
  5. While jammed, Sensor incorrectly locates the navigation tracks

Run

Great! You've successfully executed the autonomous UAV test applications inside Tangram Pro. Now you're ready to augment this system and integrate the AltNav component.

So far you've:

  • Created a valid design of SkyShield's autonomous UAV navigation system
  • Defined the interfaces / connections for each component using LMCP messages
  • Generated interface code
  • Executed the interface code and test applications in containers to verify the system is working as expected

Integrate Alternative Navigation

The current UAV navigation system relies on a GPS satellite connection to provide the UAVs current location to the mission computer. The mission computer then sends this information periodically to the gimballed sensor so it is able to locate the tracks. If the GPS receiver becomes "jammed", then it will occasionally fail to update its location. This bad data causes the sensor to incorrectly locate the tracks

Next we're going to integrate Acme's AltNav component into the design, and test interfacing with its navigation data when SatNav is jammed.

1. Add Custom Flex Message

This component doesn't use LMCP, but we can easily define a custom message type using Flex.

  1. Go to Flex Packages in the upper right menu, and click Open Flex Editor
  2. Click Package Manager and create a package named AcmeEngineering::v3
  3. Hover over your package on the left, and add a file named AltNav.flex
  4. Paste the following code in the file:
message struct AltNavPosition 
{
    timestamp : int64;
    lat: float64;
    lon: float64;
    alt: float32;
}
  1. Save the file using (Cmd + S / Ctrl + S)
  2. Create a release by clicking the checkmark icon above the package name, and clicking the Create Release button

Flex Release

2. Add Custom Flex Transform

Next we'll need to define a transform function to handle the conversion of Acme's AltNavPosition to LMCP AirVehicleState.

  1. Click Package Manager and create a new Flex package named Transforms::AcmeEngineering::v1
  2. Add a file named AltNav2LMCP.flex and enter the following code:
import AcmeEngineering::v3.AltNav (AltNavPosition)
import OpenUxAS::LMCP::v3.afrl.cmasi(AirVehicleState, AltitudeType, NavigationMode, Location3D)

transform ANP2AVS(alt : AltNavPosition) -> AirVehicleState {
    let location = Location3D {
        Latitude = alt.lat;
        Longitude = alt.lon;
        Altitude = alt.alt;
        AltitudeType = AltitudeType.MSL;
    };
    AirVehicleState {
        ID = 0;
        u = 0.0;
        v = 0.0;
        w = 0.0;
        udot = 0.0;
        vdot = 0.0;
        wdot = 0.0;
        Heading= 0.0;
        Pitch=0.0;
        Roll=0.0;
        p=0.0;
        q=0.0;
        r=0.0;
        Course = 0.0;
        Groundspeed = 0.0;
        Location = location;
        EnergyAvailable = 0.0;
        ActualEnergyRate = 0.0;
        PayloadStateList = [];
        CurrentWaypoint = 0;
        CurrentCommand = 0;
        Mode= NavigationMode.Waypoint;
        AssociatedTasks = [];
        Time = alt.timestamp;
        Info = [];
        Airspeed = 0.0;
        VerticalSpeed = 0.0;
        WindSpeed = 0.0;
        WindDirection = 0.0;
    };
}
  1. Save the file using (Cmd + S / Ctrl + S)
  2. Add package dependencies for the import statements by clicking the box icon above the package name

Flex Dependencies

  1. On the right, search for and add these 2 Flex Packages. Click Apply Changes after they're added.
    • AcmeEngineering::v3
    • OpenUxAS::LMCP::v3
  2. Create a release of your Transform package by clicking the checkmark icon above the package name, and clicking the Create Release button
  3. Close the Flex Editor by clicking the x in the top right to return to the design

3. Connect AltNav with a Transform

Next we'll add a component to represent Acme's AltNav in the design, and use the Flex packages you released. The AltNav component outputs Acme's AltNavPosition messages, but MissionComputer expects LMCP AirVehicleState messages. Let's add a transform object to the design to handle this conversion.

  1. Add a new component named AltNav
  2. Edit its interface and choose
    • Package: AcmeEngineering::v3
    • Message: AltNavPosition
    • Direction: Output
  3. Click the Add Transform button in the design toolbar and click anywhere on the stage to add it
  4. Now select which components connect to the transform. Click on AltNav first then Mission_Computer
  5. For the Input Message, use the Suggested button to choose AltNavPosition
  6. For the Output Message, use the Suggested button to choose AirVehicleState
  7. Apply the ANP2AVS transform

Great! You've integrated the AltNav component into the design. Now let's explore additional design features.

4. Tag AltNav

Let's tag the AltNav component:

  1. Select the AltNav component and Edit Tags
  2. Apply the uav 2.0 tag

You can filter the design view based on tags:

  1. Hover over a tag in the list to highlight the tagged components in the design
  2. Click the eye icon next to a tag to filter the design to only the tagged components

5. Connect Repository

There's another C++ application and Dockerfile hosted in GitHub that we'll use to test the AltNav integration.

  1. Click Build in the top left menu
  2. Select AltNav in the list on the left
  3. Go to the Code tab
  4. Select Host URL https://github.com
  5. Search for the repository named autonomous-uav-demo and click on TangramFlex / autonomous-uav-demo
  6. Keep default branch master

6. Configure Build Actions

Next, choose the code generation options.

Configure AltNav

  1. Select AltNav in the list on the left
  2. Go to the Actions tab
  3. Enable the following:
    • Generate Interface Code: C++
      • Compile Code: all
    • Containerize
      • Include Generated Code
      • Use Dockerfile Path: AltNav/Dockerfile

Configure the transform

  1. Select Transform_1 in the list on the left
  2. Choose the option Generate Transform with CSIs
  3. Enable Containerize and Use Local Dockerfile

A Dockerfile is provided automatically for transforms. We'll use the one provided, no changes needed.

7. Build

Let's generate code!

  1. Click the blue Build button
  2. This may take about 10 minutes to complete as it is compiles the AltNav component interface and transform applications, and builds the containers

8. Run a Test

Now we're going to run the whole system including AltNav and its test application.

  1. Select Run in the top left menu after the build completes
  2. Select the completed build
  3. Click the Run button to spin up the containers

Tangram Pro will spin up the container images created during the build, and display each container's execution via system logs. You'll see 6 containers spin up and begin executing their commands. It may take a minute before they're all running.

Run

What happens in the containers?

  1. The ZeroMQ container starts a proxy service
  2. The 4 component containers connect to ZeroMQ and each run a C++ application that was pulled from the connected repository https://github.com/TangramFlex/autonomous-uav-demo/
  3. The transform container connects to ZeroMQ and runs a Tangram-generated transform application (this handles converting AltNav messages to the LMCP AirVehicleState format)
  4. MissionComputer streams UAV position updates to the console using data provided by SatNav
  5. SatNav gets jammed and stops providing GPS data (you'll see Jammed: 1 in the MissionComputer output)
  6. MissionComputer falls back to position data provided by AltNav (you'll see Alt Data: 1 in the MissionComputer output) and mission navigation is back on track

The AltNav integration is made possible by the Flex transform code you added earlier. The transform application that was generated by Tangram Pro receives serialized AltNavPosition messages from ZeroMQ, deserializes them, converts them to LMCP AirVehicleState messages, serializes them in LMCP format, and sends them to ZeroMQ. The transformed messages can then be received by MissionComputer.

Cheers!

You've completed a successful test of the AltNav integration using Tangram Pro 🎉

Check out what you accomplished:

  • Designed a component-based UAV navigation system
  • Integrated a proprietary component using Flex code
  • Linked test applications from a GitHub repository
  • Generated component and transform interfaces
  • Created containers and ran applications to test the interfaces

If you want to learn more about component-based system design in Tangram Pro, take a look at our blog posts.