APMAutoPilotPlugin.cc 9.47 KB
Newer Older
1 2
/****************************************************************************
 *
Gus Grubba's avatar
Gus Grubba committed
3
 * (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
4 5 6 7 8
 *
 * 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
9

10 11 12

#include "APMAutoPilotPlugin.h"
#include "UAS.h"
13 14 15 16
#include "APMParameterMetaData.h"
#include "APMFirmwarePlugin.h"
#include "ArduCopterFirmwarePlugin.h"
#include "ArduRoverFirmwarePlugin.h"
17
#include "VehicleComponent.h"
18 19 20 21 22 23
#include "APMAirframeComponent.h"
#include "APMFlightModesComponent.h"
#include "APMRadioComponent.h"
#include "APMSafetyComponent.h"
#include "APMTuningComponent.h"
#include "APMSensorsComponent.h"
Don Gagne's avatar
Don Gagne committed
24
#include "APMPowerComponent.h"
25
#include "APMMotorComponent.h"
Don Gagne's avatar
Don Gagne committed
26
#include "APMCameraComponent.h"
27
#include "APMLightsComponent.h"
28
#include "APMSubFrameComponent.h"
DonLakeFlyer's avatar
DonLakeFlyer committed
29
#include "APMFollowComponent.h"
30
#include "ESP8266Component.h"
DonLakeFlyer's avatar
DonLakeFlyer committed
31
#include "APMHeliComponent.h"
32
#include "QGCApplication.h"
33
#include "ParameterManager.h"
34

35
#if !defined(NO_SERIAL_LINK) && !defined(__android__)
36
#include <QSerialPortInfo>
37
#endif
38 39

/// This is the AutoPilotPlugin implementatin for the MAV_AUTOPILOT_ARDUPILOT type.
40
APMAutoPilotPlugin::APMAutoPilotPlugin(Vehicle* vehicle, QObject* parent)
DonLakeFlyer's avatar
DonLakeFlyer committed
41
    : AutoPilotPlugin           (vehicle, parent)
42
    , _incorrectParameterVersion(false)
43 44 45 46 47 48 49 50 51 52 53 54 55
    , _airframeComponent        (nullptr)
    , _cameraComponent          (nullptr)
    , _lightsComponent          (nullptr)
    , _subFrameComponent        (nullptr)
    , _flightModesComponent     (nullptr)
    , _powerComponent           (nullptr)
    , _motorComponent           (nullptr)
    , _radioComponent           (nullptr)
    , _safetyComponent          (nullptr)
    , _sensorsComponent         (nullptr)
    , _tuningComponent          (nullptr)
    , _esp8266Component         (nullptr)
    , _heliComponent            (nullptr)
56 57
#if 0
    // Follow me not ready for Stable
DonLakeFlyer's avatar
DonLakeFlyer committed
58
    , _followComponent          (nullptr)
59
#endif
60
{
61
#if !defined(NO_SERIAL_LINK) && !defined(__android__)
62
    connect(vehicle->parameterManager(), &ParameterManager::parametersReadyChanged, this, &APMAutoPilotPlugin::_checkForBadCubeBlack);
63
#endif
64 65 66 67 68 69 70 71 72
}

APMAutoPilotPlugin::~APMAutoPilotPlugin()
{

}

const QVariantList& APMAutoPilotPlugin::vehicleComponents(void)
{
73
    if (_components.count() == 0 && !_incorrectParameterVersion) {
74
        if (_vehicle->parameterManager()->parametersReady()) {
75
            _airframeComponent = new APMAirframeComponent(_vehicle, this);
76 77
            _airframeComponent->setupTriggerSignals();
            _components.append(QVariant::fromValue((VehicleComponent*)_airframeComponent));
Don Gagne's avatar
Don Gagne committed
78

79
            if ( _vehicle->supportsRadio() ) {
80 81 82 83
                _radioComponent = new APMRadioComponent(_vehicle, this);
                _radioComponent->setupTriggerSignals();
                _components.append(QVariant::fromValue((VehicleComponent*)_radioComponent));
            }
Don Gagne's avatar
Don Gagne committed
84

85
            // No flight modes component for Sub versions 3.5 and up
86
            if (!_vehicle->sub() || (_vehicle->versionCompare(3, 5, 0) < 0)) {
87 88 89 90
                _flightModesComponent = new APMFlightModesComponent(_vehicle, this);
                _flightModesComponent->setupTriggerSignals();
                _components.append(QVariant::fromValue((VehicleComponent*)_flightModesComponent));
            }
91

Don Gagne's avatar
Don Gagne committed
92
            _sensorsComponent = new APMSensorsComponent(_vehicle, this);
93 94
            _sensorsComponent->setupTriggerSignals();
            _components.append(QVariant::fromValue((VehicleComponent*)_sensorsComponent));
Don Gagne's avatar
Don Gagne committed
95

Don Gagne's avatar
Don Gagne committed
96 97 98 99
            _powerComponent = new APMPowerComponent(_vehicle, this);
            _powerComponent->setupTriggerSignals();
            _components.append(QVariant::fromValue((VehicleComponent*)_powerComponent));

100
            if (!_vehicle->sub() || (_vehicle->sub() && _vehicle->versionCompare(3, 5, 3) >= 0)) {
101
                _motorComponent = new APMMotorComponent(_vehicle, this);
Don Gagne's avatar
Don Gagne committed
102 103 104 105
                _motorComponent->setupTriggerSignals();
                _components.append(QVariant::fromValue((VehicleComponent*)_motorComponent));
            }

Don Gagne's avatar
Don Gagne committed
106
            _safetyComponent = new APMSafetyComponent(_vehicle, this);
107 108
            _safetyComponent->setupTriggerSignals();
            _components.append(QVariant::fromValue((VehicleComponent*)_safetyComponent));
Don Gagne's avatar
Don Gagne committed
109

110 111 112
#if 0
    // Follow me not ready for Stable

113
            if ((qobject_cast<ArduCopterFirmwarePlugin*>(_vehicle->firmwarePlugin()) || qobject_cast<ArduRoverFirmwarePlugin*>(_vehicle->firmwarePlugin())) &&
DonLakeFlyer's avatar
DonLakeFlyer committed
114 115 116 117 118
                    _vehicle->parameterManager()->parameterExists(-1, QStringLiteral("FOLL_ENABLE"))) {
                _followComponent = new APMFollowComponent(_vehicle, this);
                _followComponent->setupTriggerSignals();
                _components.append(QVariant::fromValue((VehicleComponent*)_followComponent));
            }
119
#endif
DonLakeFlyer's avatar
DonLakeFlyer committed
120

121
            if (_vehicle->vehicleType() == MAV_TYPE_HELICOPTER && (_vehicle->versionCompare(4, 0, 0) >= 0)) {
DonLakeFlyer's avatar
DonLakeFlyer committed
122 123 124 125 126
                _heliComponent = new APMHeliComponent(_vehicle, this);
                _heliComponent->setupTriggerSignals();
                _components.append(QVariant::fromValue((VehicleComponent*)_heliComponent));
            }

Don Gagne's avatar
Don Gagne committed
127
            _tuningComponent = new APMTuningComponent(_vehicle, this);
128 129
            _tuningComponent->setupTriggerSignals();
            _components.append(QVariant::fromValue((VehicleComponent*)_tuningComponent));
130

Don Gagne's avatar
Don Gagne committed
131 132 133 134
            _cameraComponent = new APMCameraComponent(_vehicle, this);
            _cameraComponent->setupTriggerSignals();
            _components.append(QVariant::fromValue((VehicleComponent*)_cameraComponent));

135 136 137 138
            if (_vehicle->sub()) {
                _lightsComponent = new APMLightsComponent(_vehicle, this);
                _lightsComponent->setupTriggerSignals();
                _components.append(QVariant::fromValue((VehicleComponent*)_lightsComponent));
139

140
                if(_vehicle->versionCompare(3, 5, 0) >= 0) {
141 142 143 144
                    _subFrameComponent = new APMSubFrameComponent(_vehicle, this);
                    _subFrameComponent->setupTriggerSignals();
                    _components.append(QVariant::fromValue((VehicleComponent*)_subFrameComponent));
                }
145 146
            }

Don Gagne's avatar
Don Gagne committed
147
            //-- Is there an ESP8266 Connected?
148
            if(_vehicle->parameterManager()->parameterExists(MAV_COMP_ID_UDP_BRIDGE, "SW_VER")) {
Don Gagne's avatar
Don Gagne committed
149 150 151 152
                _esp8266Component = new ESP8266Component(_vehicle, this);
                _esp8266Component->setupTriggerSignals();
                _components.append(QVariant::fromValue((VehicleComponent*)_esp8266Component));
            }
153 154 155 156 157 158
        } else {
            qWarning() << "Call to vehicleCompenents prior to parametersReady";
        }
    }

    return _components;
159
}
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194

QString APMAutoPilotPlugin::prerequisiteSetup(VehicleComponent* component) const
{
    bool requiresAirframeCheck = false;

    if (qobject_cast<const APMFlightModesComponent*>(component)) {
        if (_airframeComponent && !_airframeComponent->setupComplete()) {
            return _airframeComponent->name();
        }
        if (_radioComponent && !_radioComponent->setupComplete()) {
            return _radioComponent->name();
        }
        requiresAirframeCheck = true;
    } else if (qobject_cast<const APMRadioComponent*>(component)) {
        requiresAirframeCheck = true;
    } else if (qobject_cast<const APMCameraComponent*>(component)) {
        requiresAirframeCheck = true;
    } else if (qobject_cast<const APMPowerComponent*>(component)) {
        requiresAirframeCheck = true;
    } else if (qobject_cast<const APMSafetyComponent*>(component)) {
        requiresAirframeCheck = true;
    } else if (qobject_cast<const APMTuningComponent*>(component)) {
        requiresAirframeCheck = true;
    } else if (qobject_cast<const APMSensorsComponent*>(component)) {
        requiresAirframeCheck = true;
    }

    if (requiresAirframeCheck) {
        if (_airframeComponent && !_airframeComponent->setupComplete()) {
            return _airframeComponent->name();
        }
    }

    return QString();
}
195

196
#if !defined(NO_SERIAL_LINK) && !defined(__android__)
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
/// The following code is executed when the Vehicle is parameter ready. It checks for the service bulletin against Cube Blacks.
void APMAutoPilotPlugin::_checkForBadCubeBlack(void)
{
    bool cubeBlackFound = false;
    for (const QVariant& varLink: _vehicle->links()) {
        SerialLink* serialLink = varLink.value<SerialLink*>();
        if (serialLink && QSerialPortInfo(*serialLink->_hackAccessToPort()).description().contains(QStringLiteral("CubeBlack"))) {
            cubeBlackFound = true;
        }

    }
    if (!cubeBlackFound) {
        return;
    }

    ParameterManager* paramMgr = _vehicle->parameterManager();

    QString paramAcc3("INS_ACC3_ID");
    QString paramGyr3("INS_GYR3_ID");
    QString paramEnableMask("INS_ENABLE_MASK");

    if (paramMgr->parameterExists(-1, paramAcc3) && paramMgr->getParameter(-1, paramAcc3)->rawValue().toInt() == 0 &&
            paramMgr->parameterExists(-1, paramGyr3) && paramMgr->getParameter(-1, paramGyr3)->rawValue().toInt() == 0 &&
            paramMgr->parameterExists(-1, paramEnableMask) && paramMgr->getParameter(-1, paramEnableMask)->rawValue().toInt() >= 7) {
221
        qgcApp()->showAppMessage(tr("WARNING: The flight board you are using has a critical service bulletin against it which advises against flying. For details see: https://discuss.cubepilot.org/t/sb-0000002-critical-service-bulletin-for-cubes-purchased-between-january-2019-to-present-do-not-fly/406"));
222 223 224

    }
}
225
#endif