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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.auterion.com/~/changes/TDRfjBXXgHmxK48cWqay/app-development/auterion-sdk/write-your-first-app.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
