Browse Source

Removing UASes now returns the UI to an almost pristine state. This was done by altering the activeUASSet signal so that it can emit a NULL UAS. Crashes may still exist in autopilot-specific code.

QGC4.4
Bryant 12 years ago
parent
commit
b1fc82ac54
  1. 60
      src/uas/UASManager.cc
  2. 4
      src/uas/UASManager.h
  3. 84
      src/ui/HSIDisplay.cc
  4. 1
      src/ui/HSIDisplay.h
  5. 6
      src/ui/HUD.cc
  6. 76
      src/ui/QGCToolBar.cc
  7. 3
      src/ui/QGCToolBar.h
  8. 282
      src/ui/QGCVehicleConfig.cc
  9. 7
      src/ui/QGCVehicleConfig.h
  10. 12
      src/ui/QGCVehicleConfig.ui
  11. 28
      src/ui/map/QGCMapWidget.cc
  12. 5
      src/ui/map3D/Pixhawk3DWidget.cc
  13. 33
      src/ui/uas/UASControlWidget.cc
  14. 68
      src/ui/uas/UASListWidget.cc
  15. 5
      src/ui/uas/UASListWidget.h
  16. 20
      src/ui/uas/UASQuickView.cc
  17. 90
      src/ui/uas/UASView.cc
  18. 9
      src/ui/uas/UASView.h

60
src/uas/UASManager.cc

@ -310,38 +310,23 @@ void UASManager::removeUAS(UASInterface* uas) @@ -310,38 +310,23 @@ void UASManager::removeUAS(UASInterface* uas)
{
int listindex = systems.indexOf(uas);
// If this is the active UAS, select a new one.
// Remove this system from local data store.
systems.removeAt(listindex);
// If this is the active UAS, select a new one if one exists otherwise
// indicate that there are no active UASes.
if (uas == activeUAS)
{
if (systems.count() > 1)
if (systems.count())
{
// We only set a new UAS if more than one is present
if (listindex != 0)
{
// The system to be removed is not at position 1
// set position one as new active system
setActiveUAS(systems.first());
}
else
{
// The system to be removed is at position 1,
// select the next system
setActiveUAS(systems.at(1));
}
setActiveUAS(systems.first());
}
else
{
// TODO send a null pointer if no UAS is present any more
// This has to be properly tested however, since it might
// crash code parts not handling null pointers correctly.
activeUAS = NULL;
// XXX Not emitting the null pointer yet
setActiveUAS(NULL);
}
}
// Finally delete a local reference to this UAS
systems.removeAt(listindex);
// Notify other UI elements that a UAS is being deleted before finally deleting it.
qDebug() << "Deleting UAS object: " << uas->getUASName();
emit UASDeleted(uas);
@ -449,21 +434,24 @@ UASInterface* UASManager::getUASForId(int id) @@ -449,21 +434,24 @@ UASInterface* UASManager::getUASForId(int id)
void UASManager::setActiveUAS(UASInterface* uas)
{
if (uas != NULL) {
activeUASMutex.lock();
if (activeUAS != NULL) {
emit activeUASStatusChanged(activeUAS, false);
emit activeUASStatusChanged(activeUAS->getUASID(), false);
}
activeUAS = uas;
activeUASMutex.unlock();
// Signal components that the last UAS is no longer active.
activeUASMutex.lock();
if (activeUAS != NULL) {
emit activeUASStatusChanged(activeUAS, false);
emit activeUASStatusChanged(activeUAS->getUASID(), false);
}
activeUAS = uas;
activeUASMutex.unlock();
// And signal that a new UAS is.
emit activeUASSet(activeUAS);
if (activeUAS)
{
activeUAS->setSelected();
emit activeUASSet(uas);
emit activeUASSet(uas->getUASID());
emit activeUASSetListIndex(systems.indexOf(uas));
emit activeUASStatusChanged(uas, true);
emit activeUASStatusChanged(uas->getUASID(), true);
emit activeUASSet(activeUAS->getUASID());
emit activeUASSetListIndex(systems.indexOf(activeUAS));
emit activeUASStatusChanged(activeUAS, true);
emit activeUASStatusChanged(activeUAS->getUASID(), true);
}
}

4
src/uas/UASManager.h

@ -151,12 +151,12 @@ public slots: @@ -151,12 +151,12 @@ public slots:
**/
void addUAS(UASInterface* UAS);
/** @brief Remove a system from the list. Also triggers the UAS to kill itself. */
/** @brief Remove a system from the list. If this is the active UAS, it switches to another one calling setActiveUAS. Also triggers the UAS to kill itself. */
void removeUAS(UASInterface* uas);
/**
* @brief Set a UAS as currently selected
* @brief Set a UAS as currently selected. NULL is a valid value for when no other valid UAS's are available.
*
* @param UAS Unmanned Air System to set
**/

84
src/ui/HSIDisplay.cc

@ -177,12 +177,11 @@ HSIDisplay::HSIDisplay(QWidget *parent) : @@ -177,12 +177,11 @@ HSIDisplay::HSIDisplay(QWidget *parent) :
setStatusTip(tr("View from top in body frame. Scroll with mouse wheel to change the horizontal field of view of the widget."));
connect(&statusClearTimer, SIGNAL(timeout()), this, SLOT(clearStatusMessage()));
statusClearTimer.start(3000);
setActiveUAS(UASManager::instance()->getActiveUAS());
// Listen for the removal of the active UAS.
setActiveUAS(UASManager::instance()->getActiveUAS());
connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)),
this, SLOT(setActiveUAS(UASInterface*)));
setFocusPolicy(Qt::StrongFocus);
}
@ -236,7 +235,7 @@ void HSIDisplay::paintEvent(QPaintEvent * event) @@ -236,7 +235,7 @@ void HSIDisplay::paintEvent(QPaintEvent * event)
void HSIDisplay::renderOverlay()
{
if (!isVisible()) return;
if (!isVisible() || !uas) return;
#if (QGC_EVENTLOOP_DEBUG)
qDebug() << "EVENTLOOP:" << __FILE__ << __LINE__;
#endif
@ -911,9 +910,6 @@ void HSIDisplay::setMetricWidth(double width) @@ -911,9 +910,6 @@ void HSIDisplay::setMetricWidth(double width)
*/
void HSIDisplay::setActiveUAS(UASInterface* uas)
{
if (!uas)
return;
if (this->uas != NULL) {
disconnect(this->uas, SIGNAL(gpsSatelliteStatusChanged(int,int,float,float,float,bool)), this, SLOT(updateSatellite(int,int,float,float,float,bool)));
disconnect(this->uas, SIGNAL(localPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateLocalPosition(UASInterface*,double,double,double,quint64)));
@ -946,47 +942,49 @@ void HSIDisplay::setActiveUAS(UASInterface* uas) @@ -946,47 +942,49 @@ void HSIDisplay::setActiveUAS(UASInterface* uas)
disconnect(this->uas, SIGNAL(actuatorStatusChanged(bool,bool,bool)), this, SLOT(updateActuatorStatus(bool,bool,bool)));
}
connect(uas, SIGNAL(gpsSatelliteStatusChanged(int,int,float,float,float,bool)), this, SLOT(updateSatellite(int,int,float,float,float,bool)));
connect(uas, SIGNAL(localPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateLocalPosition(UASInterface*,double,double,double,quint64)));
connect(uas, SIGNAL(globalPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateGlobalPosition(UASInterface*,double,double,double,quint64)));
connect(uas, SIGNAL(attitudeThrustSetPointChanged(UASInterface*,double,double,double,double,quint64)), this, SLOT(updateAttitudeSetpoints(UASInterface*,double,double,double,double,quint64)));
connect(uas, SIGNAL(positionSetPointsChanged(int,float,float,float,float,quint64)), this, SLOT(updatePositionSetpoints(int,float,float,float,float,quint64)));
connect(uas, SIGNAL(userPositionSetPointsChanged(int,float,float,float,float)), this, SLOT(updateUserPositionSetpoints(int,float,float,float,float)));
connect(uas, SIGNAL(speedChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateSpeed(UASInterface*,double,double,double,quint64)));
connect(uas, SIGNAL(attitudeChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateAttitude(UASInterface*,double,double,double,quint64)));
connect(uas, SIGNAL(attitudeControlEnabled(bool)), this, SLOT(updateAttitudeControllerEnabled(bool)));
connect(uas, SIGNAL(positionXYControlEnabled(bool)), this, SLOT(updatePositionXYControllerEnabled(bool)));
connect(uas, SIGNAL(positionZControlEnabled(bool)), this, SLOT(updatePositionZControllerEnabled(bool)));
connect(uas, SIGNAL(positionYawControlEnabled(bool)), this, SLOT(updatePositionYawControllerEnabled(bool)));
connect(uas, SIGNAL(localizationChanged(UASInterface*,int)), this, SLOT(updateLocalization(UASInterface*,int)));
connect(uas, SIGNAL(visionLocalizationChanged(UASInterface*,int)), this, SLOT(updateVisionLocalization(UASInterface*,int)));
connect(uas, SIGNAL(gpsLocalizationChanged(UASInterface*,int)), this, SLOT(updateGpsLocalization(UASInterface*,int)));
connect(uas, SIGNAL(irUltraSoundLocalizationChanged(UASInterface*,int)), this, SLOT(updateInfraredUltrasoundLocalization(UASInterface*,int)));
connect(uas, SIGNAL(objectDetected(uint,int,int,QString,int,float,float)), this, SLOT(updateObjectPosition(uint,int,int,QString,int,float,float)));
connect(uas, SIGNAL(gyroStatusChanged(bool,bool,bool)), this, SLOT(updateGyroStatus(bool,bool,bool)));
connect(uas, SIGNAL(accelStatusChanged(bool,bool,bool)), this, SLOT(updateAccelStatus(bool,bool,bool)));
connect(uas, SIGNAL(magSensorStatusChanged(bool,bool,bool)), this, SLOT(updateMagSensorStatus(bool,bool,bool)));
connect(uas, SIGNAL(baroStatusChanged(bool,bool,bool)), this, SLOT(updateBaroStatus(bool,bool,bool)));
connect(uas, SIGNAL(airspeedStatusChanged(bool,bool,bool)), this, SLOT(updateAirspeedStatus(bool,bool,bool)));
connect(uas, SIGNAL(opticalFlowStatusChanged(bool,bool,bool)), this, SLOT(updateOpticalFlowStatus(bool,bool,bool)));
connect(uas, SIGNAL(laserStatusChanged(bool,bool,bool)), this, SLOT(updateLaserStatus(bool,bool,bool)));
connect(uas, SIGNAL(groundTruthSensorStatusChanged(bool,bool,bool)), this, SLOT(updateGroundTruthSensorStatus(bool,bool,bool)));
connect(uas, SIGNAL(actuatorStatusChanged(bool,bool,bool)), this, SLOT(updateActuatorStatus(bool,bool,bool)));
if (uas)
{
connect(uas, SIGNAL(gpsSatelliteStatusChanged(int,int,float,float,float,bool)), this, SLOT(updateSatellite(int,int,float,float,float,bool)));
connect(uas, SIGNAL(localPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateLocalPosition(UASInterface*,double,double,double,quint64)));
connect(uas, SIGNAL(globalPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateGlobalPosition(UASInterface*,double,double,double,quint64)));
connect(uas, SIGNAL(attitudeThrustSetPointChanged(UASInterface*,double,double,double,double,quint64)), this, SLOT(updateAttitudeSetpoints(UASInterface*,double,double,double,double,quint64)));
connect(uas, SIGNAL(positionSetPointsChanged(int,float,float,float,float,quint64)), this, SLOT(updatePositionSetpoints(int,float,float,float,float,quint64)));
connect(uas, SIGNAL(userPositionSetPointsChanged(int,float,float,float,float)), this, SLOT(updateUserPositionSetpoints(int,float,float,float,float)));
connect(uas, SIGNAL(speedChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateSpeed(UASInterface*,double,double,double,quint64)));
connect(uas, SIGNAL(attitudeChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateAttitude(UASInterface*,double,double,double,quint64)));
connect(uas, SIGNAL(attitudeControlEnabled(bool)), this, SLOT(updateAttitudeControllerEnabled(bool)));
connect(uas, SIGNAL(positionXYControlEnabled(bool)), this, SLOT(updatePositionXYControllerEnabled(bool)));
connect(uas, SIGNAL(positionZControlEnabled(bool)), this, SLOT(updatePositionZControllerEnabled(bool)));
connect(uas, SIGNAL(positionYawControlEnabled(bool)), this, SLOT(updatePositionYawControllerEnabled(bool)));
connect(uas, SIGNAL(localizationChanged(UASInterface*,int)), this, SLOT(updateLocalization(UASInterface*,int)));
connect(uas, SIGNAL(visionLocalizationChanged(UASInterface*,int)), this, SLOT(updateVisionLocalization(UASInterface*,int)));
connect(uas, SIGNAL(gpsLocalizationChanged(UASInterface*,int)), this, SLOT(updateGpsLocalization(UASInterface*,int)));
connect(uas, SIGNAL(irUltraSoundLocalizationChanged(UASInterface*,int)), this, SLOT(updateInfraredUltrasoundLocalization(UASInterface*,int)));
connect(uas, SIGNAL(objectDetected(uint,int,int,QString,int,float,float)), this, SLOT(updateObjectPosition(uint,int,int,QString,int,float,float)));
connect(uas, SIGNAL(gyroStatusChanged(bool,bool,bool)), this, SLOT(updateGyroStatus(bool,bool,bool)));
connect(uas, SIGNAL(accelStatusChanged(bool,bool,bool)), this, SLOT(updateAccelStatus(bool,bool,bool)));
connect(uas, SIGNAL(magSensorStatusChanged(bool,bool,bool)), this, SLOT(updateMagSensorStatus(bool,bool,bool)));
connect(uas, SIGNAL(baroStatusChanged(bool,bool,bool)), this, SLOT(updateBaroStatus(bool,bool,bool)));
connect(uas, SIGNAL(airspeedStatusChanged(bool,bool,bool)), this, SLOT(updateAirspeedStatus(bool,bool,bool)));
connect(uas, SIGNAL(opticalFlowStatusChanged(bool,bool,bool)), this, SLOT(updateOpticalFlowStatus(bool,bool,bool)));
connect(uas, SIGNAL(laserStatusChanged(bool,bool,bool)), this, SLOT(updateLaserStatus(bool,bool,bool)));
connect(uas, SIGNAL(groundTruthSensorStatusChanged(bool,bool,bool)), this, SLOT(updateGroundTruthSensorStatus(bool,bool,bool)));
connect(uas, SIGNAL(actuatorStatusChanged(bool,bool,bool)), this, SLOT(updateActuatorStatus(bool,bool,bool)));
statusClearTimer.start(3000);
}
else
{
statusClearTimer.stop();
}
this->uas = uas;
resetMAVState();
}
void HSIDisplay::removeUAS(UASInterface* uas)
{
this->uas = NULL;
resetMAVState();
}
void HSIDisplay::updateSpeed(UASInterface* uas, double vx, double vy, double vz, quint64 time)
{
Q_UNUSED(uas);
@ -1091,7 +1089,7 @@ void HSIDisplay::updateAttitude(UASInterface* uas, double roll, double pitch, do @@ -1091,7 +1089,7 @@ void HSIDisplay::updateAttitude(UASInterface* uas, double roll, double pitch, do
void HSIDisplay::updateUserPositionSetpoints(int uasid, float xDesired, float yDesired, float zDesired, float yawDesired)
{
Q_UNUSED(uasid);
Q_UNUSED(uasid);
uiXSetCoordinate = xDesired;
uiYSetCoordinate = yDesired;
uiZSetCoordinate = zDesired;

1
src/ui/HSIDisplay.h

@ -52,7 +52,6 @@ public: @@ -52,7 +52,6 @@ public:
public slots:
void setActiveUAS(UASInterface* uas);
void removeUAS(UASInterface* uas);
/** @brief Set the width in meters this widget shows from top */
void setMetricWidth(double width);
void updateSatellite(int uasid, int satid, float azimuth, float direction, float snr, bool used);

6
src/ui/HUD.cc

@ -319,10 +319,10 @@ void HUD::setActiveUAS(UASInterface* uas) @@ -319,10 +319,10 @@ void HUD::setActiveUAS(UASInterface* uas)
connect(u, SIGNAL(imageStarted(quint64)), this, SLOT(startImage(quint64)));
connect(u, SIGNAL(imageReady(UASInterface*)), this, SLOT(copyImage()));
}
// Set new UAS
this->uas = uas;
}
// Set new UAS
this->uas = uas;
}
//void HUD::updateAttitudeThrustSetPoint(UASInterface* uas, double rollDesired, double pitchDesired, double yawDesired, double thrustDesired, quint64 msec)

76
src/ui/QGCToolBar.cc

@ -166,7 +166,6 @@ void QGCToolBar::createUI() @@ -166,7 +166,6 @@ void QGCToolBar::createUI()
// Configure the toolbar for the current default UAS
setActiveUAS(UASManager::instance()->getActiveUAS());
connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*)));
connect(UASManager::instance(), SIGNAL(UASDeleted(UASInterface*)), this, SLOT(removeUAS(UASInterface*)));
if (LinkManager::instance()->getLinks().count() > 2)
addLink(LinkManager::instance()->getLinks().last());
@ -288,8 +287,8 @@ void QGCToolBar::advancedActivityTriggered(QAction* action) @@ -288,8 +287,8 @@ void QGCToolBar::advancedActivityTriggered(QAction* action)
void QGCToolBar::setActiveUAS(UASInterface* active)
{
// Do nothing if system is the same or NULL
if ((active == NULL) || mav == active) return;
// Do nothing if system is the same
if (mav == active) return;
// If switching UASes, disconnect the only one.
if (mav)
@ -317,54 +316,43 @@ void QGCToolBar::setActiveUAS(UASInterface* active) @@ -317,54 +316,43 @@ void QGCToolBar::setActiveUAS(UASInterface* active)
// Connect new system
mav = active;
connect(active, SIGNAL(statusChanged(UASInterface*,QString,QString)), this, SLOT(updateState(UASInterface*, QString,QString)));
connect(active, SIGNAL(modeChanged(int,QString,QString)), this, SLOT(updateMode(int,QString,QString)));
connect(active, SIGNAL(nameChanged(QString)), this, SLOT(updateName(QString)));
connect(active, SIGNAL(systemTypeSet(UASInterface*,uint)), this, SLOT(setSystemType(UASInterface*,uint)));
connect(active, SIGNAL(textMessageReceived(int,int,int,QString)), this, SLOT(receiveTextMessage(int,int,int,QString)));
connect(active, SIGNAL(batteryChanged(UASInterface*,double,double,int)), this, SLOT(updateBatteryRemaining(UASInterface*,double,double,int)));
connect(active, SIGNAL(armingChanged(bool)), this, SLOT(updateArmingState(bool)));
connect(active, SIGNAL(heartbeatTimeout(bool, unsigned int)), this, SLOT(heartbeatTimeout(bool,unsigned int)));
connect(active, SIGNAL(globalPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(globalPositionChanged(UASInterface*,double,double,double,quint64)));
if (active->getWaypointManager())
if (mav)
{
connect(active->getWaypointManager(), SIGNAL(currentWaypointChanged(quint16)), this, SLOT(updateCurrentWaypoint(quint16)));
connect(active->getWaypointManager(), SIGNAL(waypointDistanceChanged(double)), this, SLOT(updateWaypointDistance(double)));
}
// Update all values once
systemName = mav->getUASName();
systemArmed = mav->isArmed();
toolBarNameLabel->setText(mav->getUASName());
toolBarNameLabel->setStyleSheet(QString("QLabel {color: %1;}").arg(mav->getColor().name()));
symbolLabel->setStyleSheet(QString("QWidget {background-color: %1;}").arg(mav->getColor().name()));
toolBarModeLabel->setText(mav->getShortMode());
toolBarStateLabel->setText(mav->getShortState());
toolBarTimeoutLabel->setText("");
toolBarDistLabel->setText("");
toolBarBatteryBar->setEnabled(true);
setSystemType(mav, mav->getSystemType());
}
connect(mav, SIGNAL(statusChanged(UASInterface*,QString,QString)), this, SLOT(updateState(UASInterface*, QString,QString)));
connect(mav, SIGNAL(modeChanged(int,QString,QString)), this, SLOT(updateMode(int,QString,QString)));
connect(mav, SIGNAL(nameChanged(QString)), this, SLOT(updateName(QString)));
connect(mav, SIGNAL(systemTypeSet(UASInterface*,uint)), this, SLOT(setSystemType(UASInterface*,uint)));
connect(mav, SIGNAL(textMessageReceived(int,int,int,QString)), this, SLOT(receiveTextMessage(int,int,int,QString)));
connect(mav, SIGNAL(batteryChanged(UASInterface*,double,double,int)), this, SLOT(updateBatteryRemaining(UASInterface*,double,double,int)));
connect(mav, SIGNAL(armingChanged(bool)), this, SLOT(updateArmingState(bool)));
connect(mav, SIGNAL(heartbeatTimeout(bool, unsigned int)), this, SLOT(heartbeatTimeout(bool,unsigned int)));
connect(mav, SIGNAL(globalPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(globalPositionChanged(UASInterface*,double,double,double,quint64)));
if (mav->getWaypointManager())
{
connect(mav->getWaypointManager(), SIGNAL(currentWaypointChanged(quint16)), this, SLOT(updateCurrentWaypoint(quint16)));
connect(mav->getWaypointManager(), SIGNAL(waypointDistanceChanged(double)), this, SLOT(updateWaypointDistance(double)));
}
/**
* @brief Handle removal of the UAS that is currently being displayed.
* Stop updating the UI periodically, reset the UI, and reset our stored UAS.
* @param uas The UAS to remove.
*/
void QGCToolBar::removeUAS(UASInterface* uas)
{
if (mav == uas) {
// Update all values once
systemName = mav->getUASName();
systemArmed = mav->isArmed();
toolBarNameLabel->setText(mav->getUASName());
toolBarNameLabel->setStyleSheet(QString("QLabel {color: %1;}").arg(mav->getColor().name()));
symbolLabel->setStyleSheet(QString("QWidget {background-color: %1;}").arg(mav->getColor().name()));
toolBarModeLabel->setText(mav->getShortMode());
toolBarStateLabel->setText(mav->getShortState());
toolBarTimeoutLabel->setText("");
toolBarDistLabel->setText("");
toolBarBatteryBar->setEnabled(true);
setSystemType(mav, mav->getSystemType());
}
else
{
updateViewTimer.stop();
resetToolbarUI();
mav = NULL;
}
}
void QGCToolBar::createCustomWidgets()
{
}
void QGCToolBar::updateArmingState(bool armed)
{
systemArmed = armed;

3
src/ui/QGCToolBar.h

@ -46,8 +46,6 @@ public: @@ -46,8 +46,6 @@ public:
public slots:
/** @brief Set the system that is currently displayed by this widget */
void setActiveUAS(UASInterface* active);
/** @brief Remove the provided UAS if it's currently active from the toolbar */
void removeUAS(UASInterface* uas);
/** @brief Set the link which is currently handled with connecting / disconnecting */
void addLink(LinkInterface* link);
/** @brief Remove link which is currently handled */
@ -86,7 +84,6 @@ public slots: @@ -86,7 +84,6 @@ public slots:
void advancedActivityTriggered(QAction* action);
protected:
void createCustomWidgets();
void storeSettings();
void loadSettings();
void createUI();

282
src/ui/QGCVehicleConfig.cc

@ -36,11 +36,6 @@ QGCVehicleConfig::QGCVehicleConfig(QWidget *parent) : @@ -36,11 +36,6 @@ QGCVehicleConfig::QGCVehicleConfig(QWidget *parent) :
ui(new Ui::QGCVehicleConfig)
{
doneLoadingConfig = false;
systemTypeToParamMap["FIXED_WING"] = new QMap<QString,QGCToolWidget*>();
systemTypeToParamMap["QUADROTOR"] = new QMap<QString,QGCToolWidget*>();
systemTypeToParamMap["GROUND_ROVER"] = new QMap<QString,QGCToolWidget*>();
systemTypeToParamMap["BOAT"] = new QMap<QString,QGCToolWidget*>();
libParamToWidgetMap = new QMap<QString,QGCToolWidget*>();
setObjectName("QGC_VEHICLECONFIG");
ui->setupUi(this);
@ -188,19 +183,21 @@ void QGCVehicleConfig::loadQgcConfig(bool primary) @@ -188,19 +183,21 @@ void QGCVehicleConfig::loadQgcConfig(bool primary)
//TODO: Throw an error here too, no autopilot specific configuration
qWarning() << "Invalid vehicle dir, no vehicle specific configuration will be loaded.";
}
// Generate widgets for the General tab.
QGCToolWidget *tool;
bool left = true;
foreach (QString file,generaldir.entryList(QDir::Files | QDir::NoDotAndDotDot))
{
if (file.toLower().endsWith(".qgw")) {
tool = new QGCToolWidget("", this);
QWidget* parent = left?ui->generalLeftContents:ui->generalRightContents;
tool = new QGCToolWidget("", parent);
if (tool->loadSettings(generaldir.absoluteFilePath(file), false))
{
toolWidgets.append(tool);
//ui->sensorLayout->addWidget(tool);
QGroupBox *box = new QGroupBox(this);
QGroupBox *box = new QGroupBox(parent);
box->setTitle(tool->objectName());
box->setLayout(new QVBoxLayout());
box->setLayout(new QVBoxLayout(box));
box->layout()->addWidget(tool);
if (left)
{
@ -217,18 +214,20 @@ void QGCVehicleConfig::loadQgcConfig(bool primary) @@ -217,18 +214,20 @@ void QGCVehicleConfig::loadQgcConfig(bool primary)
}
}
}
// Generate widgets for the Advanced tab.
left = true;
foreach (QString file,vehicledir.entryList(QDir::Files | QDir::NoDotAndDotDot))
{
if (file.toLower().endsWith(".qgw")) {
tool = new QGCToolWidget("", this);
QWidget* parent = left?ui->advancedLeftContents:ui->advancedRightContents;
tool = new QGCToolWidget("", parent);
if (tool->loadSettings(vehicledir.absoluteFilePath(file), false))
{
toolWidgets.append(tool);
//ui->sensorLayout->addWidget(tool);
QGroupBox *box = new QGroupBox(this);
QGroupBox *box = new QGroupBox(parent);
box->setTitle(tool->objectName());
box->setLayout(new QVBoxLayout());
box->setLayout(new QVBoxLayout(box));
box->layout()->addWidget(tool);
if (left)
{
@ -246,17 +245,18 @@ void QGCVehicleConfig::loadQgcConfig(bool primary) @@ -246,17 +245,18 @@ void QGCVehicleConfig::loadQgcConfig(bool primary)
}
}
//Load tabs for general configuration
// Load tabs for general configuration
foreach (QString dir,generaldir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
{
QWidget *tab = new QWidget(ui->tabWidget);
additionalTabs.append(tab);
ui->tabWidget->insertTab(2,tab,dir);
tab->setLayout(new QVBoxLayout());
tab->setLayout(new QVBoxLayout(tab));
tab->show();
QScrollArea *area = new QScrollArea();
QScrollArea *area = new QScrollArea(tab);
tab->layout()->addWidget(area);
QWidget *scrollArea = new QWidget();
scrollArea->setLayout(new QVBoxLayout());
QWidget *scrollArea = new QWidget(tab);
scrollArea->setLayout(new QVBoxLayout(tab));
area->setWidget(scrollArea);
area->setWidgetResizable(true);
area->show();
@ -265,14 +265,14 @@ void QGCVehicleConfig::loadQgcConfig(bool primary) @@ -265,14 +265,14 @@ void QGCVehicleConfig::loadQgcConfig(bool primary)
foreach (QString file,newdir.entryList(QDir::Files| QDir::NoDotAndDotDot))
{
if (file.toLower().endsWith(".qgw")) {
tool = new QGCToolWidget("", this);
tool = new QGCToolWidget("", tab);
if (tool->loadSettings(newdir.absoluteFilePath(file), false))
{
toolWidgets.append(tool);
//ui->sensorLayout->addWidget(tool);
QGroupBox *box = new QGroupBox(this);
QGroupBox *box = new QGroupBox(tab);
box->setTitle(tool->objectName());
box->setLayout(new QVBoxLayout());
box->setLayout(new QVBoxLayout(tab));
box->layout()->addWidget(tool);
scrollArea->layout()->addWidget(box);
} else {
@ -282,17 +282,18 @@ void QGCVehicleConfig::loadQgcConfig(bool primary) @@ -282,17 +282,18 @@ void QGCVehicleConfig::loadQgcConfig(bool primary)
}
}
//Load tabs for vehicle specific configuration
// Load additional tabs for vehicle specific configuration
foreach (QString dir,vehicledir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
{
QWidget *tab = new QWidget(ui->tabWidget);
additionalTabs.append(tab);
ui->tabWidget->insertTab(2,tab,dir);
tab->setLayout(new QVBoxLayout());
tab->setLayout(new QVBoxLayout(tab));
tab->show();
QScrollArea *area = new QScrollArea();
QScrollArea *area = new QScrollArea(tab);
tab->layout()->addWidget(area);
QWidget *scrollArea = new QWidget();
scrollArea->setLayout(new QVBoxLayout());
QWidget *scrollArea = new QWidget(tab);
scrollArea->setLayout(new QVBoxLayout(tab));
area->setWidget(scrollArea);
area->setWidgetResizable(true);
area->show();
@ -302,15 +303,15 @@ void QGCVehicleConfig::loadQgcConfig(bool primary) @@ -302,15 +303,15 @@ void QGCVehicleConfig::loadQgcConfig(bool primary)
foreach (QString file,newdir.entryList(QDir::Files| QDir::NoDotAndDotDot))
{
if (file.toLower().endsWith(".qgw")) {
tool = new QGCToolWidget("", this);
tool = new QGCToolWidget("", tab);
tool->addUAS(mav);
if (tool->loadSettings(newdir.absoluteFilePath(file), false))
{
toolWidgets.append(tool);
//ui->sensorLayout->addWidget(tool);
QGroupBox *box = new QGroupBox();
QGroupBox *box = new QGroupBox(tab);
box->setTitle(tool->objectName());
box->setLayout(new QVBoxLayout());
box->setLayout(new QVBoxLayout(box));
box->layout()->addWidget(tool);
scrollArea->layout()->addWidget(box);
box->show();
@ -322,30 +323,31 @@ void QGCVehicleConfig::loadQgcConfig(bool primary) @@ -322,30 +323,31 @@ void QGCVehicleConfig::loadQgcConfig(bool primary)
}
}
// Load calibration
// Load general calibration for autopilot
//TODO: Handle this more gracefully, maybe have it scan the directory for multiple calibration entries?
tool = new QGCToolWidget("", this);
tool = new QGCToolWidget("", ui->sensorContents);
tool->addUAS(mav);
if (tool->loadSettings(autopilotdir.absolutePath() + "/general/calibration/calibration.qgw", false))
{
toolWidgets.append(tool);
QGroupBox *box = new QGroupBox(this);
QGroupBox *box = new QGroupBox(ui->sensorContents);
box->setTitle(tool->objectName());
box->setLayout(new QVBoxLayout());
box->setLayout(new QVBoxLayout(box));
box->layout()->addWidget(tool);
ui->sensorLayout->addWidget(box);
} else {
delete tool;
}
tool = new QGCToolWidget("", this);
// Load vehicle-specific autopilot configuration
tool = new QGCToolWidget("", ui->sensorContents);
tool->addUAS(mav);
if (tool->loadSettings(autopilotdir.absolutePath() + "/" + mav->getSystemTypeName().toLower() + "/calibration/calibration.qgw", false))
{
toolWidgets.append(tool);
QGroupBox *box = new QGroupBox(this);
QGroupBox *box = new QGroupBox(ui->sensorContents);
box->setTitle(tool->objectName());
box->setLayout(new QVBoxLayout());
box->setLayout(new QVBoxLayout(box));
box->layout()->addWidget(tool);
ui->sensorLayout->addWidget(box);
} else {
@ -391,7 +393,7 @@ void QGCVehicleConfig::loadConfig() @@ -391,7 +393,7 @@ void QGCVehicleConfig::loadConfig()
QXmlStreamReader xml(xmlfile.readAll());
xmlfile.close();
//TODO: Testing to ensure that incorrectly formated XML won't break this.
//TODO: Testing to ensure that incorrectly formatted XML won't break this.
while (!xml.atEnd())
{
if (xml.isStartElement() && xml.name() == "paramfile")
@ -571,7 +573,16 @@ void QGCVehicleConfig::loadConfig() @@ -571,7 +573,16 @@ void QGCVehicleConfig::loadConfig()
}
if (genarraycount > 0)
{
tool = new QGCToolWidget("", this);
QWidget* parent = this;
if (valuetype == "vehicles")
{
parent = ui->generalLeftContents;
}
else if (valuetype == "libraries")
{
parent = ui->generalRightContents;
}
tool = new QGCToolWidget("", parent);
tool->addUAS(mav);
tool->setTitle(parametersname);
tool->setObjectName(parametersname);
@ -582,26 +593,26 @@ void QGCVehicleConfig::loadConfig() @@ -582,26 +593,26 @@ void QGCVehicleConfig::loadConfig()
//Based on the airframe, we add the parameter to different categories.
if (parametersname == "ArduPlane") //MAV_TYPE_FIXED_WING FIXED_WING
{
systemTypeToParamMap["FIXED_WING"]->insert(paramlist[i],tool);
systemTypeToParamMap["FIXED_WING"].insert(paramlist[i],tool);
}
else if (parametersname == "ArduCopter") //MAV_TYPE_QUADROTOR "QUADROTOR
{
systemTypeToParamMap["QUADROTOR"]->insert(paramlist[i],tool);
systemTypeToParamMap["QUADROTOR"].insert(paramlist[i],tool);
}
else if (parametersname == "APMrover2") //MAV_TYPE_GROUND_ROVER GROUND_ROVER
{
systemTypeToParamMap["GROUND_ROVER"]->insert(paramlist[i],tool);
systemTypeToParamMap["GROUND_ROVER"].insert(paramlist[i],tool);
}
else
{
libParamToWidgetMap->insert(paramlist[i],tool);
libParamToWidgetMap.insert(paramlist[i],tool);
}
}
toolWidgets.append(tool);
QGroupBox *box = new QGroupBox(this);
QGroupBox *box = new QGroupBox(parent);
box->setTitle(tool->objectName());
box->setLayout(new QVBoxLayout());
box->setLayout(new QVBoxLayout(box));
box->layout()->addWidget(tool);
if (valuetype == "vehicles")
{
@ -616,7 +627,16 @@ void QGCVehicleConfig::loadConfig() @@ -616,7 +627,16 @@ void QGCVehicleConfig::loadConfig()
}
if (advarraycount > 0)
{
tool = new QGCToolWidget("", this);
QWidget* parent = this;
if (valuetype == "vehicles")
{
parent = ui->generalLeftContents;
}
else if (valuetype == "libraries")
{
parent = ui->generalRightContents;
}
tool = new QGCToolWidget("", parent);
tool->addUAS(mav);
tool->setTitle(parametersname);
tool->setObjectName(parametersname);
@ -627,48 +647,42 @@ void QGCVehicleConfig::loadConfig() @@ -627,48 +647,42 @@ void QGCVehicleConfig::loadConfig()
//Based on the airframe, we add the parameter to different categories.
if (parametersname == "ArduPlane") //MAV_TYPE_FIXED_WING FIXED_WING
{
systemTypeToParamMap["FIXED_WING"]->insert(paramlist[i],tool);
systemTypeToParamMap["FIXED_WING"].insert(paramlist[i],tool);
}
else if (parametersname == "ArduCopter") //MAV_TYPE_QUADROTOR "QUADROTOR
{
systemTypeToParamMap["QUADROTOR"]->insert(paramlist[i],tool);
systemTypeToParamMap["QUADROTOR"].insert(paramlist[i],tool);
}
else if (parametersname == "APMrover2") //MAV_TYPE_GROUND_ROVER GROUND_ROVER
{
systemTypeToParamMap["GROUND_ROVER"]->insert(paramlist[i],tool);
systemTypeToParamMap["GROUND_ROVER"].insert(paramlist[i],tool);
}
else
{
libParamToWidgetMap->insert(paramlist[i],tool);
libParamToWidgetMap.insert(paramlist[i],tool);
}
}
toolWidgets.append(tool);
QGroupBox *box = new QGroupBox(this);
QGroupBox *box = new QGroupBox(parent);
box->setTitle(tool->objectName());
box->setLayout(new QVBoxLayout());
box->setLayout(new QVBoxLayout(box));
box->layout()->addWidget(tool);
if (valuetype == "vehicles")
{
ui->leftAdvancedLayout->addWidget(box);
ui->leftGeneralLayout->addWidget(box);
}
else if (valuetype == "libraries")
{
ui->rightAdvancedLayout->addWidget(box);
ui->rightGeneralLayout->addWidget(box);
}
box->hide();
toolToBoxMap[tool] = box;
}
}
xml.readNext();
}
}
xml.readNext();
}
}
@ -682,8 +696,8 @@ void QGCVehicleConfig::loadConfig() @@ -682,8 +696,8 @@ void QGCVehicleConfig::loadConfig()
void QGCVehicleConfig::setActiveUAS(UASInterface* active)
{
// Do nothing if system is the same or NULL
if ((active == NULL) || mav == active) return;
// Do nothing if system is the same
if (mav == active) return;
if (mav)
{
@ -693,11 +707,41 @@ void QGCVehicleConfig::setActiveUAS(UASInterface* active) @@ -693,11 +707,41 @@ void QGCVehicleConfig::setActiveUAS(UASInterface* active)
disconnect(mav, SIGNAL(parameterChanged(int,int,QString,QVariant)), this,
SLOT(parameterChanged(int,int,QString,QVariant)));
foreach (QGCToolWidget* tool, toolWidgets)
// Delete all children from all fixed tabs.
foreach(QWidget* child, ui->generalLeftContents->findChildren<QWidget*>())
{
child->deleteLater();
}
foreach(QWidget* child, ui->generalRightContents->findChildren<QWidget*>())
{
child->deleteLater();
}
foreach(QWidget* child, ui->advancedLeftContents->findChildren<QWidget*>())
{
child->deleteLater();
}
foreach(QWidget* child, ui->advancedRightContents->findChildren<QWidget*>())
{
child->deleteLater();
}
foreach(QWidget* child, ui->sensorContents->findChildren<QWidget*>())
{
child->deleteLater();
}
// And then delete any custom tabs
foreach(QWidget* child, additionalTabs)
{
delete tool;
child->deleteLater();
}
additionalTabs.clear();
toolWidgets.clear();
paramToWidgetMap = NULL;
libParamToWidgetMap.clear();
systemTypeToParamMap.clear();
toolToBoxMap.clear();
paramTooltips.clear();
}
// Reset current state
@ -707,44 +751,57 @@ void QGCVehicleConfig::setActiveUAS(UASInterface* active) @@ -707,44 +751,57 @@ void QGCVehicleConfig::setActiveUAS(UASInterface* active)
// Connect new system
mav = active;
connect(active, SIGNAL(remoteControlChannelRawChanged(int,float)), this,
SLOT(remoteControlChannelRawChanged(int,float)));
connect(active, SIGNAL(parameterChanged(int,int,QString,QVariant)), this,
SLOT(parameterChanged(int,int,QString,QVariant)));
if (systemTypeToParamMap.contains(mav->getSystemTypeName()))
{
paramToWidgetMap = systemTypeToParamMap[mav->getSystemTypeName()];
}
else
if (mav)
{
//Indication that we have no meta data for this system type.
qDebug() << "No parameters defined for system type:" << mav->getSystemTypeName();
systemTypeToParamMap[mav->getSystemTypeName()] = new QMap<QString,QGCToolWidget*>();
paramToWidgetMap = systemTypeToParamMap[mav->getSystemTypeName()];
}
connect(active, SIGNAL(remoteControlChannelRawChanged(int,float)), this,
SLOT(remoteControlChannelRawChanged(int,float)));
connect(active, SIGNAL(parameterChanged(int,int,QString,QVariant)), this,
SLOT(parameterChanged(int,int,QString,QVariant)));
if (!paramTooltips.isEmpty())
{
mav->getParamManager()->setParamInfo(paramTooltips);
}
if (systemTypeToParamMap.contains(mav->getSystemTypeName()))
{
paramToWidgetMap = &systemTypeToParamMap[mav->getSystemTypeName()];
}
else
{
//Indication that we have no meta data for this system type.
qDebug() << "No parameters defined for system type:" << mav->getSystemTypeName();
paramToWidgetMap = &systemTypeToParamMap[mav->getSystemTypeName()];
}
qDebug() << "CALIBRATION!! System Type Name:" << mav->getSystemTypeName();
if (!paramTooltips.isEmpty())
{
mav->getParamManager()->setParamInfo(paramTooltips);
}
qDebug() << "CALIBRATION!! System Type Name:" << mav->getSystemTypeName();
//Load configuration after 1ms. This allows it to go into the event loop, and prevents application hangups due to the
//amount of time it actually takes to load the configuration windows.
QTimer::singleShot(1,this,SLOT(loadConfig()));
//Load configuration after 1ms. This allows it to go into the event loop, and prevents application hangups due to the
//amount of time it actually takes to load the configuration windows.
QTimer::singleShot(1,this,SLOT(loadConfig()));
updateStatus(QString("Reading from system %1").arg(mav->getUASName()));
updateStatus(QString("Reading from system %1").arg(mav->getUASName()));
// Since a system is now connected, enable the VehicleConfig UI.
ui->tabWidget->setEnabled(true);
ui->setButton->setEnabled(true);
ui->refreshButton->setEnabled(true);
ui->readButton->setEnabled(true);
ui->writeButton->setEnabled(true);
ui->loadFileButton->setEnabled(true);
ui->saveFileButton->setEnabled(true);
// Since a system is now connected, enable the VehicleConfig UI.
ui->tabWidget->setEnabled(true);
ui->setButton->setEnabled(true);
ui->refreshButton->setEnabled(true);
ui->readButton->setEnabled(true);
ui->writeButton->setEnabled(true);
ui->loadFileButton->setEnabled(true);
ui->saveFileButton->setEnabled(true);
}
else
{
// Disable the vehicle config widget if no new UAS has been enabled.
ui->tabWidget->setEnabled(false);
ui->setButton->setEnabled(false);
ui->refreshButton->setEnabled(false);
ui->readButton->setEnabled(false);
ui->writeButton->setEnabled(false);
ui->loadFileButton->setEnabled(false);
ui->saveFileButton->setEnabled(false);
}
}
void QGCVehicleConfig::resetCalibrationRC()
@ -986,13 +1043,13 @@ void QGCVehicleConfig::parameterChanged(int uas, int component, QString paramete @@ -986,13 +1043,13 @@ void QGCVehicleConfig::parameterChanged(int uas, int component, QString paramete
qCritical() << "Widget with no box, possible memory corruption for param:" << parameterName;
}
}
else if (libParamToWidgetMap->contains(parameterName))
else if (libParamToWidgetMap.contains(parameterName))
{
//All the library parameters
libParamToWidgetMap->value(parameterName)->setParameterValue(uas,component,parameterName,value);
if (toolToBoxMap.contains(libParamToWidgetMap->value(parameterName)))
libParamToWidgetMap.value(parameterName)->setParameterValue(uas,component,parameterName,value);
if (toolToBoxMap.contains(libParamToWidgetMap.value(parameterName)))
{
toolToBoxMap[libParamToWidgetMap->value(parameterName)]->show();
toolToBoxMap[libParamToWidgetMap.value(parameterName)]->show();
}
else
{
@ -1010,7 +1067,7 @@ void QGCVehicleConfig::parameterChanged(int uas, int component, QString paramete @@ -1010,7 +1067,7 @@ void QGCVehicleConfig::parameterChanged(int uas, int component, QString paramete
{
//It should be grouped with this one, add it.
toolWidgets[i]->addParam(uas,component,parameterName,value);
libParamToWidgetMap->insert(parameterName,toolWidgets[i]);
libParamToWidgetMap.insert(parameterName,toolWidgets[i]);
found = true;
break;
}
@ -1018,7 +1075,18 @@ void QGCVehicleConfig::parameterChanged(int uas, int component, QString paramete @@ -1018,7 +1075,18 @@ void QGCVehicleConfig::parameterChanged(int uas, int component, QString paramete
if (!found)
{
//New param type, create a QGroupBox for it.
QGCToolWidget *tool = new QGCToolWidget("", this);
QWidget* parent;
if (ui->leftAdvancedLayout->count() > ui->rightAdvancedLayout->count())
{
parent = ui->advancedRightContents;
}
else
{
parent = ui->advancedLeftContents;
}
// Create the tool, attaching it to the QGroupBox
QGCToolWidget *tool = new QGCToolWidget("", parent);
QString tooltitle = parameterName;
if (parameterName.split("_").size() > 1)
{
@ -1026,15 +1094,15 @@ void QGCVehicleConfig::parameterChanged(int uas, int component, QString paramete @@ -1026,15 +1094,15 @@ void QGCVehicleConfig::parameterChanged(int uas, int component, QString paramete
}
tool->setTitle(tooltitle);
tool->setObjectName(tooltitle);
//tool->setSettings(set);
tool->addParam(uas,component,parameterName,value);
libParamToWidgetMap->insert(parameterName,tool);
toolWidgets.append(tool);
QGroupBox *box = new QGroupBox(this);
tool->addParam(uas, component, parameterName, value);
QGroupBox *box = new QGroupBox(parent);
box->setTitle(tool->objectName());
box->setLayout(new QVBoxLayout());
box->setLayout(new QVBoxLayout(box));
box->layout()->addWidget(tool);
libParamToWidgetMap.insert(parameterName,tool);
toolWidgets.append(tool);
//Make sure we have similar number of widgets on each side.
if (ui->leftAdvancedLayout->count() > ui->rightAdvancedLayout->count())

7
src/ui/QGCVehicleConfig.h

@ -175,9 +175,10 @@ protected: @@ -175,9 +175,10 @@ protected:
QList<QGCToolWidget*> toolWidgets; ///< Configurable widgets
bool calibrationEnabled; ///< calibration mode on / off
QMap<QString,QGCToolWidget*> *paramToWidgetMap; ///< Holds the current active MAV's parameter widgets.
QMap<QString,QGCToolWidget*> *libParamToWidgetMap; ///< Holds the library parameter widgets
QMap<QString,QMap<QString,QGCToolWidget*>*> systemTypeToParamMap; ///< Holds all loaded MAV specific parameter widgets, for every MAV.
QMap<QString,QGCToolWidget*>* paramToWidgetMap; ///< Holds the current active MAV's parameter widgets.
QList<QWidget*> additionalTabs; ///< Stores additional tabs loaded for this vehicle/autopilot configuration. Used for cleaning up.
QMap<QString,QGCToolWidget*> libParamToWidgetMap; ///< Holds the library parameter widgets
QMap<QString,QMap<QString,QGCToolWidget*> > systemTypeToParamMap; ///< Holds all loaded MAV specific parameter widgets, for every MAV.
QMap<QGCToolWidget*,QGroupBox*> toolToBoxMap; ///< Easy method of figuring out which QGroupBox is tied to which ToolWidget.
QMap<QString,QString> paramTooltips; ///< Tooltips for the ? button next to a parameter.

12
src/ui/QGCVehicleConfig.ui

@ -35,7 +35,7 @@ @@ -35,7 +35,7 @@
</sizepolicy>
</property>
<property name="currentIndex">
<number>3</number>
<number>0</number>
</property>
<widget class="QWidget" name="rcTab">
<property name="sizePolicy">
@ -765,7 +765,7 @@ p, li { white-space: pre-wrap; } @@ -765,7 +765,7 @@ p, li { white-space: pre-wrap; }
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_7">
<widget class="QWidget" name="sensorContents">
<property name="geometry">
<rect>
<x>0</x>
@ -849,7 +849,7 @@ p, li { white-space: pre-wrap; } @@ -849,7 +849,7 @@ p, li { white-space: pre-wrap; }
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<widget class="QWidget" name="generalLeftContents">
<property name="geometry">
<rect>
<x>0</x>
@ -886,7 +886,7 @@ p, li { white-space: pre-wrap; } @@ -886,7 +886,7 @@ p, li { white-space: pre-wrap; }
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_2">
<widget class="QWidget" name="generalRightContents">
<property name="geometry">
<rect>
<x>0</x>
@ -983,7 +983,7 @@ p, li { white-space: pre-wrap; } @@ -983,7 +983,7 @@ p, li { white-space: pre-wrap; }
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_4">
<widget class="QWidget" name="advancedLeftContents">
<property name="geometry">
<rect>
<x>0</x>
@ -1036,7 +1036,7 @@ p, li { white-space: pre-wrap; } @@ -1036,7 +1036,7 @@ p, li { white-space: pre-wrap; }
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_5">
<widget class="QWidget" name="advancedRightContents">
<property name="geometry">
<rect>
<x>0</x>

28
src/ui/map/QGCMapWidget.cc

@ -302,7 +302,6 @@ void QGCMapWidget::addUAS(UASInterface* uas) @@ -302,7 +302,6 @@ void QGCMapWidget::addUAS(UASInterface* uas)
void QGCMapWidget::activeUASSet(UASInterface* uas)
{
// Only execute if proper UAS is set
if (!uas) return;
this->uas = uas;
// Disconnect old MAV manager
@ -315,17 +314,26 @@ void QGCMapWidget::activeUASSet(UASInterface* uas) @@ -315,17 +314,26 @@ void QGCMapWidget::activeUASSet(UASInterface* uas)
disconnect(this, SIGNAL(waypointChanged(Waypoint*)), currWPManager, SLOT(notifyOfChangeEditable(Waypoint*)));
}
currWPManager = uas->getWaypointManager();
// Attach the new waypoint manager if a new UAS was selected. Otherwise, indicate
// that no such manager exists.
if (uas)
{
currWPManager = uas->getWaypointManager();
updateSelectedSystem(uas->getUASID());
followUAVID = uas->getUASID();
updateWaypointList(uas->getUASID());
updateSelectedSystem(uas->getUASID());
followUAVID = uas->getUASID();
updateWaypointList(uas->getUASID());
// Connect the waypoint manager / data storage to the UI
connect(currWPManager, SIGNAL(waypointEditableListChanged(int)), this, SLOT(updateWaypointList(int)));
connect(currWPManager, SIGNAL(waypointEditableChanged(int, Waypoint*)), this, SLOT(updateWaypoint(int,Waypoint*)));
connect(this, SIGNAL(waypointCreated(Waypoint*)), currWPManager, SLOT(addWaypointEditable(Waypoint*)));
connect(this, SIGNAL(waypointChanged(Waypoint*)), currWPManager, SLOT(notifyOfChangeEditable(Waypoint*)));
// Connect the waypoint manager / data storage to the UI
connect(currWPManager, SIGNAL(waypointEditableListChanged(int)), this, SLOT(updateWaypointList(int)));
connect(currWPManager, SIGNAL(waypointEditableChanged(int, Waypoint*)), this, SLOT(updateWaypoint(int,Waypoint*)));
connect(this, SIGNAL(waypointCreated(Waypoint*)), currWPManager, SLOT(addWaypointEditable(Waypoint*)));
connect(this, SIGNAL(waypointChanged(Waypoint*)), currWPManager, SLOT(notifyOfChangeEditable(Waypoint*)));
}
else
{
currWPManager = NULL;
}
}
/**

5
src/ui/map3D/Pixhawk3DWidget.cc

@ -113,7 +113,10 @@ Pixhawk3DWidget::~Pixhawk3DWidget() @@ -113,7 +113,10 @@ Pixhawk3DWidget::~Pixhawk3DWidget()
void
Pixhawk3DWidget::activeSystemChanged(UASInterface* uas)
{
mActiveSystemId = uas->getUASID();
if (uas)
{
mActiveSystemId = uas->getUASID();
}
mActiveUAS = uas;

33
src/ui/uas/UASControlWidget.cc

@ -70,7 +70,7 @@ UASControlWidget::UASControlWidget(QWidget *parent) : QWidget(parent), @@ -70,7 +70,7 @@ UASControlWidget::UASControlWidget(QWidget *parent) : QWidget(parent),
void UASControlWidget::setUAS(UASInterface* uas)
{
if (this->uas != 0)
if (this->uas)
{
UASInterface* oldUAS = UASManager::instance()->getUASForId(this->uas);
disconnect(ui.controlButton, SIGNAL(clicked()), oldUAS, SLOT(armSystem()));
@ -83,18 +83,25 @@ void UASControlWidget::setUAS(UASInterface* uas) @@ -83,18 +83,25 @@ void UASControlWidget::setUAS(UASInterface* uas)
}
// Connect user interface controls
connect(ui.controlButton, SIGNAL(clicked()), this, SLOT(cycleContextButton()));
connect(ui.liftoffButton, SIGNAL(clicked()), uas, SLOT(launch()));
connect(ui.landButton, SIGNAL(clicked()), uas, SLOT(home()));
connect(ui.shutdownButton, SIGNAL(clicked()), uas, SLOT(shutdown()));
//connect(ui.setHomeButton, SIGNAL(clicked()), uas, SLOT(setLocalOriginAtCurrentGPSPosition()));
connect(uas, SIGNAL(modeChanged(int,QString,QString)), this, SLOT(updateMode(int,QString,QString)));
connect(uas, SIGNAL(statusChanged(int)), this, SLOT(updateState(int)));
ui.controlStatusLabel->setText(tr("Connected to ") + uas->getUASName());
this->uas = uas->getUASID();
setBackgroundColor(uas->getColor());
if (uas)
{
connect(ui.controlButton, SIGNAL(clicked()), this, SLOT(cycleContextButton()));
connect(ui.liftoffButton, SIGNAL(clicked()), uas, SLOT(launch()));
connect(ui.landButton, SIGNAL(clicked()), uas, SLOT(home()));
connect(ui.shutdownButton, SIGNAL(clicked()), uas, SLOT(shutdown()));
//connect(ui.setHomeButton, SIGNAL(clicked()), uas, SLOT(setLocalOriginAtCurrentGPSPosition()));
connect(uas, SIGNAL(modeChanged(int,QString,QString)), this, SLOT(updateMode(int,QString,QString)));
connect(uas, SIGNAL(statusChanged(int)), this, SLOT(updateState(int)));
ui.controlStatusLabel->setText(tr("Connected to ") + uas->getUASName());
this->uas = uas->getUASID();
setBackgroundColor(uas->getColor());
}
else
{
this->uas = -1;
}
}
UASControlWidget::~UASControlWidget()

68
src/ui/uas/UASListWidget.cc

@ -56,15 +56,21 @@ UASListWidget::UASListWidget(QWidget *parent) : QWidget(parent), @@ -56,15 +56,21 @@ UASListWidget::UASListWidget(QWidget *parent) : QWidget(parent),
m_ui->verticalLayout->addWidget(uWidget);
linkToBoxMapping = QMap<LinkInterface*, QGroupBox*>();
uasToBoxMapping = QMap<UASInterface*, QGroupBox*>();
uasViews = QMap<UASInterface*, UASView*>();
this->setVisible(false);
// Listen for when UASes are added or removed. This does not manage the UASView
// widgets that are displayed within this widget.
connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)),
this, SLOT(addUAS(UASInterface*)));
connect(UASManager::instance(), SIGNAL(UASDeleted(UASInterface*)),
this, SLOT(removeUAS(UASInterface*)));
// Get a list of all existing UAS
foreach (UASInterface* uas, UASManager::instance()->getUASList()) {
foreach (UASInterface* uas, UASManager::instance()->getUASList())
{
addUAS(uas);
}
}
@ -94,7 +100,7 @@ void UASListWidget::addUAS(UASInterface* uas) @@ -94,7 +100,7 @@ void UASListWidget::addUAS(UASInterface* uas)
if (uasViews.isEmpty())
{
m_ui->verticalLayout->removeWidget(uWidget);
delete uWidget;
uWidget->deleteLater();
uWidget = NULL;
}
@ -125,6 +131,7 @@ void UASListWidget::addUAS(UASInterface* uas) @@ -125,6 +131,7 @@ void UASListWidget::addUAS(UASInterface* uas)
// And add the new UAS to the UASList
UASView* newView = new UASView(uas, newBox);
uasViews.insert(uas, newView);
uasToBoxMapping[uas] = newBox;
newBox->layout()->addWidget(newView);
// Watch for when this widget is destroyed so that we can clean up the
@ -149,30 +156,49 @@ void UASListWidget::activeUAS(UASInterface* uas) @@ -149,30 +156,49 @@ void UASListWidget::activeUAS(UASInterface* uas)
*/
void UASListWidget::removeUAS(UASInterface* uas)
{
// Remove the UAS from our data structures and
// the global listing.
// Remove the UASView and check if its parent GroupBox has any other children,
// delete it if it doesn't.
QGroupBox* box = uasToBoxMapping[uas];
uasToBoxMapping.remove(uas);
uasViews.remove(uas);
// Check all groupboxes for all links this uas had and check if they're empty.
// Delete them if they are.
QListIterator<LinkInterface*> i = *uas->getLinks();
while (i.hasNext())
int otherViews = 0;
foreach (UASView* view, box->findChildren<UASView*>())
{
LinkInterface* link = i.next();
if (view->uas == uas)
{
view->deleteLater();
}
else
{
++otherViews;
}
}
if (otherViews == 0)
{
// Delete the groupbox.
QMap<LinkInterface*, QGroupBox*>::const_iterator i = linkToBoxMapping.constBegin();
while (i != linkToBoxMapping.constEnd()) {
if (i.value() == box)
{
linkToBoxMapping.remove(i.key());
}
++i;
}
box->deleteLater();
QGroupBox* box = linkToBoxMapping[link];
if (box)
// And if no other QGroupBoxes are left, put the initial widget back.
int otherBoxes = 0;
foreach (const QGroupBox* otherBox, findChildren<QGroupBox*>())
{
// If this was the last UAS in the GroupBox, remove it and its corresponding link.
int views = box->findChildren<UASView*>().size();
if (views == 0) {
box->deleteLater();
linkToBoxMapping.remove(link);
if (otherBox != box)
{
++otherBoxes;
}
}
if (otherBoxes == 0)
{
uWidget = new QGCUnconnectedInfoWidget(this);
m_ui->verticalLayout->addWidget(uWidget);
}
}
// And if no QGroupBoxes are left, put the initial widget back.
uWidget = new QGCUnconnectedInfoWidget(this);
m_ui->verticalLayout->addWidget(uWidget);
}

5
src/ui/uas/UASListWidget.h

@ -33,6 +33,7 @@ This file is part of the QGROUNDCONTROL project @@ -33,6 +33,7 @@ This file is part of the QGROUNDCONTROL project
#include <QWidget>
#include <QMap>
#include <QList>
#include <QVBoxLayout>
#include <QGroupBox>
#include "UASInterface.h"
@ -54,9 +55,11 @@ public slots: @@ -54,9 +55,11 @@ public slots:
void removeUAS(UASInterface* uas);
protected:
// Keep a mapping from UASes to their GroupBox. Useful for determining when groupboxes are empty.
QMap<UASInterface*, QGroupBox*> uasToBoxMapping;
// Keep a mapping from Links to GroupBoxes for adding new links.
QMap<LinkInterface*, QGroupBox*> linkToBoxMapping;
// Tie each view to their UAS object.
// Tie each view to their UAS object so they can be removed easily.
QMap<UASInterface*, UASView*> uasViews;
QGCUnconnectedInfoWidget* uWidget;
void changeEvent(QEvent *e);

20
src/ui/uas/UASQuickView.cc

@ -17,61 +17,61 @@ UASQuickView::UASQuickView(QWidget *parent) : @@ -17,61 +17,61 @@ UASQuickView::UASQuickView(QWidget *parent) :
{
QAction *action = new QAction("latitude",this);
QAction *action = new QAction(tr("latitude"),this);
action->setCheckable(true);
action->setChecked(true);
connect(action,SIGNAL(toggled(bool)),this,SLOT(actionTriggered(bool)));
this->addAction(action);
UASQuickViewItem *item = new UASQuickViewItem(this);
item->setTitle("latitude");
item->setTitle(tr("latitude"));
this->layout()->addWidget(item);
uasPropertyToLabelMap["latitude"] = item;
}
{
QAction *action = new QAction("longitude",this);
QAction *action = new QAction(tr("longitude"),this);
action->setCheckable(true);
action->setChecked(true);
connect(action,SIGNAL(toggled(bool)),this,SLOT(actionTriggered(bool)));
this->addAction(action);
UASQuickViewItem *item = new UASQuickViewItem(this);
item->setTitle("longitude");
item->setTitle(tr("longitude"));
this->layout()->addWidget(item);
uasPropertyToLabelMap["longitude"] = item;
}
{
QAction *action = new QAction("altitude",this);
QAction *action = new QAction(tr("altitude"),this);
action->setCheckable(true);
action->setChecked(true);
connect(action,SIGNAL(toggled(bool)),this,SLOT(actionTriggered(bool)));
this->addAction(action);
UASQuickViewItem *item = new UASQuickViewItem(this);
item->setTitle("altitude");
item->setTitle(tr("altitude"));
this->layout()->addWidget(item);
uasPropertyToLabelMap["altitude"] = item;
}
{
QAction *action = new QAction("satelliteCount",this);
QAction *action = new QAction(tr("satelliteCount"),this);
action->setCheckable(true);
action->setChecked(true);
connect(action,SIGNAL(toggled(bool)),this,SLOT(actionTriggered(bool)));
this->addAction(action);
UASQuickViewItem *item = new UASQuickViewItem(this);
item->setTitle("satelliteCount");
item->setTitle(tr("satelliteCount"));
this->layout()->addWidget(item);
uasPropertyToLabelMap["satelliteCount"] = item;
}
{
QAction *action = new QAction("distToWaypoint",this);
QAction *action = new QAction(tr("distToWaypoint"),this);
action->setCheckable(true);
action->setChecked(true);
connect(action,SIGNAL(toggled(bool)),this,SLOT(actionTriggered(bool)));
this->addAction(action);
UASQuickViewItem *item = new UASQuickViewItem(this);
item->setTitle("distToWaypoint");
item->setTitle(tr("distToWaypoint"));
this->layout()->addWidget(item);
uasPropertyToLabelMap["distToWaypoint"] = item;
}

90
src/ui/uas/UASView.cc

@ -43,48 +43,48 @@ This file is part of the PIXHAWK project @@ -43,48 +43,48 @@ This file is part of the PIXHAWK project
#include <QGCHilFlightGearConfiguration.h>
UASView::UASView(UASInterface* uas, QWidget *parent) :
QWidget(parent),
startTime(0),
timeout(false),
iconIsRed(true),
disconnected(false),
timeRemaining(0),
chargeLevel(0),
uas(uas),
load(0),
state("UNKNOWN"),
stateDesc(tr("Unknown state")),
mode("MAV_MODE_UNKNOWN"),
thrust(0),
isActive(false),
x(0),
y(0),
z(0),
totalSpeed(0),
lat(0),
lon(0),
alt(0),
groundDistance(0),
localFrame(false),
globalFrameKnown(false),
removeAction(new QAction("Delete this system", this)),
renameAction(new QAction("Rename..", this)),
selectAction(new QAction("Control this system", this )),
hilAction(new QAction("HIL - Hardware in the Loop", this )),
selectAirframeAction(new QAction("Choose Airframe", this)),
setBatterySpecsAction(new QAction("Set Battery Options", this)),
lowPowerModeEnabled(true),
generalUpdateCount(0),
filterTime(0),
m_ui(new Ui::UASView)
QWidget(parent),
uas(uas),
startTime(0),
timeout(false),
iconIsRed(true),
disconnected(false),
timeRemaining(0),
chargeLevel(0),
load(0),
state("UNKNOWN"),
stateDesc(tr("Unknown state")),
mode("MAV_MODE_UNKNOWN"),
thrust(0),
isActive(false),
x(0),
y(0),
z(0),
totalSpeed(0),
lat(0),
lon(0),
alt(0),
groundDistance(0),
localFrame(false),
globalFrameKnown(false),
removeAction(new QAction(tr("Delete this system"), this)),
renameAction(new QAction(tr("Rename.."), this)),
selectAction(new QAction(tr("Control this system"), this)),
hilAction(new QAction(tr("HIL - Hardware in the Loop"), this)),
selectAirframeAction(new QAction(tr("Choose Airframe"), this)),
setBatterySpecsAction(new QAction(tr("Set Battery Options"), this)),
lowPowerModeEnabled(true),
generalUpdateCount(0),
filterTime(0),
m_ui(new Ui::UASView)
{
m_ui->setupUi(this);
// FIXME XXX
lowPowerModeEnabled = MainWindow::instance()->lowPowerModeEnabled();
hilAction->setCheckable(true);
m_ui->setupUi(this);
// Setup communication
//connect(uas, SIGNAL(valueChanged(int,QString,double,quint64)), this, SLOT(receiveValue(int,QString,double,quint64)));
connect(uas, SIGNAL(batteryChanged(UASInterface*, double, double, int)), this, SLOT(updateBattery(UASInterface*, double, double, int)));
@ -116,8 +116,8 @@ UASView::UASView(UASInterface* uas, QWidget *parent) : @@ -116,8 +116,8 @@ UASView::UASView(UASInterface* uas, QWidget *parent) :
connect(m_ui->killButton, SIGNAL(clicked()), uas, SLOT(emergencyKILL()));
connect(m_ui->shutdownButton, SIGNAL(clicked()), uas, SLOT(shutdown()));
// Allow to delete this widget
connect(removeAction, SIGNAL(triggered()), this, SLOT(prepareForDeletion()));
// Allow deleting this widget
connect(removeAction, SIGNAL(triggered()), this, SLOT(triggerUASDeletion()));
connect(renameAction, SIGNAL(triggered()), this, SLOT(rename()));
connect(selectAction, SIGNAL(triggered()), uas, SLOT(setSelected()));
connect(hilAction, SIGNAL(triggered(bool)), this, SLOT(showHILUi()));
@ -170,9 +170,6 @@ UASView::UASView(UASInterface* uas, QWidget *parent) : @@ -170,9 +170,6 @@ UASView::UASView(UASInterface* uas, QWidget *parent) :
UASView::~UASView()
{
delete m_ui;
delete removeAction;
delete renameAction;
delete selectAction;
}
void UASView::heartbeatTimeout(bool timeout, unsigned int ms)
@ -561,23 +558,14 @@ void UASView::showHILUi() @@ -561,23 +558,14 @@ void UASView::showHILUi()
MainWindow::instance()->showHILConfigurationWidget(uas);
}
/**
* @brief Stop updating this UASView, queue it for deletion, and also tell the UASManager to delete the UAS.
*/
void UASView::prepareForDeletion()
void UASView::triggerUASDeletion()
{
refreshTimer->stop();
UASManager::instance()->removeUAS(uas);
deleteLater();
}
void UASView::refresh()
{
//setUpdatesEnabled(false);
//setUpdatesEnabled(true);
//repaint();
//qDebug() << "UPDATING UAS WIDGET!" << uas->getUASName();
if (generalUpdateCount == 4)
{
#if (QGC_EVENTLOOP_DEBUG)

9
src/ui/uas/UASView.h

@ -49,6 +49,7 @@ class UASView : public QWidget @@ -49,6 +49,7 @@ class UASView : public QWidget
public:
UASView(UASInterface* uas, QWidget *parent = 0);
~UASView();
UASInterface* uas;
public slots:
/** @brief Update the name of the system */
@ -65,8 +66,11 @@ public slots: @@ -65,8 +66,11 @@ public slots:
void updateLoad(UASInterface* uas, double load);
//void receiveValue(int uasid, QString id, double value, quint64 time);
void showHILUi();
/** @brief Disables the widget from accessing the UAS object in preparation for being deleted */
void prepareForDeletion();
/**
* Request that the UASManager deletes this UAS. This doesn't delete this widget
* yet, it waits for the approprait uasDeleted signal.
*/
void triggerUASDeletion();
void refresh();
/** @brief Receive new waypoint information */
void setWaypoint(int uasId, int id, double x, double y, double z, double yaw, bool autocontinue, bool current);
@ -103,7 +107,6 @@ protected: @@ -103,7 +107,6 @@ protected:
bool disconnected;
int timeRemaining;
float chargeLevel;
UASInterface* uas;
float load;
QString state;
QString stateDesc;

Loading…
Cancel
Save