APMRadioComponent.cc 4.74 KB
Newer Older
1 2 3 4 5 6 7 8 9
/****************************************************************************
 *
 *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

Don Gagne's avatar
Don Gagne committed
10 11 12

#include "APMRadioComponent.h"
#include "APMAutoPilotPlugin.h"
13
#include "APMAirframeComponent.h"
14
#include "ParameterManager.h"
Don Gagne's avatar
Don Gagne committed
15 16

APMRadioComponent::APMRadioComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent) :
17
    VehicleComponent(vehicle, autopilot, parent),
Don Gagne's avatar
Don Gagne committed
18 19
    _name(tr("Radio"))
{
Don Gagne's avatar
Don Gagne committed
20 21 22
    _mapParams << QStringLiteral("RCMAP_ROLL") << QStringLiteral("RCMAP_PITCH") << QStringLiteral("RCMAP_YAW") << QStringLiteral("RCMAP_THROTTLE");

    foreach (const QString& mapParam, _mapParams) {
23
        Fact* fact = _vehicle->parameterManager()->getParameter(-1, mapParam);
Don Gagne's avatar
Don Gagne committed
24 25 26 27
        connect(fact, &Fact::valueChanged, this, &APMRadioComponent::_triggerChanged);
    }

    _connectSetupTriggers();
Don Gagne's avatar
Don Gagne committed
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
}

QString APMRadioComponent::name(void) const
{
    return _name;
}

QString APMRadioComponent::description(void) const
{
    return tr("The Radio Component is used to setup which channels on your RC Transmitter you will use for each vehicle control such as Roll, Pitch, Yaw and Throttle. "
              "It also allows you to assign switches and dials to the various flight modes. "
              "Prior to flight you must also calibrate the extents for all of your channels.");
}

QString APMRadioComponent::iconResource(void) const
{
44
    return QStringLiteral("/qmlimages/RadioComponentIcon.png");
Don Gagne's avatar
Don Gagne committed
45 46 47 48 49 50 51 52 53 54
}

bool APMRadioComponent::requiresSetup(void) const
{
    return true;
}

bool APMRadioComponent::setupComplete(void) const
{
    // The best we can do to detect the need for a radio calibration is look for attitude
Don Gagne's avatar
Don Gagne committed
55 56 57 58 59
    // controls to be mapped as well as all attitude control rc min/max/trim still at defaults.
    QList<int> mapValues;

    // First check for all attitude controls mapped
    for (int i=0; i<_mapParams.count(); i++) {
60
        mapValues << _vehicle->parameterManager()->getParameter(FactSystem::defaultComponentId, _mapParams[i])->rawValue().toInt();
Don Gagne's avatar
Don Gagne committed
61
        if (mapValues[i] <= 0) {
Don Gagne's avatar
Don Gagne committed
62 63 64
            return false;
        }
    }
Don Gagne's avatar
Don Gagne committed
65 66 67

    // Next check RC#_MIN/MAX/TRIM all at defaults
    foreach (const QString& mapParam, _mapParams) {
68 69
        int channel = _vehicle->parameterManager()->getParameter(-1, mapParam)->rawValue().toInt();
        if (_vehicle->parameterManager()->getParameter(-1, QString("RC%1_MIN").arg(channel))->rawValue().toInt() != 1100) {
Don Gagne's avatar
Don Gagne committed
70 71
            return true;
        }
72
        if (_vehicle->parameterManager()->getParameter(-1, QString("RC%1_MAX").arg(channel))->rawValue().toInt() != 1900) {
Don Gagne's avatar
Don Gagne committed
73 74
            return true;
        }
75
        if (_vehicle->parameterManager()->getParameter(-1, QString("RC%1_TRIM").arg(channel))->rawValue().toInt() != 1500) {
Don Gagne's avatar
Don Gagne committed
76 77 78
            return true;
        }
    }
Don Gagne's avatar
Don Gagne committed
79
    
Don Gagne's avatar
Don Gagne committed
80
    return false;
Don Gagne's avatar
Don Gagne committed
81 82 83 84
}

QStringList APMRadioComponent::setupCompleteChangedTriggerList(void) const
{
Don Gagne's avatar
Don Gagne committed
85 86
    // APMRadioComponent manages it's own triggers
    return QStringList();
Don Gagne's avatar
Don Gagne committed
87 88 89 90
}

QUrl APMRadioComponent::setupSource(void) const
{
91
    return QUrl::fromUserInput(QStringLiteral("qrc:/qml/RadioComponent.qml"));
Don Gagne's avatar
Don Gagne committed
92 93 94 95
}

QUrl APMRadioComponent::summaryQmlSource(void) const
{
96
    return QUrl::fromUserInput(QStringLiteral("qrc:/qml/APMRadioComponentSummary.qml"));
Don Gagne's avatar
Don Gagne committed
97 98
}

Don Gagne's avatar
Don Gagne committed
99 100 101 102 103 104 105 106 107 108
void APMRadioComponent::_connectSetupTriggers(void)
{
    // Disconnect previous triggers
    foreach(Fact* fact, _triggerFacts) {
        disconnect(fact, &Fact::valueChanged, this, &APMRadioComponent::_triggerChanged);
    }
    _triggerFacts.clear();

    // Get the channels for attitude controls and connect to those values for triggers
    foreach (const QString& mapParam, _mapParams) {
109
        int channel = _vehicle->parameterManager()->getParameter(FactSystem::defaultComponentId, mapParam)->rawValue().toInt();
Don Gagne's avatar
Don Gagne committed
110

111
        Fact* fact = _vehicle->parameterManager()->getParameter(-1, QString("RC%1_MIN").arg(channel));
Don Gagne's avatar
Don Gagne committed
112 113 114
        _triggerFacts << fact;
        connect(fact, &Fact::valueChanged, this, &APMRadioComponent::_triggerChanged);

115
        fact = _vehicle->parameterManager()->getParameter(-1, QString("RC%1_MAX").arg(channel));
Don Gagne's avatar
Don Gagne committed
116 117 118
        _triggerFacts << fact;
        connect(fact, &Fact::valueChanged, this, &APMRadioComponent::_triggerChanged);

119
        fact = _vehicle->parameterManager()->getParameter(-1, QString("RC%1_TRIM").arg(channel));
Don Gagne's avatar
Don Gagne committed
120 121 122 123 124 125 126 127 128 129 130 131
        _triggerFacts << fact;
        connect(fact, &Fact::valueChanged, this, &APMRadioComponent::_triggerChanged);
    }
}

void APMRadioComponent::_triggerChanged(void)
{
    emit setupCompleteChanged(setupComplete());

    // Control mapping may have changed so we need to reset triggers
    _connectSetupTriggers();
}