Commit dd0e4204 authored by pixhawk's avatar pixhawk

Fixed MAV selection bug in parameter view

parents 89a3286f 3555ae74
......@@ -20,3 +20,5 @@ qgroundcontrol
qgroundcontrol.xcodeproj/**
doc/html
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()
QString time = parts.first();
QString field = parts.at(2);
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
quint64 index = times->indexOf(time);
QString outLine = outLines->at(index);
......
......@@ -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. y", pos.y, 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;
case MAVLINK_MSG_ID_POSITION:
......@@ -533,7 +543,6 @@ void UAS::requestParameters()
mavlink_msg_param_request_list_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), 0);
// Send message twice to increase chance of reception
sendMessage(msg);
sendMessage(msg);
}
void UAS::writeParameters()
......
......@@ -120,7 +120,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),
QList<QHostAddress> hostAddresses = QNetworkInterface::allAddresses();
QString windowname = qApp->applicationName() + " " + qApp->applicationVersion();
/*
windowname.append(" (" + QHostInfo::localHostName() + ": ");
bool prevAddr = false;
for (int i = 0; i < hostAddresses.size(); i++)
......@@ -135,7 +135,6 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),
}
windowname.append(")");
*/
setWindowTitle(windowname);
#ifndef Q_WS_MAC
......@@ -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()
{
// Load style sheet
//QFile styleSheet(MG::DIR::getSupportFilesDirectory() + "/images/style-mission.css");
QFile styleSheet(":/images/style-mission.css");
if (styleSheet.open(QIODevice::ReadOnly | QIODevice::Text)) {
QString style = QString(styleSheet.readAll());
style.replace("ICONDIR", MG::DIR::getIconDirectory());
QFile* styleSheet = new QFile(QCoreApplication::applicationDirPath() + "/qgroundcontrol.css");
if (!styleSheet->exists())
{
styleSheet = new QFile(":/images/style-mission.css");
}
if (styleSheet->open(QIODevice::ReadOnly | QIODevice::Text)) {
QString style = QString(styleSheet->readAll());
style.replace("ICONDIR", QCoreApplication::applicationDirPath()+ "/images/");
qApp->setStyleSheet(style);
} 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)
......@@ -235,14 +244,9 @@ void MainWindow::showStatusMessage(const QString& status, int timeout)
statusBar->showMessage(status, timeout);
}
void MainWindow::setLastAction(QString status)
void MainWindow::showStatusMessage(const QString& status)
{
showStatusMessage(status, 5);
}
void MainWindow::setLinkStatus(QString status)
{
showStatusMessage(status, 15);
statusBar->showMessage(status, 5);
}
/**
......@@ -270,6 +274,7 @@ void MainWindow::connectActions()
connect(ui.actionEngineerView, SIGNAL(triggered()), this, SLOT(loadEngineerView()));
connect(ui.actionOperatorView, SIGNAL(triggered()), this, SLOT(loadOperatorView()));
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()));
// Joystick configuration
......@@ -501,28 +506,65 @@ void MainWindow::loadEngineerView()
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()
{
loadOperatorView();
//loadEngineerView();
//loadOperatorView();
loadEngineerView();
//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:
MainWindow(QWidget *parent = 0);
~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:
/**
* @brief Shows a status message on the bottom status bar
......@@ -112,8 +86,15 @@ public slots:
* @param timeout how long the status should be displayed
*/
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(LinkInterface* link);
void configure();
......@@ -133,10 +114,8 @@ public slots:
/** @brief Load view with all widgets */
void loadAllView();
/** @brief Reload the CSS style sheet */
void reloadStylesheet();
void runTests();
protected:
QStatusBar* statusBar;
QStatusBar* createStatusBar();
......@@ -151,16 +130,39 @@ protected:
MAVLinkSimulationLink* simulationLink;
LinkInterface* udpLink;
QDockWidget* controlDock;
QStackedWidget* centerStack;
QSettings settings;
UASControlWidget* control;
LinechartWidget* linechart;
UASInfoWidget* info;
CameraView* camera;
UASListWidget* list;
WaypointList* waypoints;
ObjectDetectionView* detection;
HUD* hud;
DebugConsole* debugConsole;
MapWidget* map;
ParameterInterface* parameters;
XMLCommProtocolWidget* protocol;
HDDisplay* headDown1;
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;
QString screenFileName;
......
......@@ -74,6 +74,7 @@
<addaction name="actionOperatorView"/>
<addaction name="actionSettingsView"/>
<addaction name="separator"/>
<addaction name="actionShow_full_view"/>
<addaction name="actionStyleConfig"/>
</widget>
<addaction name="menuMGround"/>
......@@ -243,6 +244,15 @@
<string>Simulate one vehicle to test and evaluate this application</string>
</property>
</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>
<layoutdefault spacing="6" margin="11"/>
<resources>
......
......@@ -43,7 +43,8 @@ This file is part of the QGROUNDCONTROL project
QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) :
QWidget(parent),
mav(uas),
components(new QMap<int, QTreeWidgetItem*>())
components(new QMap<int, QTreeWidgetItem*>()),
changedValues()//QMap<int, QMap<QString, float>* >())
{
// Create tree widget
tree = new QTreeWidget(this);
......@@ -82,6 +83,8 @@ QGCParamWidget::QGCParamWidget(UASInterface* uas, QWidget *parent) :
// Connect signals/slots
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
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,
{
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())
tree->expandAll();
tree->update();
......@@ -156,6 +177,40 @@ void QGCParamWidget::requestParameterList()
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 parameterName name of the parameter, as delivered by the system
......@@ -171,36 +226,23 @@ void QGCParamWidget::setParameter(int component, QString parameterName, float va
*/
void QGCParamWidget::setParameters()
{
//mav->setParameter(component, parameterName, value);
// Iterate through all components, through all parameters and emit them
QMap<int, QTreeWidgetItem*>::iterator i;
// Iterate through all components / subsystems
for (i = components->begin(); i != components->end(); ++i)
QMap<int, QMap<QString, float>*>::iterator i;
for (i = changedValues.begin(); i != changedValues.end(); ++i)
{
// Get all parameters of this component
// Iterate through the parameters of the component
int compid = i.key();
QTreeWidgetItem* item = i.value();
for (int j = 0; j < item->childCount(); ++j)
QMap<QString, float>* comp = i.value();
{
QTreeWidgetItem* param = item->child(j);
// First column is name, second column value
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)
QMap<QString, float>::iterator j;
for (j = comp->begin(); j != comp->end(); ++j)
{
emit parameterChanged(compid, key, value);
qDebug() << "KEY:" << key << "VALUE:" << value;
}
else
{
qDebug() << __FILE__ << __LINE__ << "CONVERSION ERROR!";
emit parameterChanged(compid, j.key(), j.value());
}
}
}
clear();
//mav->requestParameters();
changedValues.clear();
qDebug() << __FILE__ << __LINE__ << "SETTING ALL PARAMETERS";
}
......
......@@ -67,10 +67,13 @@ public slots:
void writeParameters();
/** @brief Clear the parameter list */
void clear();
/** @brief Update when user changes parameters */
void parameterItemChanged(QTreeWidgetItem* prev, int column);
protected:
UASInterface* mav; ///< The MAV this widget is controlling
QTreeWidget* tree; ///< The parameter tree
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