MissionCommands.cc 6.57 KB
Newer Older
Don Gagne's avatar
Don Gagne committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/*===================================================================
QGroundControl Open Source Ground Control Station

(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>

This file is part of the QGROUNDCONTROL project

    QGROUNDCONTROL is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    QGROUNDCONTROL is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.

======================================================================*/

#include "MissionCommands.h"
#include "FactMetaData.h"
25 26 27 28
#include "Vehicle.h"
#include "FirmwarePluginManager.h"
#include "QGCApplication.h"
#include "QGroundControlQmlGlobal.h"
Don Gagne's avatar
Don Gagne committed
29

30 31
#include <QQmlEngine>

Don Gagne's avatar
Don Gagne committed
32 33
MissionCommands::MissionCommands(QGCApplication* app)
    : QGCTool(app)
34
    , _commonMissionCommands(QStringLiteral(":/json/MavCmdInfoCommon.json"))
Don Gagne's avatar
Don Gagne committed
35
{
36 37 38 39 40
}

void MissionCommands::setToolbox(QGCToolbox* toolbox)
{
    QGCTool::setToolbox(toolbox);
Don Gagne's avatar
Don Gagne committed
41

42 43 44 45
    // Setup overrides
    QString overrideCommonJsonFilename;
    QString overrideFixedWingJsonFilename;
    QString overrideMultiRotorJsonFilename;
Don Gagne's avatar
Don Gagne committed
46

47 48
    QList<MAV_AUTOPILOT> firmwareList;
    firmwareList << MAV_AUTOPILOT_GENERIC << MAV_AUTOPILOT_PX4 << MAV_AUTOPILOT_ARDUPILOTMEGA;
Don Gagne's avatar
Don Gagne committed
49

50 51
    foreach (MAV_AUTOPILOT firmwareType, firmwareList) {
        FirmwarePlugin* plugin = _toolbox->firmwarePluginManager()->firmwarePluginForAutopilot(firmwareType, MAV_TYPE_QUADROTOR);
Don Gagne's avatar
Don Gagne committed
52

53 54 55 56
        plugin->missionCommandOverrides(overrideCommonJsonFilename, overrideFixedWingJsonFilename, overrideMultiRotorJsonFilename);
        _autopilotToCommonMissionCommands[firmwareType] =       new MissionCommandList(overrideCommonJsonFilename);
        _autopilotToFixedWingMissionCommands[firmwareType] =    new MissionCommandList(overrideFixedWingJsonFilename);
        _autopilotToMultiRotorMissionCommands[firmwareType] =   new MissionCommandList(overrideMultiRotorJsonFilename);
Don Gagne's avatar
Don Gagne committed
57 58
    }

59 60
    _createCategories();
}
Don Gagne's avatar
Don Gagne committed
61

62 63 64 65 66 67
/// Create category hierarchy for support commands
void MissionCommands::_createCategories(void)
{
    // FIXME: This isn't quite right since it's hardcoding the firmware providers. But ok for now.
    QList<MAV_AUTOPILOT>    firmwareList;
    firmwareList << MAV_AUTOPILOT_GENERIC << MAV_AUTOPILOT_PX4 << MAV_AUTOPILOT_ARDUPILOTMEGA;
Don Gagne's avatar
Don Gagne committed
68

69 70
    foreach (MAV_AUTOPILOT firmwareType, firmwareList) {
        FirmwarePlugin* plugin = _toolbox->firmwarePluginManager()->firmwarePluginForAutopilot(firmwareType, MAV_TYPE_QUADROTOR);
Don Gagne's avatar
Don Gagne committed
71

72 73 74 75 76
        bool allCommandsSupported = false;
        QList<MAV_CMD> cmdList = plugin->supportedMissionCommands();
        if (cmdList.isEmpty()) {
            allCommandsSupported = true;
            cmdList = _commonMissionCommands.commandsIds();
Don Gagne's avatar
Don Gagne committed
77 78
        }

79 80
        foreach (MAV_CMD command, cmdList) {
            MavCmdInfo* mavCmdInfo = _commonMissionCommands.getMavCmdInfo(command);
Don Gagne's avatar
Don Gagne committed
81

Don Gagne's avatar
Don Gagne committed
82 83 84 85 86 87 88 89
            if (mavCmdInfo) {
                if (mavCmdInfo->friendlyEdit()) {
                    _categoryToMavCmdListMap[firmwareType][mavCmdInfo->category()].append(command);
                } else if (!allCommandsSupported) {
                    qWarning() << "Attempt to add non friendly edit supported command" << command;
                }
            } else {
                qCDebug(MissionCommandsLog) << "Command missing from json" << command;
Don Gagne's avatar
Don Gagne committed
90 91 92
            }
        }
    }
93

Don Gagne's avatar
Don Gagne committed
94
}
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111

MAV_AUTOPILOT MissionCommands::_firmwareTypeFromVehicle(Vehicle* vehicle) const
{
    if (vehicle) {
        return vehicle->firmwareType();
    } else {
        QSettings settings;

        // FIXME: Hack duplicated code from QGroundControlQmlGlobal. Had to do this for now since
        // QGroundControlQmlGlobal is not available from C++ side.

        return (MAV_AUTOPILOT)settings.value("OfflineEditingFirmwareType", MAV_AUTOPILOT_ARDUPILOTMEGA).toInt();
    }
}

QString MissionCommands::categoryFromCommand(MavlinkQmlSingleton::Qml_MAV_CMD command) const
{
112
    return _commonMissionCommands.getMavCmdInfo((MAV_CMD)command)->category();
113 114 115 116
}

QVariant MissionCommands::getCommandsForCategory(Vehicle* vehicle, const QString& category) const
{
117 118 119 120 121 122 123 124
    QmlObjectListModel* list = new QmlObjectListModel();
    QQmlEngine::setObjectOwnership(list, QQmlEngine::JavaScriptOwnership);

    foreach (MAV_CMD command, _categoryToMavCmdListMap[_firmwareTypeFromVehicle(vehicle)][category]) {
        list->append(getMavCmdInfo(command, vehicle));
    }

    return QVariant::fromValue(list);
125 126 127 128 129 130
}

const QStringList MissionCommands::categories(Vehicle* vehicle) const
{
    QStringList list;

131
    foreach (const QString &category, _categoryToMavCmdListMap[_firmwareTypeFromVehicle(vehicle)].keys()) {
132 133 134 135 136 137
        list << category;
    }

    return list;
}

138
bool MissionCommands::contains(MAV_CMD command) const
139
{
140 141
    return _commonMissionCommands.contains(command);
}
142

143 144 145 146 147 148
MavCmdInfo* MissionCommands::getMavCmdInfo(MAV_CMD command, Vehicle* vehicle) const
{
    if (!contains(command)) {
        qWarning() << "Unknown command" << command;
        return NULL;
    }
149

150 151
    MavCmdInfo*     mavCmdInfo = NULL;
    MAV_AUTOPILOT   firmwareType = _firmwareTypeFromVehicle(vehicle);
152

153 154
    if (vehicle) {
        if (vehicle->fixedWing()) {
Don Gagne's avatar
Don Gagne committed
155
            if (_autopilotToFixedWingMissionCommands.contains(firmwareType) && _autopilotToFixedWingMissionCommands[firmwareType]->contains(command)) {
156 157 158
                mavCmdInfo = _autopilotToFixedWingMissionCommands[firmwareType]->getMavCmdInfo(command);
            }
        } else if (vehicle->multiRotor()) {
Don Gagne's avatar
Don Gagne committed
159
            if (_autopilotToMultiRotorMissionCommands.contains(firmwareType) && _autopilotToMultiRotorMissionCommands[firmwareType]->contains(command)) {
160 161
                mavCmdInfo = _autopilotToMultiRotorMissionCommands[firmwareType]->getMavCmdInfo(command);
            }
162 163
        }
    }
164

Don Gagne's avatar
Don Gagne committed
165
    if (!mavCmdInfo && _autopilotToCommonMissionCommands.contains(firmwareType) && _autopilotToCommonMissionCommands[firmwareType]->contains(command)) {
166 167 168
        mavCmdInfo = _autopilotToCommonMissionCommands[firmwareType]->getMavCmdInfo(command);
    }

169 170 171 172 173 174 175 176 177 178
    if (!mavCmdInfo) {
        mavCmdInfo = _commonMissionCommands.getMavCmdInfo(command);
    }

    return mavCmdInfo;
}

QList<MAV_CMD> MissionCommands::commandsIds(void) const
{
    return _commonMissionCommands.commandsIds();
179
}