> For the complete documentation index, see [llms.txt](https://docs.auterion.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.auterion.com/~/changes/TDRfjBXXgHmxK48cWqay/app-development/auterion-sdk/write-your-first-app.md).

# Write Your First App

This example app assembles a flight mode, which will automatically register itself in APX4 and become available in [AMC](/~/changes/TDRfjBXXgHmxK48cWqay/vehicle-operation/auterion-mission-control.md) when running. When activated, this flight mode example app holds the current 3D position of the vehicle by setting the desired horizontal acceleration, vertical velocity and the yaw heading rate to zero.

### 1. Code structure

Create a new directory for this app:

```bash
mkdir -p my-app/src
cd my-app
```

Create a minimal `CMakeLists.txt` file:

```cmake
cmake_minimum_required(VERSION 3.8)
project(my_app)

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(auterion_sdk REQUIRED)

add_executable(my_app src/my_app.cpp)

ament_target_dependencies(
  my_app
  auterion_sdk
)
```

Create a source file `src/my_app.cpp`:

{% hint style="info" %}
This illustrates the structure of custom flight mode using the SDK, and does not represent a practical use case for a flight mode.&#x20;
{% endhint %}

```cpp
#include <auterion_sdk/auterion.hpp>
#include <auterion_sdk/control/multicopter/local_frame_dynamics_control.hpp>
#include <auterion_sdk/control/mode.hpp>
#include <iostream>

class MyMode {
private:
    auterion::Mode _mode;


public:
    explicit MyMode(auterion::SDK& sdk) : _mode(sdk, "My Mode", {
        auterion::multicopter::LocalFrameDynamicsSetpoint::Config{}
    }) {
        _mode.onActivate([]() {
            // initilize your controller here, like integrators, ramps, etc.
            std::cout << "My mode activated" << std::endl;
        });

        _mode.onDeactivate([]() {
            std::cout << "My mode deactivated" << std::endl;
        });

        _mode.onUpdateSetpoint([](float dt_s) -> auterion::multicopter::LocalFrameDynamicsSetpoint {
            return auterion::multicopter::LocalFrameDynamicsSetpoint()
                .withHorizontalAcceleration(Eigen::Vector2f(0.0f, 0.0f))
                .withVerticalVelocity(0.0f)
                .withHeadingRate(0.0f);
        });
    }
};

int main(int argc, char* argv[]) {
    auterion::SDK sdk(argc, argv, "flight_mode_example");

    MyMode my_mode(sdk);

    sdk.run();

    return 0;
}
```

This sets up the minimal structure for a local-frame-dynamics mode for a Multicopter.

You can now run the app locally, with the commands

```bash
source /opt/ros/humble/setup.sh
cmake -B build -S.
cmake --build build
```

### 2. Make it into an AuterionOS app

Turning this example code into an AuterionOS app is done using the [App Framework](/~/changes/TDRfjBXXgHmxK48cWqay/app-development/app-framework.md). Make sure to have the tooling set up before continuing. In particular the helper tool **auterion-cli** should be installed on the machine that is used to build the app.&#x20;

Create a `Dockerfile` to build your app image:

```docker
FROM auterion/app-base:v2

RUN curl -1sLf 'https://dl.cloudsmith.io/public/auterion/public/setup.deb.sh'| sudo -E bash
RUN apt update && apt install -y ros-humble-auterion-sdk

COPY src /app/src
COPY CMakeLists.txt /app
WORKDIR /app
RUN . /opt/ros/humble/setup.sh && \
    cmake -B build -S . && cmake --build build

CMD . /opt/ros/humble/setup.sh && /app/build/my_app
```

Create the `auterion-app.yml` metadata file:

{% hint style="warning" %}
AuterionOS app API Version v3 or later is required to support Auterion SDK. For more details on the apps API see [Apps API](/~/changes/TDRfjBXXgHmxK48cWqay/app-development/app-framework/app-framework-1.md)&#x20;
{% endhint %}

```yaml
auterion-api-version: 3
auterion-app-base: v2

app-name: local-frame-dynamics-mode
app-author: <com.your-company>
app-version: 0.0.1
target-platform: skynode

services:
  my-mode: 
    build: .
```

Now, you can build and install your app on Skynode:

```
auterion-cli app build
auterion-cli app install
```

#### Virtual Skynode

If you are building your app for [Virtual Skynode](/~/changes/TDRfjBXXgHmxK48cWqay/app-development/virtual-skynode.md), you must provide the `--simulation` flag to your build arguments to specify the correct simulation target architecture:

```
auterion-cli app build --simulation
```

This is explained in the [Application Development](/~/changes/TDRfjBXXgHmxK48cWqay/app-development/app-development/application-development-1.md#virtual-skynode) page.
