QGCPX4VehicleConfig.cc 10.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
// On Windows (for VS2010) stdint.h contains the limits normally contained in limits.h
// It also needs the __STDC_LIMIT_MACROS macro defined in order to include them (done
// in qgroundcontrol.pri).
#ifdef WIN32
#include <stdint.h>
#else
#include <limits.h>
#endif

#include <QTimer>
#include <QDir>
#include <QXmlStreamReader>
13
#include <QLabel>
14 15

#include "QGCPX4VehicleConfig.h"
16

17 18
#include "QGC.h"
#include "QGCToolWidget.h"
19
#include "UASManager.h"
20
#include "LinkManager.h"
21
#include "UASParameterCommsMgr.h"
22
#include "ui_QGCPX4VehicleConfig.h"
23
#include "px4_configuration/QGCPX4AirframeConfig.h"
24
#include "px4_configuration/QGCPX4SensorCalibration.h"
25
#include "px4_configuration/PX4RCCalibration.h"
26

27
#include "PX4FirmwareUpgrade.h"
tstellanova's avatar
tstellanova committed
28

29 30 31 32 33 34
#define WIDGET_INDEX_FIRMWARE 0
#define WIDGET_INDEX_RC 1
#define WIDGET_INDEX_SENSOR_CAL 2
#define WIDGET_INDEX_AIRFRAME_CONFIG 3
#define WIDGET_INDEX_GENERAL_CONFIG 4
#define WIDGET_INDEX_ADV_CONFIG 5
35 36 37 38

#define MIN_PWM_VAL 800
#define MAX_PWM_VAL 2200

39 40 41
QGCPX4VehicleConfig::QGCPX4VehicleConfig(QWidget *parent) :
    QWidget(parent),
    mav(NULL),
42
    px4AirframeConfig(NULL),
Lorenz Meier's avatar
Lorenz Meier committed
43 44
    planeBack(":/files/images/px4/rc/cessna_back.png"),
    planeSide(":/files/images/px4/rc/cessna_side.png"),
Lorenz Meier's avatar
Lorenz Meier committed
45
    px4SensorCalibration(NULL),
46 47 48 49 50 51 52
    ui(new Ui::QGCPX4VehicleConfig)
{
    doneLoadingConfig = false;

    setObjectName("QGC_VEHICLECONFIG");
    ui->setupUi(this);

53 54 55 56 57
    ui->advancedMenuButton->setEnabled(false);
    ui->airframeMenuButton->setEnabled(false);
    ui->sensorMenuButton->setEnabled(false);
    ui->rcMenuButton->setEnabled(false);

58 59 60
    px4AirframeConfig = new QGCPX4AirframeConfig(this);
    ui->airframeLayout->addWidget(px4AirframeConfig);

61 62 63
    px4SensorCalibration = new QGCPX4SensorCalibration(this);
    ui->sensorLayout->addWidget(px4SensorCalibration);

64 65 66
    px4RCCalibration = new PX4RCCalibration(this);
    ui->rcLayout->addWidget(px4RCCalibration);
    
67 68
    PX4FirmwareUpgrade* firmwareUpgrade = new PX4FirmwareUpgrade(this);
    ui->firmwareLayout->addWidget(firmwareUpgrade);
69

70 71 72 73
    connect(ui->rcMenuButton,SIGNAL(clicked()),
            this,SLOT(rcMenuButtonClicked()));
    connect(ui->sensorMenuButton,SIGNAL(clicked()),
            this,SLOT(sensorMenuButtonClicked()));
74 75 76 77 78 79
    connect(ui->flightModeMenuButton, SIGNAL(clicked()),
            this, SLOT(flightModeMenuButtonClicked()));
    connect(ui->safetyConfigButton, SIGNAL(clicked()),
            this, SLOT(safetyConfigMenuButtonClicked()));
    connect(ui->tuningMenuButton,SIGNAL(clicked()),
            this,SLOT(tuningMenuButtonClicked()));
80 81 82 83 84 85
    connect(ui->advancedMenuButton,SIGNAL(clicked()),
            this,SLOT(advancedMenuButtonClicked()));
    connect(ui->airframeMenuButton, SIGNAL(clicked()),
            this, SLOT(airframeMenuButtonClicked()));
    connect(ui->firmwareMenuButton, SIGNAL(clicked()),
            this, SLOT(firmwareMenuButtonClicked()));
86

87
    //TODO connect buttons here to save/clear actions?
88 89 90
    UASInterface* tmpMav = UASManager::instance()->getActiveUAS();
    if (tmpMav) {
        ui->pendingCommitsWidget->initWithUAS(tmpMav);
tstellanova's avatar
tstellanova committed
91
        ui->pendingCommitsWidget->update();
92
        setActiveUAS(tmpMav);
tstellanova's avatar
tstellanova committed
93
    }
94

95 96 97
    connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)),
            this, SLOT(setActiveUAS(UASInterface*)));

98
    firmwareMenuButtonClicked();
99
}
100

101 102 103 104 105
QGCPX4VehicleConfig::~QGCPX4VehicleConfig()
{
    delete ui;
}

106 107
void QGCPX4VehicleConfig::rcMenuButtonClicked()
{
108
    ui->stackedWidget->setCurrentWidget(ui->rcTab);
Lorenz Meier's avatar
Lorenz Meier committed
109
    ui->tabTitleLabel->setText(tr("Radio Calibration"));
110 111 112 113
}

void QGCPX4VehicleConfig::sensorMenuButtonClicked()
{
114
    ui->stackedWidget->setCurrentWidget(ui->sensorTab);
Lorenz Meier's avatar
Lorenz Meier committed
115
    ui->tabTitleLabel->setText(tr("Sensor Calibration"));
116 117
}

118 119
void QGCPX4VehicleConfig::tuningMenuButtonClicked()
{
Lorenz Meier's avatar
Lorenz Meier committed
120
    ui->stackedWidget->setCurrentWidget(ui->tuningTab);
121 122 123 124 125 126 127 128 129 130
    ui->tabTitleLabel->setText(tr("Controller Tuning"));
}

void QGCPX4VehicleConfig::flightModeMenuButtonClicked()
{
    ui->stackedWidget->setCurrentWidget(ui->flightModeTab);
    ui->tabTitleLabel->setText(tr("Flight Mode Configuration"));
}

void QGCPX4VehicleConfig::safetyConfigMenuButtonClicked()
131
{
132 133
    ui->stackedWidget->setCurrentWidget(ui->safetyConfigTab);
    ui->tabTitleLabel->setText(tr("Safety Feature Configuration"));
134 135 136 137
}

void QGCPX4VehicleConfig::advancedMenuButtonClicked()
{
138
    ui->stackedWidget->setCurrentWidget(ui->advancedTab);
Lorenz Meier's avatar
Lorenz Meier committed
139
    ui->tabTitleLabel->setText(tr("Advanced Configuration Options"));
140 141
}

142 143
void QGCPX4VehicleConfig::airframeMenuButtonClicked()
{
144
    ui->stackedWidget->setCurrentWidget(ui->airframeTab);
Lorenz Meier's avatar
Lorenz Meier committed
145
    ui->tabTitleLabel->setText(tr("Airframe Configuration"));
146 147
}

148 149
void QGCPX4VehicleConfig::firmwareMenuButtonClicked()
{
150
    ui->stackedWidget->setCurrentWidget(ui->firmwareTab);
Lorenz Meier's avatar
Lorenz Meier committed
151
    ui->tabTitleLabel->setText(tr("Firmware Upgrade"));
152 153
}

154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
void QGCPX4VehicleConfig::menuButtonClicked()
{
    QPushButton *button = qobject_cast<QPushButton*>(sender());
    if (!button)
    {
        return;
    }
    if (buttonToWidgetMap.contains(button))
    {
        ui->stackedWidget->setCurrentWidget(buttonToWidgetMap[button]);
    }

}

void QGCPX4VehicleConfig::setActiveUAS(UASInterface* active)
{
    // Hide items if NULL and abort
    if (!active) {
        return;
    }


tstellanova's avatar
tstellanova committed
176 177 178
    // Do nothing if UAS is already visible
    if (mav == active)
        return;
179 180 181

    if (mav)
    {
182

183
        //TODO use paramCommsMgr instead
184 185 186
        disconnect(mav, SIGNAL(parameterChanged(int,int,QString,QVariant)), this,
                   SLOT(parameterChanged(int,int,QString,QVariant)));

187 188 189 190 191
        foreach(QWidget* child, ui->airframeLayout->findChildren<QWidget*>())
        {
            child->deleteLater();
        }

192
        // And then delete any custom tabs
193
        foreach(QWidget* child, additionalTabs) {
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
            child->deleteLater();
        }
        additionalTabs.clear();

        toolWidgets.clear();
        paramToWidgetMap.clear();
        libParamToWidgetMap.clear();
        systemTypeToParamMap.clear();
        toolToBoxMap.clear();
        paramTooltips.clear();
    }

    // Connect new system
    mav = active;

209 210
    paramMgr = mav->getParamManager();

tstellanova's avatar
tstellanova committed
211
    ui->pendingCommitsWidget->setUAS(mav);
212
    ui->paramTreeWidget->setUAS(mav);
tstellanova's avatar
tstellanova committed
213

214
    //TODO eliminate the separate RC_TYPE call
215 216 217
    mav->requestParameter(0, "RC_TYPE");

    // Connect new system
218
    connect(mav, SIGNAL(parameterChanged(int,int,QString,QVariant)), this,
219
               SLOT(parameterChanged(int,int,QString,QVariant)));
220

221

222
    if (systemTypeToParamMap.contains(mav->getSystemTypeName())) {
223 224
        paramToWidgetMap = systemTypeToParamMap[mav->getSystemTypeName()];
    }
225
    else {
226 227 228 229 230
        //Indication that we have no meta data for this system type.
        qDebug() << "No parameters defined for system type:" << mav->getSystemTypeName();
        paramToWidgetMap = systemTypeToParamMap[mav->getSystemTypeName()];
    }

231
    if (!paramTooltips.isEmpty()) {
232
           mav->getParamManager()->setParamDescriptions(paramTooltips);
233 234 235 236 237 238 239
    }

    qDebug() << "CALIBRATION!! System Type Name:" << mav->getSystemTypeName();

    updateStatus(QString("Reading from system %1").arg(mav->getUASName()));

    // Since a system is now connected, enable the VehicleConfig UI.
240
    // Enable buttons
241
    
Don Gagne's avatar
Don Gagne committed
242
    bool px4Firmware = mav->getAutopilotType() == MAV_AUTOPILOT_PX4;
243 244 245
    ui->airframeMenuButton->setEnabled(px4Firmware);
    ui->sensorMenuButton->setEnabled(px4Firmware);
    ui->rcMenuButton->setEnabled(px4Firmware);
246
    ui->advancedMenuButton->setEnabled(true);
247 248
}

249 250
void QGCPX4VehicleConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value)
{
251
    if (!doneLoadingConfig) {
252 253 254 255 256
        //We do not want to attempt to generate any UI elements until loading of the config file is complete.
        //We should re-request params later if needed, that is not implemented yet.
        return;
    }

257
    if (paramToWidgetMap.contains(parameterName)) {
258 259
        //Main group of parameters of the selected airframe
        paramToWidgetMap.value(parameterName)->setParameterValue(uas,component,parameterName,value);
260
        if (toolToBoxMap.contains(paramToWidgetMap.value(parameterName))) {
261 262
            toolToBoxMap[paramToWidgetMap.value(parameterName)]->show();
        }
263
        else {
264 265 266
            qCritical() << "Widget with no box, possible memory corruption for param:" << parameterName;
        }
    }
267
    else if (libParamToWidgetMap.contains(parameterName)) {
268 269
        //All the library parameters
        libParamToWidgetMap.value(parameterName)->setParameterValue(uas,component,parameterName,value);
270
        if (toolToBoxMap.contains(libParamToWidgetMap.value(parameterName))) {
271 272
            toolToBoxMap[libParamToWidgetMap.value(parameterName)]->show();
        }
273
        else {
274 275 276
            qCritical() << "Widget with no box, possible memory corruption for param:" << parameterName;
        }
    }
277
    else {
278 279
        //Param recieved that we have no metadata for. Search to see if it belongs in a
        //group with some other params
280
        //bool found = false;
281 282
        for (int i=0;i<toolWidgets.size();i++) {
            if (parameterName.startsWith(toolWidgets[i]->objectName())) {
283 284 285
                //It should be grouped with this one, add it.
                toolWidgets[i]->addParam(uas,component,parameterName,value);
                libParamToWidgetMap.insert(parameterName,toolWidgets[i]);
286
                //found  = true;
287 288 289
                break;
            }
        }
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
//        if (!found) {
//            //New param type, create a QGroupBox for it.
//            QWidget* parent = ui->advanceColumnContents;

//            // Create the tool, attaching it to the QGroupBox
//            QGCToolWidget *tool = new QGCToolWidget("", parent);
//            QString tooltitle = parameterName;
//            if (parameterName.split("_").size() > 1) {
//                tooltitle = parameterName.split("_")[0] + "_";
//            }
//            tool->setTitle(tooltitle);
//            tool->setObjectName(tooltitle);
//            //tool->setSettings(set);
//            libParamToWidgetMap.insert(parameterName,tool);
//            toolWidgets.append(tool);
//            tool->addParam(uas, component, parameterName, value);
//            QGroupBox *box = new QGroupBox(parent);
//            box->setTitle(tool->objectName());
//            box->setLayout(new QVBoxLayout(box));
//            box->layout()->addWidget(tool);

//            libParamToWidgetMap.insert(parameterName,tool);
//            toolWidgets.append(tool);
//            ui->advancedColumnLayout->addWidget(box);

//            toolToBoxMap[tool] = box;
//        }
317 318 319 320 321 322
    }

}

void QGCPX4VehicleConfig::updateStatus(const QString& str)
{
323 324
    ui->advancedStatusLabel->setText(str);
    ui->advancedStatusLabel->setStyleSheet("");
325 326 327 328
}

void QGCPX4VehicleConfig::updateError(const QString& str)
{
329 330
    ui->advancedStatusLabel->setText(str);
    ui->advancedStatusLabel->setStyleSheet(QString("QLabel { margin: 0px 2px; font: 14px; color: %1; background-color: %2; }").arg(QGC::colorDarkWhite.name()).arg(QGC::colorMagenta.name()));
331
}