# Software development

The Sky-Drones Platform helps to integrate drones in custom end-to-end workflows with lots of enhanced features for advancing our enterprise customers:

* Real-time digital HD video streaming
* Real-time payload data processing (e.g. computer vision)
* Real-time flight control (e.g. target tracking, collision prevention, and obstacle avoidance)
* In-flight telemetry and payload data streaming directly to customer’s cloud
* Drone-to-drone communications
* Running custom apps directly on the drone (edge computing)
* Safely performing autonomous BVLOS missions with real-time control

You have all the necessary infrastructure to develop your own drone software as well as use advanced software from Sky-Drones partners.

## Accessing AIRLink Mission Computer with SSH

Open Terminal and access AIRLink Mission Computer with SSH using the following command:

```bash
ssh smartap@airlink.local
```

You will be asked for the password, the default credentials are:

* Login: **smartap**
* Password: **smartap**

If you log in successfully you will see the following welcome page:

![](/files/-MdmM9BjtQI2Hy9_c2Gn)

{% hint style="info" %}
If you are connected to AIRLink using WiFi Access Point mode and your computer doesn't support local DNS, you would need to use IP address **10.42.0.1** instead of **airlink.local.**
{% endhint %}

That's all you need for the development and we assume now you know what to do :)

#### Root access

{% hint style="info" %}
SSH root access is not available as standard for security and safety reasons. However, this can be provided by Sky-Drones upon request. Please [contact us](https://sky-drones.com/contact-us) to get an access.&#x20;
{% endhint %}

## Read / Write MAVLink Telemetry data

SmartAP AIRLink provides user access for MAVLink telemetry stream which is useful for 3rd party applications development where you need to have access to the data from / to Autopilot and to / from Ground Control Station.&#x20;

AIRLink supports 3 ports for user applications: 2 absolutely independent UDP ports and 1 TCP port for third party apps access:

| # | Type | Host      | Port  | Protocol |
| - | ---- | --------- | ----- | -------- |
| 1 | UDP  | 127.0.0.1 | 14560 | MAVLink  |
| 2 | UDP  | 127.0.0.1 | 14561 | MAVLink  |
| 3 | TCP  | 127.0.0.1 | 14556 | MAVLink  |

For developer's convenience we offer code samples for reading and writing MAVLink messages. This example displays how to read HEARTBEAT message from the other MAVLink nodes and send HEARTBEAT from our example.

### UDP Example

Read / write MAVLink using UDP connection:

```python
#!/usr/bin/python3
# Usage example of MAVLink UDP port for user applications
# To execute:
#     python3 heartbeat_example_udp.py
# or
#     python3 heartbeat_example.py 127.0.0.1:14560 35
#     in this case: 127.0.0.1:14560 - address and port of mavlink source,
#                                     now available 14560 and 14561 udp ports 
#                                     for user applications
#                   35 - system-id for signature
#

import pymavlink.mavutil as mavutil
from pymavlink.dialects.v20 import common as mavlink
import sys
import time
from threading import Thread


if len(sys.argv) != 3:
    # use default arguments if no arguments given from command line
    srcSystem = mavlink.MAV_COMP_ID_USER1
    remote_address = "127.0.0.1:14560"
else:
    # use arguments from command line
    srcSystem = int(sys.argv[2])
    remote_address = sys.argv[1]

# create connection
mav = mavutil.mavlink_connection(
    'udpout:' + remote_address, source_system=srcSystem)


def sender_loop():
    while True:
        mav.mav.heartbeat_send(mavlink.MAV_TYPE_GENERIC,
                               mavlink.MAV_AUTOPILOT_INVALID,
                               mavlink.MAV_MODE_FLAG_CUSTOM_MODE_ENABLED,
                               0,
                               mavlink.MAV_STATE_STANDBY)
        time.sleep(2)


send_thread = Thread(target=sender_loop)
send_thread.daemon = True
send_thread.start()

while True:
    msg = mav.recv_match(blocking=True)
    if msg.get_type() == 'HEARTBEAT':
        print("HEARTBEAT from %d: %s" % (msg.get_srcSystem(), msg))


```

Run this example with:&#x20;

```python
python3 heartbeat_example_udp.py
```

### TCP Example

Read / write MAVLink using TCP connection:

```python
#!/usr/bin/python3
# Usage example of MAVLink TCP port for user applications
# To execute:
#     python3 heartbeat_example_tcp.py
# or
#     python3 heartbeat_example.py 127.0.0.1:14556 35
#     in this case: 127.0.0.1:14560 - address and port of mavlink source,
#                                     now available 14556 tcp port
#                   35 - system-id for signature
#

import pymavlink.mavutil as mavutil
from pymavlink.dialects.v20 import common as mavlink
import sys
import time
from threading import Thread


if len(sys.argv) != 3:
    srcSystem = mavlink.MAV_COMP_ID_USER2
    remote_address = "127.0.0.1:14556"
else:
    srcSystem = int(sys.argv[2])
    remote_address = sys.argv[1]

mav = mavutil.mavlink_connection(
    'tcp:' + remote_address, source_system=srcSystem)


def sender_loop():
    while True:
        mav.mav.heartbeat_send(mavlink.MAV_TYPE_GENERIC,
                               mavlink.MAV_AUTOPILOT_INVALID,
                               mavlink.MAV_MODE_FLAG_CUSTOM_MODE_ENABLED,
                               0,
                               mavlink.MAV_STATE_STANDBY)
        time.sleep(2)


send_thread = Thread(target=sender_loop)
send_thread.daemon = True
send_thread.start()

while True:
    msg = mav.recv_match(blocking=True)
    if msg.get_type() == 'HEARTBEAT':
        print("HEARTBEAT from %d: %s" % (msg.get_srcSystem(), msg))


```

### Run the example

Run the example with the following commands:&#x20;

```bash
# Login via SSH
ssh smartap@airlink.local

# Make sure that you have the example 
# file in your home directory and run it with
python3 heartbeat_example_udp.py
```

Once you run the example above you should expect the following output. This is the Heartbeat message coming from the Flight Controller:

![](/files/-Mhwouet-hQb0udYJmXu)

If you connect with the Ground Control Station software you will also see the heartbeat coming from the GCS:

![](/files/-MhwpE8dWCKvhmG3_Tba)

Feel free to use these code samples for your custom apps development using SmartAP AIRLink and MAVLink communication protocol.&#x20;

## Get Video feed

AIRLink provides video feed access via RTSP either locally (127.0.0.1) or remotely (airlink.local). Currently, we support integrated CSI camera and HDMI input as well as [NextVision](https://www.nextvision-sys.com/) cameras over Ethernet:&#x20;

| # | Video feed        | Type | Host                       | Port | Address                             |
| - | ----------------- | ---- | -------------------------- | ---- | ----------------------------------- |
| 1 | CSI Camera        | RTSP | 127.0.0.1 or airlink.local | 8554 | rtsp\://airlink.local:8554/camera/0 |
| 2 | HDMI Input        | RTSP | 127.0.0.1 or airlink.local | 8554 | rtsp\://airlink.local:8554/camera/1 |
| 3 | NextVision Camera | RTSP | 127.0.0.1 or airlink.local | 8554 | rtsp\://airlink.local:8554/camera/2 |

To check the video stream using a standard GStreamer pipeline use the following command:

```bash
gst-launch-1.0 rtspsrc location=rtsp://airlink.local:8554/camera/0 ! rtph264depay ! avdec_h264 ! autovideosink sync=false
```

{% hint style="success" %}
If you have any other questions related to the software development with AIRLink please get in touch with our support team [here.](https://sky-drones.com/contact-us)
{% endhint %}


---

# 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.sky-drones.com/avionics/airlink/software-development.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.
