Commit b445c833 authored by Lorenz Meier's avatar Lorenz Meier

First stab at better multi-use / multi-platform requirements

parent 08b25b0c
From where is the 3D mouse used?
Comm folder:
============
LinkInterface is a QThread. Appears to describe an interface on the host system (TCP port, serial port, ....).
Does it suppport multiple connections?
SerialLinkInterface: Extension of above
SerialLink: Implementation
XBeeLinkInterface: Extension of LinkInterface (but without other serial stuff than baudrate, is the rest assumed?)
XBeeLink: Implementation (with address resetting probably it's Series 1)
UDPLink: UDP implementation. Port is defaulted.
MAVLinkSimulationLink: Simulation/dummy implementation of LinkInterface. Does some file IO.
MAVLinkSimulationUAV: Simulation/dummy basic (remote) UAV state (minus mission state) for MAVLinkSimulationLink.
MAVLinkSimulationWaypointPlanner: imulation/dummy basic (remote) UAV mission state for MAVLinkSimulationLink.
ProtocolInterface describes a protocol. Major method:
virtual void receiveBytes(LinkInterface *link, QByteArray b) = 0;
MavlinkProtocol: MAVLink implementation of ProtocolInterface
Parameter: Identity of a parameter (the value types are not handled here. Oddly there is no type metainfo either)
ParameterList: Is pretty much what the name impiles.
QGCParamID: Wrapper if parameter text IDs, conversion to byte* and back
QGCHilLink: Link to a HIL external system
QCGFlightGearLink, QGCJSBSimLink, QGCXPlaneLink : Implementations of QGCHilLink
QGCMAVLink: Nothing more than in include to raw mavlink.h
input folder:
=============
Some exotic input devices
uas folder:
===========
UAS.h: Local UAV model. Claims to support some sort of RPC. Uses some properties with notifications. Assumes MAVLink.
Some methods:
int getUASID() const; // the systemId
QList<LinkInterface*>* getLinks(); // it knows its links
virtual void receiveMessage(LinkInterface* link, mavlink_message_t message);
float receiveDropRate; ///< Percentage of packets that were dropped on the MAV's receiving link (from GCS and other MAVs)
float sendDropRate; ///< Percentage of packets that were not received from the MAV by the GCS
Some fields:
bool positionLock; ///< Status if position information is available or not
double localX; // (what is this?)
double localY;
double localZ;
double latitude; ///< Global latitude as estimated by position estimator
double longitude; ///< Global longitude as estimated by position estimator
double altitude; ///< Global altitude as estimated by position estimator
double satelliteCount; ///< Number of satellites visible to raw GPS
bool globalEstimatorActive; ///< Global position estimator present, do not fall back to GPS raw for position
double latitude_gps; ///< Global latitude as estimated by raw GPS
double longitude_gps; ///< Global longitude as estimated by raw GPS
double altitude_gps; ///< Global altitude as estimated by raw GPS
and lots ans lots more...
*MAV.h: Implementations of UAS
QGCUASParamManager.h: A mixture of a widget and a parameter up/download state machine. Has a reference to its associated UAV.
UASWaypointManager: API to waypoint / mission control. Not a widget. Has a reference to its associated UAV.
UASManager.h: Singleton interface to all UASs on all interfaces. Maintains a single selected/active UAS.
Ideas to do
TCPLink
XBee Series2 implementation
Less stress on uplink
Get rid of hardcoded SystemId of 255
Quick View should print all altitudes (GPS, mix, ground and/or home), letting user see errors.
Console debugging is hopefully removed?
Major
1) Absolute altitude should absolutely work. Also in face of bad GPS init.
How does the mission planning part work with that, how is alt. stored in waypoints?
When is home altitude stored in the UAV?
2) Some people have worse datalinks than average - eg. slow or noisy telemetry. GPRS data also easily gets
flooded. All data rates should be configurable and uplinks eased off a little.
3) Some streams should be sent always even if not in use. For example using RC override and then stopping
using it: If the UAV does not received the final RC override message with zero values for all channels,
it will not get out of RC override. A solution is to make the message non final, repeating it every
now and then.
Minor
1) I would like to see initial dummy values for eg. battery voltage go away and be replaced by "unknown".
Dummy values confuse, you won't know if your sensors and link are working or not.
2) Suggestion if the DO_JUMP behavior of APM today (where DO_JUMP requires a waypoint command after it):
Modify APM code so DO_JUMP is regarded a navigation command. Make non navigation commands appear in
planning as sub commands of navigation commands (indent them). Easier to understand.
3) Old style audio with signals/bells/beeps / Morse may be prefered by some. Maybe add slots'n'signals for
all audio and different implementation types (speech, beep, ...). Or a generic operator messaging thing.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="333.93051"
height="194.91403"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.48.2 r9819"
version="1.0"
sodipodi:docname="Wi-Fi_Logo.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs4">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="1693.0157 : 423.14553 : 1"
inkscape:vp_y="6.1230318e-14 : 1000 : 0"
inkscape:vp_z="2437.1101 : 423.14553 : 1"
inkscape:persp3d-origin="2065.0629 : 247.75183 : 1"
id="perspective10" />
<inkscape:perspective
id="perspective2447"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 526.18109 : 1"
sodipodi:type="inkscape:persp3d" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
gridtolerance="10000"
guidetolerance="10"
objecttolerance="10"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.9542857"
inkscape:cx="172.92683"
inkscape:cy="89.097065"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1280"
inkscape:window-height="752"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
fit-margin-left="30"
fit-margin-top="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-115.142,-334.90274)">
<path
id="path3281"
style="fill:#000000;fill-opacity:0.67845662;fill-rule:evenodd;stroke:none"
d="m 425.2708,376.22429 0,2.17814 3.72494,0 0,10.25936 2.36754,0 0,-10.22779 3.6618,0 0,-2.24128 -9.75428,0.0316 z m 11.96399,0.0947 0,12.31124 1.89404,0 0,-9.50175 2.95615,8.25614 1.99371,-0.0139 3.06822,-8.11599 0,9.53331 1.92561,0 0,-12.50063 -3.53554,0 -2.49299,8.78645 -2.55777,-8.75489 -3.25143,0 z m -292.09192,73.99368 0,-34.85027 c 0,0 -0.37881,-15.02601 14.64721,-30.05203 15.02602,-15.02602 29.29443,-13.38452 29.29443,-13.38452 l 19.69797,0 c 0,0 24.74874,-37.12311 73.74114,-37.12311 48.99239,0 77.02413,36.61803 77.02413,36.61803 l 22.22335,0 c 0,0 5.61025,-0.25403 12.66151,3.28709 7.12703,3.57918 13.53849,7.70338 20.06663,17.83514 6.54672,10.16061 7.42543,17.48017 7.42543,22.8194 0,0 0,38.13326 0,38.13326 0,7.9502 -0.75762,14.14214 -14.14214,27.52666 -13.38452,13.38452 -30.55711,11.86929 -30.55711,11.86929 l -20.45559,0 c 0,0 -25.54935,36.82516 -73.4886,36.82516 -47.94704,0 -72.47844,-36.57262 -72.47844,-36.57262 l -22.72844,0 c 0,0 -15.02602,0.88388 -29.54696,-13.63706 -14.52094,-14.52094 -13.13198,-29.29442 -13.38452,-29.29442 z m 24.11739,-50.12882 14.14214,60.98796 15.53109,0 6.9448,-35.1028 6.69226,35.1028 15.90991,0 14.14213,-60.60916 -16.92005,0 -4.9245,33.20877 -6.9448,-33.33503 -15.27855,0 -6.9448,33.71384 -5.17704,-33.84011 -17.17259,-0.12627 z m 81.3542,17.06072 0,43.87112 14.92523,0 0,-43.87112 -14.92523,0 z m 17.18663,-12.39246 c 0,4.24419 -4.21453,7.68875 -9.40742,7.68875 -5.19289,0 -9.40741,-3.44456 -9.40741,-7.68875 0,-4.24419 4.21452,-7.68875 9.40741,-7.68875 5.19289,0 9.40742,3.44456 9.40742,7.68875 z m 3.61823,79.51075 c 0,0 18.63392,-14.14069 18.63392,-35.18735 0,0 0,-35.45872 0,-35.45872 0,-5.70122 2.92325,-13.77796 11.66881,-22.52352 8.74556,-8.74556 16.45238,-10.13106 21.79988,-10.13106 0,0 55.53993,0 55.53993,0 9.44034,0.13157 16.77581,4.08862 23.51853,10.40243 6.24776,6.5645 10.31198,14.7908 10.31198,23.7899 l 0,33.92097 c 0,6.67743 -1.79054,16.35395 -10.6738,24.51355 -8.88326,8.1596 -15.72893,10.6738 -22.79489,10.6738 0,0 -108.00436,0 -108.00436,0 z m 102.57695,-67.07307 0,43.87112 14.92523,0 0,-43.87112 -14.92523,0 z m 17.18663,-12.39246 c 0,4.24419 -4.21453,7.68875 -9.40742,7.68875 -5.19289,0 -9.40741,-3.44456 -9.40741,-7.68875 0,-4.24419 4.21452,-7.68875 9.40741,-7.68875 5.19289,0 9.40742,3.44456 9.40742,7.68875 z m -79.96297,55.94699 16.73434,0 0,-18.27209 31.84048,0 0,-13.65885 -31.93094,0 0,-14.29203 36.09191,0 0,-14.20158 -52.82625,0 0.0905,60.42455 z"
sodipodi:nodetypes="cccccccccccccccccccccccccsccsccssccsccsccscccccccccccccccccccccsssccccscccccsccccccccssscccccccccccc"
inkscape:connector-curvature="0" />
<path
style="fill:#ffffff;fill-opacity:1"
d="m 38.354192,125.39247 c -0.447841,-1.33494 -13.57503,-58.49942 -13.57503,-59.114671 0,-0.48498 1.9789,-0.63957 8.187134,-0.63957 4.502924,0 8.186134,0.172698 8.18491,0.383772 -0.0037,0.647807 4.627377,31.001373 4.937987,32.364766 0.270505,1.187355 0.318138,1.205732 0.663146,0.255848 0.204438,-0.562865 1.849042,-8.224778 3.654674,-17.026473 l 3.282968,-16.003081 7.397918,0.140508 7.397918,0.140508 3.351251,16.207259 c 1.843189,8.913993 3.491965,16.347975 3.663951,16.519961 0.410989,0.410989 0.489125,-0.03701 3.052972,-17.504267 l 2.196869,-14.967105 8.08871,0 c 4.448792,0 8.088715,0.146356 8.088715,0.325235 0,0.369669 -13.215396,57.27129 -13.620925,58.64772 -0.235948,0.80083 -1.067679,0.89547 -7.870303,0.89547 -6.80128,0 -7.634776,-0.0948 -7.873834,-0.89547 -0.147049,-0.49251 -1.662973,-8.2484 -3.368722,-17.23531 -1.70575,-8.986918 -3.207377,-16.445862 -3.336949,-16.575435 -0.399998,-0.399997 -0.6438,0.693065 -3.974724,17.820245 l -3.234254,16.63012 -7.537598,0.14166 c -5.760068,0.10826 -7.589287,-0.0124 -7.756784,-0.51169 l 0,0 z"
id="path2814"
transform="translate(145.14287,334.86218)"
inkscape:connector-curvature="0" />
<path
style="fill:#ffffff;fill-opacity:1"
d="m 105.62712,104.27127 0,-21.747076 7.16374,0 7.16374,0 0,21.747076 0,21.74708 -7.16374,0 -7.16374,0 0,-21.74708 z"
id="path2816"
transform="translate(145.14287,334.86218)"
inkscape:connector-curvature="0" />
<path
style="fill:#ffffff;fill-opacity:1"
d="m 109.87745,76.869158 c -0.89879,-0.274794 -2.43346,-1.253464 -3.41039,-2.174822 -3.38782,-3.195125 -2.84853,-7.712365 1.24406,-10.420717 1.77034,-1.171553 2.73293,-1.434018 5.28517,-1.441081 11.80196,-0.03266 12.57809,13.617509 0.81796,14.385811 -1.26645,0.08274 -3.03801,-0.0744 -3.9368,-0.349191 z"
id="path2818"
transform="translate(145.14287,334.86218)"
inkscape:connector-curvature="0" />
<path
style="fill:#ffffff;fill-opacity:1"
d="m 131.32077,145.03949 c 5.99946,-6.27956 9.7733,-12.3945 12.21262,-19.78869 1.14295,-3.46456 1.19165,-4.34438 1.4868,-26.864033 0.32797,-25.023316 0.28749,-24.638195 3.19979,-30.445906 1.70145,-3.393049 5.82578,-8.649151 9.52503,-12.138837 4.09514,-3.863152 8.24462,-6.493302 12.86749,-8.156074 l 3.32602,-1.196317 31.72515,0 c 34.90986,0 34.3956,-0.0405 41.44736,3.264291 8.94786,4.193392 17.21604,14.283171 19.4424,23.725842 1.12494,4.77119 1.11347,44.373344 -0.0141,48.761274 -2.33503,9.08667 -8.82127,17.19952 -18.26049,22.83986 -7.16609,4.28206 -2.63115,4.00376 -65.24325,4.00376 l -55.54131,0 3.82652,-4.00517 z m 112.46424,-40.76822 0,-22.258772 -7.67544,0 -7.67544,0 0,22.258772 0,22.25877 7.67544,0 7.67544,0 0,-22.25877 z m -60.89181,12.7924 0,-8.95468 16.11842,0 16.11842,0 0,-7.16374 0,-7.163746 -16.11842,0 -16.11842,0 0,-6.907895 0,-6.907894 18.1652,0 18.16521,0 0,-7.419591 0,-7.419591 -26.94439,0 -26.9444,0 0.33621,8.524707 c 0.18491,4.688588 0.3362,18.389246 0.3362,30.44591 l 0,21.9212 8.44299,0 8.44298,0 0,-8.95468 z m 57.44753,-39.686008 c 5.50647,-1.529182 7.77524,-8.26653 4.05144,-12.0312 -4.33496,-4.382541 -11.79449,-4.258949 -15.59558,0.258391 -2.58713,3.074625 -2.45591,6.604646 0.34982,9.410366 2.64079,2.640792 6.9314,3.54628 11.19432,2.362443 l 0,0 z"
id="path2820"
transform="translate(145.14287,334.86218)"
inkscape:connector-curvature="0" />
</g>
</svg>
......@@ -5,6 +5,11 @@
font-size: 11px;
}
QWidget#viewModeWidget {
border-radius: 12px;
border: 3px solid #465158;
}
*::disabled {
color: #777;
}
......@@ -340,6 +345,16 @@ QPushButton, QToolButton {
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #777, stop: 1 #333);
}
QPushButton#viewModeGeneric, QPushButton#viewModePX4, QPushButton#viewModeAPM, QPushButton#viewModeAR {
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #73D95D, stop: 1 #18A154);
border-radius: 12px;
min-height: 120px;
max-height: 140px;
min-width: 120px;
max-width: 140px;
border: 3px solid #465158;
}
QPushButton#connectButton, QPushButton#controlButton {
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #73D95D, stop: 1 #18A154);
}
......
......@@ -236,7 +236,9 @@ FORMS += src/ui/MainWindow.ui \
src/ui/UASRawStatusView.ui \
src/ui/uas/QGCMessageView.ui \
src/ui/JoystickButton.ui \
src/ui/JoystickAxis.ui
src/ui/JoystickAxis.ui \
src/ui/main/QGCViewModeSelection.ui \
src/ui/main/QGCWelcomeMainWindow.ui
INCLUDEPATH += src \
src/ui \
src/ui/linechart \
......@@ -252,7 +254,8 @@ INCLUDEPATH += src \
src/ui/watchdog \
src/ui/map3D \
src/ui/mission \
src/ui/designer
src/ui/designer \
src/ui/main
HEADERS += src/MG.h \
src/QGCCore.h \
src/uas/UASInterface.h \
......@@ -395,7 +398,9 @@ HEADERS += src/MG.h \
src/ui/PrimaryFlightDisplay.h \
src/ui/uas/QGCMessageView.h \
src/ui/JoystickButton.h \
src/ui/JoystickAxis.h
src/ui/JoystickAxis.h \
src/ui/main/QGCViewModeSelection.h \
src/ui/main/QGCWelcomeMainWindow.h
# Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler
macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h
......@@ -573,7 +578,9 @@ SOURCES += src/main.cc \
src/ui/PrimaryFlightDisplay.cc \
src/ui/uas/QGCMessageView.cc \
src/ui/JoystickButton.cc \
src/ui/JoystickAxis.cc
src/ui/JoystickAxis.cc \
src/ui/main/QGCViewModeSelection.cc \
src/ui/main/QGCWelcomeMainWindow.cc
# Enable Google Earth only on Mac OS and Windows with Visual Studio compiler
macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc
......
......@@ -102,6 +102,11 @@
<file>files/images/patterns/lenna.jpg</file>
<file>files/images/rc_stick.svg</file>
<file>files/images/actions/qgroundcontrol-connect.svg</file>
<file>files/images/actions/qgroundcontrol-generic.svg</file>
<file>files/images/actions/qgroundcontrol-px4.svg</file>
<file>files/images/actions/qgroundcontrol-apm.svg</file>
<file>files/images/actions/qgroundcontrol-ardrone.svg</file>
<file>files/images/actions/qgroundcontrol-wifi.svg</file>
</qresource>
<qresource prefix="/general">
<file alias="vera.ttf">files/styles/Vera.ttf</file>
......
......@@ -45,6 +45,7 @@ This file is part of the QGROUNDCONTROL project
#include "QGC.h"
#include "QGCCore.h"
#include "MainWindow.h"
#include "QGCWelcomeMainWindow.h"
#include "GAudioOutput.h"
#ifdef OPAL_RT
......@@ -65,8 +66,13 @@ This file is part of the QGROUNDCONTROL project
**/
QGCCore::QGCCore(int &argc, char* argv[]) : QApplication(argc, argv)
QGCCore::QGCCore(bool firstStart, int &argc, char* argv[]) : QApplication(argc, argv),
restartRequested(false),
welcome(NULL)
{
// Exit main application when last window is closed
connect(this, SIGNAL(lastWindowClosed()), this, SLOT(quit()));
// Set application name
this->setApplicationName(QGC_APPLICATION_NAME);
this->setApplicationVersion(QGC_APPLICATION_VERSION);
......@@ -83,8 +89,9 @@ QGCCore::QGCCore(int &argc, char* argv[]) : QApplication(argc, argv)
// Show user an upgrade message if QGC got upgraded (see code below, after splash screen)
bool upgraded = false;
enum MainWindow::CUSTOM_MODE mode = MainWindow::CUSTOM_MODE_NONE;
QString lastApplicationVersion("");
if (settings.contains("QGC_APPLICATION_VERSION"))
if (settings.contains("QGC_APPLICATION_VERSION") && firstStart)
{
QString qgcVersion = settings.value("QGC_APPLICATION_VERSION").toString();
if (qgcVersion != QGC_APPLICATION_VERSION)
......@@ -95,6 +102,10 @@ QGCCore::QGCCore(int &argc, char* argv[]) : QApplication(argc, argv)
settings.setValue("QGC_APPLICATION_VERSION", QGC_APPLICATION_VERSION);
upgraded = true;
}
else
{
mode = (enum MainWindow::CUSTOM_MODE) settings.value("QGC_CUSTOM_MODE", (int)MainWindow::CUSTOM_MODE_NONE).toInt();
}
}
else
{
......@@ -106,6 +117,15 @@ QGCCore::QGCCore(int &argc, char* argv[]) : QApplication(argc, argv)
settings.sync();
// "Bootload" the application
if ((!settings.contains("QGC_CUSTOM_MODE_STORED") || settings.value("QGC_CUSTOM_MODE_STORED") == false) && firstStart)
{
welcome = new QGCWelcomeMainWindow();
connect(welcome, SIGNAL(customViewModeSelected(MainWindow::CUSTOM_MODE)), this, SLOT(customViewModeSelected(MainWindow::CUSTOM_MODE)));
restartRequested = true;
return;
}
// Show splash screen
QPixmap splashImage(":/files/images/splash.png");
QSplashScreen* splashScreen = new QSplashScreen(splashImage);
......@@ -115,9 +135,6 @@ QGCCore::QGCCore(int &argc, char* argv[]) : QApplication(argc, argv)
processEvents();
splashScreen->showMessage(tr("Loading application fonts"), Qt::AlignLeft | Qt::AlignBottom, QColor(62, 93, 141));
// Exit main application when last window is closed
connect(this, SIGNAL(lastWindowClosed()), this, SLOT(quit()));
// Load application font
QFontDatabase fontDatabase = QFontDatabase();
const QString fontFileName = ":/general/vera.ttf"; ///< Font file is part of the QRC file and compiled into the app
......@@ -140,16 +157,19 @@ QGCCore::QGCCore(int &argc, char* argv[]) : QApplication(argc, argv)
splashScreen->showMessage(tr("Starting user interface"), Qt::AlignLeft | Qt::AlignBottom, QColor(62, 93, 141));
// The first call to instance() creates the MainWindow, so make sure it's passed the splashScreen.
mainWindow = MainWindow::instance(splashScreen);
mainWindow = MainWindow::instance_mode(splashScreen, mode);
// Connect links
// to make sure that all components are initialized when the
// first messages arrive
UDPLink* udpLink = new UDPLink(QHostAddress::Any, 14550);
MainWindow::instance()->addLink(udpLink);
// Listen on Multicast-Address 239.255.77.77, Port 14550
//QHostAddress * multicast_udp = new QHostAddress("239.255.77.77");
//UDPLink* udpLink = new UDPLink(*multicast_udp, 14550);
UDPLink* udpLink = NULL;
//if (mainWindow->getCustomMode() == MainWindow::CUSTOM_MODE_WIFI)
if (settings.value("QGC_CUSTOM_MODE", (unsigned int)MainWindow::CUSTOM_MODE_NONE) == MainWindow::CUSTOM_MODE_WIFI)
{
// Connect links
// to make sure that all components are initialized when the
// first messages arrive
udpLink = new UDPLink(QHostAddress::Any, 14550);
MainWindow::instance()->addLink(udpLink);
}
#ifdef OPAL_RT
// Add OpalRT Link, but do not connect
......@@ -165,7 +185,7 @@ QGCCore::QGCCore(int &argc, char* argv[]) : QApplication(argc, argv)
if (upgraded) mainWindow->showInfoMessage(tr("Default Settings Loaded"), tr("QGroundControl has been upgraded from version %1 to version %2. Some of your user preferences have been reset to defaults for safety reasons. Please adjust them where needed.").arg(lastApplicationVersion).arg(QGC_APPLICATION_VERSION));
// Check if link could be connected
if (!udpLink->connect())
if (udpLink && !udpLink->connect())
{
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Critical);
......@@ -193,17 +213,24 @@ QGCCore::QGCCore(int &argc, char* argv[]) : QApplication(argc, argv)
**/
QGCCore::~QGCCore()
{
//mainWindow->storeSettings();
//mainWindow->close();
//mainWindow->deleteLater();
// Delete singletons
// First systems
delete UASManager::instance();
// then links
delete LinkManager::instance();
// Finally the main window
//delete MainWindow::instance();
//The main window now autodeletes on close.
if (welcome)
{
welcome->close();
delete welcome;
} else {
//mainWindow->storeSettings();
//mainWindow->close();
//mainWindow->deleteLater();
// Delete singletons
// First systems
delete UASManager::instance();
// then links
delete LinkManager::instance();
// Finally the main window
//delete MainWindow::instance();
//The main window now autodeletes on close.
}
}
/**
......@@ -258,4 +285,14 @@ void QGCCore::startUASManager()
}
}
void QGCCore::customViewModeSelected(enum MainWindow::CUSTOM_MODE mode)
{
qDebug() << "SET MODE =" << (unsigned int)mode;
QSettings settings;
settings.setValue("QGC_CUSTOM_MODE", (unsigned int)mode);
// Store settings only if requested by user
settings.setValue("QGC_CUSTOM_MODE_STORED", welcome->getStoreSettings());
settings.sync();
welcome->close();
}
......@@ -36,6 +36,7 @@ This file is part of the PIXHAWK project
#include <QApplication>
#include "MainWindow.h"
#include "QGCWelcomeMainWindow.h"
#include "UASManager.h"
#include "LinkManager.h"
/*#include "ViconTarsusProtocol.h" */
......@@ -56,9 +57,17 @@ class QGCCore : public QApplication
Q_OBJECT
public:
QGCCore(int &argc, char* argv[]);
QGCCore(bool firstStart, int &argc, char* argv[]);
~QGCCore();
bool getRestartRequested()
{
return restartRequested;
}
public slots:
void customViewModeSelected(enum MainWindow::CUSTOM_MODE mode);
protected:
void startLinkManager();
......@@ -71,6 +80,8 @@ protected:
private:
MainWindow* mainWindow;
bool restartRequested;
QGCWelcomeMainWindow* welcome;
};
#endif /* _CORE_H_ */
......@@ -11,14 +11,14 @@
#define WITH_TEXT_TO_SPEECH 1
#define QGC_APPLICATION_NAME "QGroundControl"
#define QGC_APPLICATION_VERSION "v. 1.0.9 (beta RC1)"
#define QGC_APPLICATION_VERSION "v. 1.1.1 (beta)"
namespace QGC
{
const QString APPNAME = "QGROUNDCONTROL";
const QString COMPANYNAME = "QGROUNDCONTROL";
const int APPLICATIONVERSION = 109; // 1.0.9
const int APPLICATIONVERSION = 110; // 1.1.0
}
#endif // QGC_CONFIGURATION_H
......@@ -69,6 +69,18 @@ int main(int argc, char *argv[])
qInstallMsgHandler( msgHandler );
#endif
QGCCore core(argc, argv);
return core.exec();
QGCCore* core = NULL;
int val;
bool firstStart = true;
do {
if (core) {
delete core;
firstStart = false;
}
core = new QGCCore(firstStart, argc, argv);
val = core->exec();
} while (core->getRestartRequested());
return val;
}
......@@ -80,12 +80,13 @@ This file is part of the QGROUNDCONTROL project
const QString MainWindow::defaultDarkStyle = ":files/styles/style-dark.css";
const QString MainWindow::defaultLightStyle = ":files/styles/style-light.css";
MainWindow* MainWindow::instance(QSplashScreen* screen)
MainWindow* MainWindow::instance_mode(QSplashScreen* screen, enum MainWindow::CUSTOM_MODE mode)
{
static MainWindow* _instance = 0;
if (_instance == 0)
{
_instance = new MainWindow();
_instance->setCustomMode(mode);
if (screen)
{
connect(_instance, SIGNAL(initStatusChanged(QString,int,QColor)),
......@@ -96,6 +97,11 @@ MainWindow* MainWindow::instance(QSplashScreen* screen)
return _instance;
}
MainWindow* MainWindow::instance(QSplashScreen* screen)
{
instance_mode(screen, CUSTOM_MODE_NONE);
}
/**
* Create new mainwindow. The constructor instantiates all parts of the user
* interface. It does NOT show the mainwindow. To display it, call the show()
......@@ -115,16 +121,15 @@ MainWindow::MainWindow(QWidget *parent):
autoReconnect(false),
lowPowerMode(false),
isAdvancedMode(false),
dockWidgetTitleBarEnabled(true)
dockWidgetTitleBarEnabled(true),
customMode(CUSTOM_MODE_WIFI)
{
this->setAttribute(Qt::WA_DeleteOnClose);
hide();
loadSettings();
}
void MainWindow::init()
{
emit initStatusChanged(tr("Loading settings"), Qt::AlignLeft | Qt::AlignBottom, QColor(62, 93, 141));
loadSettings();
emit initStatusChanged(tr("Loading style"), Qt::AlignLeft | Qt::AlignBottom, QColor(62, 93, 141));
qApp->setStyle("plastique");
......@@ -1139,6 +1144,9 @@ void MainWindow::loadCustomWidgetsFromDefaults(const QString& systemType, const
void MainWindow::loadSettings()
{
QSettings settings;
settings.sync();
customMode = static_cast<enum MainWindow::CUSTOM_MODE>(settings.value("QGC_CUSTOM_MODE", (unsigned int)MainWindow::CUSTOM_MODE_NONE).toInt());
qDebug() << "MAINWINDOW: CUSTOM MODE:" << customMode;
settings.beginGroup("QGC_MAINWINDOW");
autoReconnect = settings.value("AUTO_RECONNECT", autoReconnect).toBool();
currentStyle = (QGC_MAINWINDOW_STYLE)settings.value("CURRENT_STYLE", currentStyle).toInt();
......@@ -1171,6 +1179,7 @@ void MainWindow::storeSettings()
// Save the current power mode
}
settings.setValue("LOW_POWER_MODE", lowPowerMode);
settings.setValue("QGC_CUSTOM_MODE", (int)customMode);
settings.sync();
}
......
......@@ -97,6 +97,14 @@ class MainWindow : public QMainWindow
Q_OBJECT
public:
enum CUSTOM_MODE {
CUSTOM_MODE_NONE = 0,
CUSTOM_MODE_PX4,
CUSTOM_MODE_APM,
CUSTOM_MODE_WIFI
};
/**
* A static function for obtaining the sole instance of the MainWindow. The screen
* argument is only important on the FIRST call to this function. The provided splash
......@@ -104,6 +112,7 @@ public:
* function cannot be used within the MainWindow constructor!
*/
static MainWindow* instance(QSplashScreen* screen = 0);
static MainWindow* instance_mode(QSplashScreen* screen = 0, enum MainWindow::CUSTOM_MODE mode = MainWindow::CUSTOM_MODE_NONE);
/**
* Initializes the MainWindow. Some variables are initialized and the widget is hidden.
......@@ -167,6 +176,16 @@ public:
return lowPowerMode;
}
void setCustomMode(enum MainWindow::CUSTOM_MODE mode)
{
customMode = mode;
}
enum MainWindow::CUSTOM_MODE getCustomMode()
{
return customMode;
}
QList<QAction*> listLinkMenuActions(void);
public slots:
......@@ -480,6 +499,7 @@ private:
QMap<VIEW_SECTIONS,QMap<QString,QWidget*> > centralWidgetToDockWidgetsMap;
bool isAdvancedMode; ///< If enabled dock widgets can be moved and floated.
bool dockWidgetTitleBarEnabled; ///< If enabled, dock widget titlebars are displayed when NOT in advanced mode.
CUSTOM_MODE customMode;
Ui::MainWindow ui;
/** @brief Set the appropriate titlebar for a given dock widget.
......
......@@ -48,10 +48,20 @@ QGCSettingsWidget::QGCSettingsWidget(QWidget *parent, Qt::WindowFlags flags) :
ui->lowPowerCheckBox->setChecked(mainWindow->lowPowerModeEnabled());
connect(ui->lowPowerCheckBox, SIGNAL(clicked(bool)), mainWindow, SLOT(enableLowPowerMode(bool)));
//Dock widget title bars
// Dock widget title bars
ui->titleBarCheckBox->setChecked(mainWindow->dockWidgetTitleBarsEnabled());
connect(ui->titleBarCheckBox,SIGNAL(clicked(bool)),mainWindow,SLOT(enableDockWidgetTitleBars(bool)));
// Custom mode
ui->customModeComboBox->addItem(tr("Default: Generic MAVLink and serial links"), MainWindow::CUSTOM_MODE_NONE);
ui->customModeComboBox->addItem(tr("Wifi: Generic MAVLink, wifi or serial links"), MainWindow::CUSTOM_MODE_WIFI);
ui->customModeComboBox->addItem(tr("PX4: Optimized for PX4 Autopilot Users"), MainWindow::CUSTOM_MODE_PX4);
ui->customModeComboBox->addItem(tr("APM: Optimized for ArduPilot Users"), MainWindow::CUSTOM_MODE_APM);
ui->customModeComboBox->setCurrentIndex(ui->customModeComboBox->findData(mainWindow->getCustomMode()));
connect(ui->customModeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(selectCustomMode(int)));
// Intialize the style UI to the proper values obtained from the MainWindow.
MainWindow::QGC_MAINWINDOW_STYLE style = mainWindow->getStyle();
ui->styleChooser->setCurrentIndex(style);
......@@ -177,3 +187,9 @@ void QGCSettingsWidget::setDefaultStyle()
mainWindow->loadStyle(MainWindow::QGC_MAINWINDOW_STYLE_DARK, MainWindow::defaultDarkStyle);
}
}
void QGCSettingsWidget::selectCustomMode(int mode)
{
MainWindow::instance()->setCustomMode(static_cast<enum MainWindow::CUSTOM_MODE>(ui->customModeComboBox->itemData(mode).toInt()));
MainWindow::instance()->showInfoMessage(tr("Please restart QGroundControl"), tr("The optimization selection was changed. The application needs to be closed and restarted to put all optimizations into effect."));
}
......@@ -22,6 +22,7 @@ public slots:
void lineEditFinished();
void setDefaultStyle();
void selectStylesheet();
void selectCustomMode(int mode);
private:
MainWindow* mainWindow;
......
......@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>528</width>
<height>321</height>
<height>455</height>
</rect>
</property>
<property name="sizePolicy">
......@@ -72,6 +72,9 @@
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="customModeComboBox"/>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
......
......@@ -301,7 +301,8 @@ void QGCToolBar::advancedActivityTriggered(QAction* action)
void QGCToolBar::setActiveUAS(UASInterface* active)
{
// Do nothing if system is the same
if (mav == active) return;
if (mav == active || active == NULL)
return;
// If switching UASes, disconnect the only one.
if (mav)
......
#include "QGCViewModeSelection.h"
#include "ui_QGCViewModeSelection.h"
#include "QGC.h"
#include "MainWindow.h"
QGCViewModeSelection::QGCViewModeSelection(QWidget *parent) :
QWidget(parent),
selected(false),
ui(new Ui::QGCViewModeSelection)
{
ui->setupUi(this);
connect(ui->viewModeGeneric, SIGNAL(clicked()), this, SLOT(selectGeneric()));
connect(ui->viewModeAR, SIGNAL(clicked()), this, SLOT(selectWifi()));
connect(ui->viewModePX4, SIGNAL(clicked()), this, SLOT(selectPX4()));
connect(ui->viewModeAPM, SIGNAL(clicked()), this, SLOT(selectAPM()));
connect(ui->notAgainCheckBox, SIGNAL(clicked(bool)), this, SIGNAL(settingsStorageRequested(bool)));
}
QGCViewModeSelection::~QGCViewModeSelection()
{
delete ui;
}
enum MainWindow::CUSTOM_MODE QGCViewModeSelection::waitForInput() {
while (!selected)
QGC::SLEEP::msleep(200);
return mode;
}
void QGCViewModeSelection::selectGeneric() {
emit customViewModeSelected(MainWindow::CUSTOM_MODE_NONE);
mode = MainWindow::CUSTOM_MODE_NONE;
selected = true;
}
void QGCViewModeSelection::selectWifi() {
emit customViewModeSelected(MainWindow::CUSTOM_MODE_WIFI);
mode = MainWindow::CUSTOM_MODE_WIFI;
selected = true;
}
void QGCViewModeSelection::selectPX4() {
emit customViewModeSelected(MainWindow::CUSTOM_MODE_PX4);
mode = MainWindow::CUSTOM_MODE_PX4;
selected = true;
}
void QGCViewModeSelection::selectAPM() {
emit customViewModeSelected(MainWindow::CUSTOM_MODE_APM);
mode = MainWindow::CUSTOM_MODE_APM;
selected = true;
}
#ifndef QGCVIEWMODESELECTION_H
#define QGCVIEWMODESELECTION_H
#include <QWidget>
#include "MainWindow.h"
namespace Ui {
class QGCViewModeSelection;
}
class QGCViewModeSelection : public QWidget
{
Q_OBJECT
public:
explicit QGCViewModeSelection(QWidget *parent = 0);
~QGCViewModeSelection();
enum MainWindow::CUSTOM_MODE waitForInput();
public slots:
void selectGeneric();
void selectPX4();
void selectAPM();
void selectWifi();
signals:
void customViewModeSelected(enum MainWindow::CUSTOM_MODE mode);
void settingsStorageRequested(bool requested);
private:
Ui::QGCViewModeSelection *ui;
bool selected;
enum MainWindow::CUSTOM_MODE mode;
};
#endif // QGCVIEWMODESELECTION_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QGCViewModeSelection</class>
<widget class="QWidget" name="QGCViewModeSelection">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>750</width>
<height>409</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="2" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>47</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="1">
<widget class="QWidget" name="viewModeWidget" native="true">
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="2">
<widget class="QPushButton" name="viewModePX4">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../qgroundcontrol.qrc">
<normaloff>:/files/images/actions/qgroundcontrol-px4.svg</normaloff>:/files/images/actions/qgroundcontrol-px4.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>120</width>
<height>120</height>
</size>
</property>
</widget>
</item>
<item row="4" column="0" colspan="4">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="viewModeGeneric">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../qgroundcontrol.qrc">
<normaloff>:/files/images/actions/qgroundcontrol-generic.svg</normaloff>:/files/images/actions/qgroundcontrol-generic.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>120</width>
<height>120</height>
</size>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Radio / Serial Link</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="viewModeAR">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../qgroundcontrol.qrc">
<normaloff>:/files/images/actions/qgroundcontrol-wifi.svg</normaloff>:/files/images/actions/qgroundcontrol-wifi.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>120</width>
<height>120</height>
</size>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="label_2">
<property name="text">
<string>PX4 Autopilot</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_4">
<property name="text">
<string>WiFi / UDP</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QLabel" name="label_3">
<property name="text">
<string>APM Autopilot</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QPushButton" name="viewModeAPM">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../qgroundcontrol.qrc">
<normaloff>:/files/images/actions/qgroundcontrol-apm.svg</normaloff>:/files/images/actions/qgroundcontrol-apm.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>120</width>
<height>120</height>
</size>
</property>
</widget>
</item>
<item row="3" column="0" colspan="4">
<widget class="QCheckBox" name="notAgainCheckBox">
<property name="text">
<string>Do not ask again on next startup</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>76</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<widget class="QLabel" name="viewModeHintLabel">
<property name="text">
<string>Please select the connection or autopilot you want to use QGroundControl with.</string>
</property>
</widget>
</item>
<item row="4" column="1">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>76</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>46</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="1">
<widget class="QLabel" name="viewModeExplanationLabel">
<property name="text">
<string>The selection can be changed any time in the preferences.</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../../../qgroundcontrol.qrc"/>
</resources>
<connections/>
</ui>
#include "QGCWelcomeMainWindow.h"
#include "ui_QGCWelcomeMainWindow.h"
#include "MainWindow.h"
#include "QGCViewModeSelection.h"
QGCWelcomeMainWindow::QGCWelcomeMainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::QGCWelcomeMainWindow),
storeSettings(false)
{
ui->setupUi(this);
statusBar()->hide();
QString windowname = qApp->applicationName() + " " + qApp->applicationVersion();
setWindowTitle(windowname);
viewModeSelection = new QGCViewModeSelection(this);
connect(viewModeSelection, SIGNAL(customViewModeSelected(MainWindow::CUSTOM_MODE)), this, SIGNAL(customViewModeSelected(MainWindow::CUSTOM_MODE)));
connect(viewModeSelection, SIGNAL(settingsStorageRequested(bool)), this, SIGNAL(settingsStorageRequested(bool)));
connect(viewModeSelection, SIGNAL(settingsStorageRequested(bool)), this, SLOT(setStoreSettings(bool)));
setCentralWidget(viewModeSelection);
// Load the new stylesheet.
QFile styleSheet(":files/styles/style-dark.css");
// Attempt to open the stylesheet.
if (styleSheet.open(QIODevice::ReadOnly | QIODevice::Text))
{
// Signal to the user that the app will pause to apply a new stylesheet
qApp->setOverrideCursor(Qt::WaitCursor);
qApp->setStyleSheet(styleSheet.readAll());
// Finally restore the cursor before returning.
qApp->restoreOverrideCursor();
}
resize(780, 400);
show();
}
QGCWelcomeMainWindow::~QGCWelcomeMainWindow()
{
delete ui;
delete viewModeSelection;
}
enum MainWindow::CUSTOM_MODE QGCWelcomeMainWindow::getCustomMode()
{
// QGCViewModeSelection* s = new QGCViewModeSelection(this);
// setCentralWidget(s);
// show();
// enum MainWindow::CUSTOM_MODE mode = MainWindow::CUSTOM_MODE_WIFI;// = s->waitForInput();
// delete s;
// return mode;
}
#ifndef QGCWELCOMEMAINWINDOW_H
#define QGCWELCOMEMAINWINDOW_H
#include <QMainWindow>
#include "MainWindow.h"
#include "QGCViewModeSelection.h"
namespace Ui {
class QGCWelcomeMainWindow;
}
class QGCWelcomeMainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit QGCWelcomeMainWindow(QWidget *parent = 0);
~QGCWelcomeMainWindow();
enum MainWindow::CUSTOM_MODE getCustomMode();
bool getStoreSettings()
{
return storeSettings;
}
public slots:
void setStoreSettings(bool settings)
{
storeSettings = settings;
}
signals:
void customViewModeSelected(enum MainWindow::CUSTOM_MODE mode);
void settingsStorageRequested(bool requested);
private:
Ui::QGCWelcomeMainWindow *ui;
QGCViewModeSelection* viewModeSelection;
bool storeSettings;
};
#endif // QGCWELCOMEMAINWINDOW_H
<ui version="4.0">
<author/>
<comment/>
<exportmacro/>
<class>QGCWelcomeMainWindow</class>
<widget class="QMainWindow" name="QGCWelcomeMainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QMenuBar" name="menubar"/>
<widget class="QWidget" name="centralwidget"/>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<pixmapfunction/>
<connections/>
</ui>
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