Commit dd0e4204 authored by pixhawk's avatar pixhawk

Fixed MAV selection bug in parameter view

parents 89a3286f 3555ae74
...@@ -20,3 +20,5 @@ qgroundcontrol ...@@ -20,3 +20,5 @@ qgroundcontrol
qgroundcontrol.xcodeproj/** qgroundcontrol.xcodeproj/**
doc/html doc/html
doc/doxy.log doc/doxy.log
deploy/mac
deploy/linux
#!/bin/sh
# Clean build directories
rm -rf linux
mkdir -p linux
# Change to build directory and compile application
cd ..
make -j4
# Copy and build the application bundle
cd deploy
cp -r qgroundcontrol linux/.
cp -r ../audio linux/.
# FIXME Create debian packet
echo -e '\n QGroundControl Debian packet is now ready for publishing\n'
#!/bin/sh
# Clean build directories
rm -rf mac
mkdir -p mac
# Change to build directory and compile application
cd ..
make -j4
# Copy and build the application bundle
cd deploy
cp -r ../bin/mac/qgroundcontrol.app mac/.
cp -r ../audio mac/qgroundcontrol.app/Contents/MacOs/.
macdeployqt qgroundcontrol.app --bundle
echo -e '\n QGroundControl .DMG file is now ready for publishing\n'
#!/bin/sh
cp -r audio bin/mac/qgroundcontrol.app/Contents/MacOs/.
...@@ -81,6 +81,11 @@ void LogCompressor::run() ...@@ -81,6 +81,11 @@ void LogCompressor::run()
QString time = parts.first(); QString time = parts.first();
QString field = parts.at(2); QString field = parts.at(2);
QString value = parts.at(3); QString value = parts.at(3);
// Enforce NaN if no value is present
if (value.length() == 0 || value == "" || value == " " || value == "\t" || value == "\n")
{
value = "NaN";
}
// Get matching output line // Get matching output line
quint64 index = times->indexOf(time); quint64 index = times->indexOf(time);
QString outLine = outLines->at(index); QString outLine = outLines->at(index);
......
...@@ -285,6 +285,16 @@ void UAS::receiveMessage(LinkInterface* link, mavlink_message_t message) ...@@ -285,6 +285,16 @@ void UAS::receiveMessage(LinkInterface* link, mavlink_message_t message)
emit valueChanged(uasId, "vis. x", pos.x, time); emit valueChanged(uasId, "vis. x", pos.x, time);
emit valueChanged(uasId, "vis. y", pos.y, time); emit valueChanged(uasId, "vis. y", pos.y, time);
emit valueChanged(uasId, "vis. z", pos.z, time); emit valueChanged(uasId, "vis. z", pos.z, time);
// FIXME Only for testing for now
emit valueChanged(uasId, "vis. rot r1", pos.r1, time);
emit valueChanged(uasId, "vis. rot r2", pos.r2, time);
emit valueChanged(uasId, "vis. rot r3", pos.r3, time);
emit valueChanged(uasId, "vis. rot r4", pos.r4, time);
emit valueChanged(uasId, "vis. rot r5", pos.r5, time);
emit valueChanged(uasId, "vis. rot r6", pos.r6, time);
emit valueChanged(uasId, "vis. rot r7", pos.r7, time);
emit valueChanged(uasId, "vis. rot r8", pos.r8, time);
emit valueChanged(uasId, "vis. rot r9", pos.r9, time);
} }
break; break;
case MAVLINK_MSG_ID_POSITION: case MAVLINK_MSG_ID_POSITION:
...@@ -533,7 +543,6 @@ void UAS::requestParameters() ...@@ -533,7 +543,6 @@ void UAS::requestParameters()
mavlink_msg_param_request_list_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), 0); mavlink_msg_param_request_list_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), 0);
// Send message twice to increase chance of reception // Send message twice to increase chance of reception
sendMessage(msg); sendMessage(msg);
sendMessage(msg);
} }
void UAS::writeParameters() void UAS::writeParameters()
......
...@@ -120,7 +120,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ...@@ -120,7 +120,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),
QList<QHostAddress> hostAddresses = QNetworkInterface::allAddresses(); QList<QHostAddress> hostAddresses = QNetworkInterface::allAddresses();
QString windowname = qApp->applicationName() + " " + qApp->applicationVersion(); QString windowname = qApp->applicationName() + " " + qApp->applicationVersion();
/*
windowname.append(" (" + QHostInfo::localHostName() + ": "); windowname.append(" (" + QHostInfo::localHostName() + ": ");
bool prevAddr = false; bool prevAddr = false;
for (int i = 0; i < hostAddresses.size(); i++) for (int i = 0; i < hostAddresses.size(); i++)
...@@ -135,7 +135,6 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ...@@ -135,7 +135,6 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),
} }
windowname.append(")"); windowname.append(")");
*/
setWindowTitle(windowname); setWindowTitle(windowname);
#ifndef Q_WS_MAC #ifndef Q_WS_MAC
...@@ -216,18 +215,28 @@ void MainWindow::saveScreen() ...@@ -216,18 +215,28 @@ void MainWindow::saveScreen()
} }
} }
/**
* Reload the style sheet from disk. The function tries to load "qgroundcontrol.css" from the application
* directory (which by default does not exist). If it fails, it will load the bundled default CSS
* from memory.
* To customize the application, just create a qgroundcontrol.css file in the application directory
*/
void MainWindow::reloadStylesheet() void MainWindow::reloadStylesheet()
{ {
// Load style sheet // Load style sheet
//QFile styleSheet(MG::DIR::getSupportFilesDirectory() + "/images/style-mission.css"); QFile* styleSheet = new QFile(QCoreApplication::applicationDirPath() + "/qgroundcontrol.css");
QFile styleSheet(":/images/style-mission.css"); if (!styleSheet->exists())
if (styleSheet.open(QIODevice::ReadOnly | QIODevice::Text)) { {
QString style = QString(styleSheet.readAll()); styleSheet = new QFile(":/images/style-mission.css");
style.replace("ICONDIR", MG::DIR::getIconDirectory()); }
if (styleSheet->open(QIODevice::ReadOnly | QIODevice::Text)) {
QString style = QString(styleSheet->readAll());
style.replace("ICONDIR", QCoreApplication::applicationDirPath()+ "/images/");
qApp->setStyleSheet(style); qApp->setStyleSheet(style);
} else { } else {
qDebug() << "Style not set:" << styleSheet.fileName() << "opened: " << styleSheet.isOpen(); qDebug() << "Style not set:" << styleSheet->fileName() << "opened: " << styleSheet->isOpen();
} }
delete styleSheet;
} }
void MainWindow::showStatusMessage(const QString& status, int timeout) void MainWindow::showStatusMessage(const QString& status, int timeout)
...@@ -235,14 +244,9 @@ void MainWindow::showStatusMessage(const QString& status, int timeout) ...@@ -235,14 +244,9 @@ void MainWindow::showStatusMessage(const QString& status, int timeout)
statusBar->showMessage(status, timeout); statusBar->showMessage(status, timeout);
} }
void MainWindow::setLastAction(QString status) void MainWindow::showStatusMessage(const QString& status)
{ {
showStatusMessage(status, 5); statusBar->showMessage(status, 5);
}
void MainWindow::setLinkStatus(QString status)
{
showStatusMessage(status, 15);
} }
/** /**
...@@ -270,6 +274,7 @@ void MainWindow::connectActions() ...@@ -270,6 +274,7 @@ void MainWindow::connectActions()
connect(ui.actionEngineerView, SIGNAL(triggered()), this, SLOT(loadEngineerView())); connect(ui.actionEngineerView, SIGNAL(triggered()), this, SLOT(loadEngineerView()));
connect(ui.actionOperatorView, SIGNAL(triggered()), this, SLOT(loadOperatorView())); connect(ui.actionOperatorView, SIGNAL(triggered()), this, SLOT(loadOperatorView()));
connect(ui.actionSettingsView, SIGNAL(triggered()), this, SLOT(loadSettingsView())); connect(ui.actionSettingsView, SIGNAL(triggered()), this, SLOT(loadSettingsView()));
connect(ui.actionShow_full_view, SIGNAL(triggered()), this, SLOT(loadAllView()));
connect(ui.actionStyleConfig, SIGNAL(triggered()), this, SLOT(reloadStylesheet())); connect(ui.actionStyleConfig, SIGNAL(triggered()), this, SLOT(reloadStylesheet()));
// Joystick configuration // Joystick configuration
...@@ -501,28 +506,65 @@ void MainWindow::loadEngineerView() ...@@ -501,28 +506,65 @@ void MainWindow::loadEngineerView()
void MainWindow::loadAllView() void MainWindow::loadAllView()
{ {
clearView();
GAudioOutput::instance()->say("Loaded complete view");
QDockWidget* containerPFD = new QDockWidget(tr("Primary Flight Display"), this);
containerPFD->setWidget(headDown1);
addDockWidget(Qt::RightDockWidgetArea, containerPFD);
QDockWidget* containerPayload = new QDockWidget(tr("Payload Status"), this);
containerPayload->setWidget(headDown2);
addDockWidget(Qt::RightDockWidgetArea, containerPayload);
headDown1->start();
headDown2->start();
// UAS CONTROL
QDockWidget* containerControl = new QDockWidget(tr("Control"), this);
containerControl->setWidget(control);
addDockWidget(Qt::LeftDockWidgetArea, containerControl);
// UAS LIST
QDockWidget* containerUASList = new QDockWidget(tr("Unmanned Systems"), this);
containerUASList->setWidget(list);
addDockWidget(Qt::BottomDockWidgetArea, containerUASList);
// UAS STATUS
QDockWidget* containerStatus = new QDockWidget(tr("Status Details"), this);
containerStatus->setWidget(info);
addDockWidget(Qt::LeftDockWidgetArea, containerStatus);
// WAYPOINT LIST
QDockWidget* containerWaypoints = new QDockWidget(tr("Waypoint List"), this);
containerWaypoints->setWidget(waypoints);
addDockWidget(Qt::BottomDockWidgetArea, containerWaypoints);
// DEBUG CONSOLE
QDockWidget* containerComm = new QDockWidget(tr("Communication Console"), this);
containerComm->setWidget(debugConsole);
addDockWidget(Qt::BottomDockWidgetArea, containerComm);
// OBJECT DETECTION
QDockWidget* containerObjRec = new QDockWidget(tr("Object Recognition"), this);
containerObjRec->setWidget(detection);
addDockWidget(Qt::RightDockWidgetArea, containerObjRec);
// LINE CHART
linechart->setActive(true);
centerStack->setCurrentWidget(linechart);
// ONBOARD PARAMETERS
QDockWidget* containerParams = new QDockWidget(tr("Onboard Parameters"), this);
containerParams->setWidget(parameters);
addDockWidget(Qt::RightDockWidgetArea, containerParams);
this->show();
} }
void MainWindow::loadWidgets() void MainWindow::loadWidgets()
{ {
loadOperatorView(); //loadOperatorView();
//loadEngineerView(); loadEngineerView();
//loadPilotView(); //loadPilotView();
} }
/*
void MainWindow::removeCommConfAct(QAction* action)
{
ui.menuNetwork->removeAction(action);
}*/
void MainWindow::runTests()
{
// TODO Remove after debugging: Add fake data
static double testvalue = 0.0f;
testvalue += 0.01f;
linechart->appendData(126, "test data", testvalue, MG::TIME::getGroundTimeNow());
}
...@@ -76,32 +76,6 @@ public: ...@@ -76,32 +76,6 @@ public:
MainWindow(QWidget *parent = 0); MainWindow(QWidget *parent = 0);
~MainWindow(); ~MainWindow();
QSettings settings;
UASControlWidget* control;
LinechartWidget* linechart;
UASInfoWidget* info;
CameraView* camera;
UASListWidget* list;
WaypointList* waypoints;
ObjectDetectionView* detection;
HUD* hud;
PFD* pfd;
GaugePanel* gaugePanel;
// Popup widgets
JoystickWidget* joystickWidget;
JoystickInput* joystick;
/** User interface actions **/
QAction* connectUASAct;
QAction* disconnectUASAct;
QAction* startUASAct;
QAction* returnUASAct;
QAction* stopUASAct;
QAction* killUASAct;
QAction* simulateUASAct;
public slots: public slots:
/** /**
* @brief Shows a status message on the bottom status bar * @brief Shows a status message on the bottom status bar
...@@ -112,8 +86,15 @@ public slots: ...@@ -112,8 +86,15 @@ public slots:
* @param timeout how long the status should be displayed * @param timeout how long the status should be displayed
*/ */
void showStatusMessage(const QString& status, int timeout); void showStatusMessage(const QString& status, int timeout);
void setLastAction(QString status); /**
void setLinkStatus(QString status); * @brief Shows a status message on the bottom status bar
*
* The status message will be overwritten if a new message is posted to this function.
* it will be automatically hidden after 5 seconds.
*
* @param status message text
*/
void showStatusMessage(const QString& status);
void addLink(); void addLink();
void addLink(LinkInterface* link); void addLink(LinkInterface* link);
void configure(); void configure();
...@@ -133,10 +114,8 @@ public slots: ...@@ -133,10 +114,8 @@ public slots:
/** @brief Load view with all widgets */ /** @brief Load view with all widgets */
void loadAllView(); void loadAllView();
/** @brief Reload the CSS style sheet */
void reloadStylesheet(); void reloadStylesheet();
void runTests();
protected: protected:
QStatusBar* statusBar; QStatusBar* statusBar;
QStatusBar* createStatusBar(); QStatusBar* createStatusBar();
...@@ -151,16 +130,39 @@ protected: ...@@ -151,16 +130,39 @@ protected:
MAVLinkSimulationLink* simulationLink; MAVLinkSimulationLink* simulationLink;
LinkInterface* udpLink; LinkInterface* udpLink;
QDockWidget* controlDock; QSettings settings;
QStackedWidget* centerStack; UASControlWidget* control;
LinechartWidget* linechart;
UASInfoWidget* info;
CameraView* camera;
UASListWidget* list;
WaypointList* waypoints;
ObjectDetectionView* detection;
HUD* hud;
DebugConsole* debugConsole; DebugConsole* debugConsole;
MapWidget* map; MapWidget* map;
ParameterInterface* parameters; ParameterInterface* parameters;
XMLCommProtocolWidget* protocol; XMLCommProtocolWidget* protocol;
HDDisplay* headDown1; HDDisplay* headDown1;
HDDisplay* headDown2; HDDisplay* headDown2;
GaugePanel* gaugePanel;
// Popup widgets
JoystickWidget* joystickWidget;
JoystickInput* joystick;
/** User interface actions **/
QAction* connectUASAct;
QAction* disconnectUASAct;
QAction* startUASAct;
QAction* returnUASAct;
QAction* stopUASAct;
QAction* killUASAct;
QAction* simulateUASAct;
QDockWidget* controlDock;
QStackedWidget* centerStack;
LogCompressor* comp; LogCompressor* comp;
QString screenFileName; QString screenFileName;
......
...@@ -74,6 +74,7 @@ ...@@ -74,6 +74,7 @@
<addaction name="actionOperatorView"/> <addaction name="actionOperatorView"/>
<addaction name="actionSettingsView"/> <addaction name="actionSettingsView"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionShow_full_view"/>
<addaction name="actionStyleConfig"/> <addaction name="actionStyleConfig"/>
</widget> </widget>
<addaction name="menuMGround"/> <addaction name="menuMGround"/>
...@@ -243,6 +244,15 @@ ...@@ -243,6 +244,15 @@
<string>Simulate one vehicle to test and evaluate this application</string> <string>Simulate one vehicle to test and evaluate this application</string>
</property> </property>
</action> </action>
<action name="actionShow_full_view">
<property name="icon">
<iconset resource="../../mavground.qrc">
<normaloff>:/images/status/network-transmit-receive.svg</normaloff>:/images/status/network-transmit-receive.svg</iconset>
</property>
<property name="text">
<string>Show full view</string>
</property>
</action>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<resources> <resources>
......
...@@ -43,7 +43,8 @@ This file is part of the QGROUNDCONTROL project ...@@ -43,7 +43,8 @@ This file is part of the QGROUNDCONTROL project
QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) :
QWidget(parent), QWidget(parent),
mav(uas), mav(uas),
components(new QMap<int, QTreeWidgetItem*>()) components(new QMap<int, QTreeWidgetItem*>()),
changedValues()//QMap<int, QMap<QString, float>* >())
{ {
// Create tree widget // Create tree widget
tree = new QTreeWidget(this); tree = new QTreeWidget(this);
...@@ -82,6 +83,8 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) : ...@@ -82,6 +83,8 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) :
// Connect signals/slots // Connect signals/slots
connect(this, SIGNAL(parameterChanged(int,QString,float)), mav, SLOT(setParameter(int,QString,float))); connect(this, SIGNAL(parameterChanged(int,QString,float)), mav, SLOT(setParameter(int,QString,float)));
connect(tree, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SLOT(parameterItemChanged(QTreeWidgetItem*,int)));
// New parameters from UAS // New parameters from UAS
connect(uas, SIGNAL(parameterChanged(int,int,QString,float)), this, SLOT(addParameter(int,int,QString,float))); connect(uas, SIGNAL(parameterChanged(int,int,QString,float)), this, SLOT(addParameter(int,int,QString,float)));
} }
...@@ -138,8 +141,26 @@ void QGCParamWidget::addParameter(int uas, int component, QString parameterName, ...@@ -138,8 +141,26 @@ void QGCParamWidget::addParameter(int uas, int component, QString parameterName,
{ {
addComponent(uas, component, "Component #" + QString::number(component)); addComponent(uas, component, "Component #" + QString::number(component));
} }
components->value(component)->addChild(item);
item->setFlags(item->flags() | Qt::ItemIsEditable); bool found = false;
QTreeWidgetItem* parent = components->value(component);
for (int i = 0; i < parent->childCount(); i++)
{
QTreeWidgetItem* child = parent->child(i);
QString key = child->data(0, Qt::DisplayRole).toString();
if (key == parameterName)
{
qDebug() << "UPDATED CHILD";
child->setData(1, Qt::DisplayRole, value);
found = true;
}
}
if (!found)
{
components->value(component)->addChild(item);
item->setFlags(item->flags() | Qt::ItemIsEditable);
}
//connect(item, SIGNAL()) //connect(item, SIGNAL())
tree->expandAll(); tree->expandAll();
tree->update(); tree->update();
...@@ -156,6 +177,40 @@ void QGCParamWidget::requestParameterList() ...@@ -156,6 +177,40 @@ void QGCParamWidget::requestParameterList()
mav->requestParameters(); mav->requestParameters();
} }
void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* current, int column)
{
if (current && column > 0)
{
QTreeWidgetItem* parent = current->parent();
while (parent->parent() != NULL)
{
parent = parent->parent();
}
// Parent is now top-level component
int key = components->key(parent);
if (!changedValues.contains(key))
{
changedValues.insert(key, new QMap<QString, float>());
}
QMap<QString, float>* map = changedValues.value(key, NULL);
if (map)
{
bool ok;
QString str = current->data(0, Qt::DisplayRole).toString();
float value = current->data(1, Qt::DisplayRole).toDouble(&ok);
// Send parameter to MAV
if (ok)
{
if (ok)
{
qDebug() << "PARAM CHANGED: COMP:" << key << "KEY:" << str << "VALUE:" << value;
map->insert(str, value);
}
}
}
}
}
/** /**
* @param component the subsystem which has the parameter * @param component the subsystem which has the parameter
* @param parameterName name of the parameter, as delivered by the system * @param parameterName name of the parameter, as delivered by the system
...@@ -171,36 +226,23 @@ void QGCParamWidget::setParameter(int component, QString parameterName, float va ...@@ -171,36 +226,23 @@ void QGCParamWidget::setParameter(int component, QString parameterName, float va
*/ */
void QGCParamWidget::setParameters() void QGCParamWidget::setParameters()
{ {
//mav->setParameter(component, parameterName, value);
// Iterate through all components, through all parameters and emit them // Iterate through all components, through all parameters and emit them
QMap<int, QTreeWidgetItem*>::iterator i; QMap<int, QMap<QString, float>*>::iterator i;
// Iterate through all components / subsystems for (i = changedValues.begin(); i != changedValues.end(); ++i)
for (i = components->begin(); i != components->end(); ++i)
{ {
// Get all parameters of this component // Iterate through the parameters of the component
int compid = i.key(); int compid = i.key();
QTreeWidgetItem* item = i.value(); QMap<QString, float>* comp = i.value();
for (int j = 0; j < item->childCount(); ++j)
{ {
QTreeWidgetItem* param = item->child(j); QMap<QString, float>::iterator j;
// First column is name, second column value for (j = comp->begin(); j != comp->end(); ++j)
bool ok = true;
QString key = param->data(0, Qt::DisplayRole).toString();
float value = param->data(1, Qt::DisplayRole).toDouble(&ok);
// Send parameter to MAV
if (ok)
{ {
emit parameterChanged(compid, key, value); emit parameterChanged(compid, j.key(), j.value());
qDebug() << "KEY:" << key << "VALUE:" << value;
}
else
{
qDebug() << __FILE__ << __LINE__ << "CONVERSION ERROR!";
} }
} }
} }
clear();
//mav->requestParameters(); changedValues.clear();
qDebug() << __FILE__ << __LINE__ << "SETTING ALL PARAMETERS"; qDebug() << __FILE__ << __LINE__ << "SETTING ALL PARAMETERS";
} }
......
...@@ -67,10 +67,13 @@ public slots: ...@@ -67,10 +67,13 @@ public slots:
void writeParameters(); void writeParameters();
/** @brief Clear the parameter list */ /** @brief Clear the parameter list */
void clear(); void clear();
/** @brief Update when user changes parameters */
void parameterItemChanged(QTreeWidgetItem* prev, int column);
protected: protected:
UASInterface* mav; ///< The MAV this widget is controlling UASInterface* mav; ///< The MAV this widget is controlling
QTreeWidget* tree; ///< The parameter tree QTreeWidget* tree; ///< The parameter tree
QMap<int, QTreeWidgetItem*>* components; ///< The list of components QMap<int, QTreeWidgetItem*>* components; ///< The list of components
QMap<int, QMap<QString, float>* > changedValues; ///< Changed values
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment