# Payloads and Cameras

PX4 supports a wide range of payloads and cameras.

# Mapping Drones

Mapping drones use cameras to capture images at time or distance intervals during surveys.

MAVLink cameras that support the MAVLink Camera Protocol (opens new window) provide the best integration with PX4 and QGroundControl. The MAVSDK provides simple APIs to use this protocol for both standalone camera operations (opens new window) and in missions (opens new window).

Cameras can also be connected directly to a flight controller using PWM or GPI outputs. PX4 supports the following set of MAVLink commands/mission items for cameras that are connected to the flight controller:

The following topics show how to connect your camera configure PX4:

# Cargo Drones ("Actuator" Payloads)

Cargo drones commonly use servos/actuators to trigger cargo release, control winches, etc. PX4 supports servo and GPIO triggering via both RC and MAVLink commands.

# RC Triggering

You can map up to three RC channels to control servos/actuators attached to the flight controller using the parameters RC_MAP_AUX1 to RC_MAP_AUX3.

The RC channels are usually mapped to the AUX1, AUX2, AUX3 outputs of your flight controller (using a mixer file defined in your airfame). You can confirm which outputs are used for RC AUX passthrough on your vehicle in the Airframe Reference. For example, Quadrotor-X has the normal mapping: "AUX1: feed-through of RC AUX1 channel", "AUX2: feed-through of RC AUX2 channel", "AUX3: feed-through of RC AUX3 channel".

If your vehicle doesn't specify RC AUX feed-through outputs, then you can add them using using a custom Mixer File that maps Control group 3 outputs 5-7 to your desired port(s). An example of such a mixer is the default passthrough mixer: pass.aux.mix (opens new window).

注解

The same outputs used for "feed-through of RC AUX" may also be set using a MAVLink command (see below). PX4 will use the last value set through either mechanism.

# Mission Triggering

You can use the MAV_CMD_DO_SET_ACTUATOR (opens new window) MAVLink command to set (up to) three actuators values at a time, either in a mission or as a command.

Command parameters param1, param2, and param3 are usually mapped to the AUX1, AUX2, AUX3 outputs of your flight controller, while command parameters param4 to param7 are unused/ignored by PX4. The parameters take normalised values in the range [-1, 1] (resulting in PWM outputs in the range [PWM_AUX_MINx, PWM_AUX_MAXx], where X is the output number). All params/actuators that are not being controlled should be set to NaN.

MAVLink uses the same outputs as are configured for [RC AUX passthrough](#rc-triggering) (see previous section). You can check which outputs are used in the [Airframe Reference](../airframes/airframe_reference.md) for your vehicle, and change them if needed using a [custom mixer file](../concept/mixing.md).

# MAVSDK (Example script)

The following MAVSDK (opens new window) example code (opens new window) shows how to trigger payload release using the MAVSDK Action plugin's set_actuator() (opens new window) method.

The set_actuator() index values of 1 to 3 normally map to the AUX1, AUX2, AUX3 outputs of your flight controller.

MAVSDK

sends the MAV_CMD_DO_SET_ACTUATOR (opens new window) MAVLink command under the hood, and hence uses the same outputs as are configured for Mission Triggering and RC Triggering (see previous sections). You can check which outputs are used in the Airframe Reference for your vehicle, and change them if needed using a custom mixer file.

#include <mavsdk/mavsdk.h>
#include <mavsdk/plugins/action/action.h>
#include <chrono>
#include <cstdint>
#include <iostream>
#include <future>

using namespace mavsdk;

void usage(const std::string& bin_name)
{
    std::cerr << "Usage :" << bin_name << " <connection_url> <actuator_index> <actuator_value>\n"
              << "Connection URL format should be :\n"
              << " For TCP : tcp://[server_host][:server_port]\n"
              << " For UDP : udp://[bind_host][:bind_port]\n"
              << " For Serial : serial:///path/to/serial/dev[:baudrate]\n"
              << "For example, to connect to the simulator use URL: udp://:14540\n";
}

int main(int argc, char** argv)
{
    if (argc != 4) {
        usage(argv[0]);
        return 1;
    }

    const std::string connection_url = argv[1];
    const int index = std::stod(argv[2]);
    const float value = std::stof(argv[3]);

    Mavsdk mavsdk;
    const ConnectionResult connection_result = mavsdk.add_any_connection(connection_url);

    if (connection_result != ConnectionResult::Success) {
        std::cerr << "Connection failed: " << connection_result << '\n';
        return 1;
    }

    std::cout << "Waiting to discover system...\n";
    auto prom = std::promise<std::shared_ptr<System>>{};
    auto fut = prom.get_future();

    // We wait for new systems to be discovered, once we find one that has an
    // autopilot, we decide to use it.
    mavsdk.subscribe_on_new_system([&mavsdk, &prom]() {
        auto system = mavsdk.systems().back();

        if (system->has_autopilot()) {
            std::cout << "Discovered autopilot\n";

            // Unsubscribe again as we only want to find one system.
            mavsdk.subscribe_on_new_system(nullptr);
            prom.set_value(system);
        }
    });

    // We usually receive heartbeats at 1Hz, therefore we should find a
    // system after around 3 seconds max, surely.
    if (fut.wait_for(std::chrono::seconds(3)) == std::future_status::timeout) {
        std::cerr << "No autopilot found, exiting.\n";
        return 1;
    }

    // Get discovered system now.
    auto system = fut.get();

    // Instantiate plugins.
    auto action = Action{system};

    std::cout << "Setting actuator...\n";
    const Action::Result set_actuator_result = action.set_actuator(index, value);

    if (set_actuator_result != Action::Result::Success) {
        std::cerr << "Setting actuator failed:" << set_actuator_result << '\n';
        return 1;
    }

    return 0;
}

# Surveillance, Search & Rescue

Surveillance and Search & Rescue drones have similar requirements to mapping drones. The main differences are that, in addition to flying a planned survey area, they typically need good standalone control over the camera for image and video capture, and they may need to be able to work during both day and night

Use a camera that supports the MAVLink Camera Protocol (opens new window) as this supports image and video capture, zooming, storage management, multiple cameras on the same vehicle and switching between them, etc. These cameras can be controlled either manually from QGroundControl or via MAVSDK (for both standalone camera operations (opens new window) and in missions (opens new window)). See Camera triggering for information on how to configure your camera to work with MAVLink.

注解

Cameras connected directly to the flight control only support camera triggering, and are unlikely to be suitable for most surveillance/search work.

A search and rescue drone may also need to carry cargo, for example, emergency supplies for a stranded hiker. See Cargo Drones above for information about payload delivery.