地面站终端 App
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

272 lines
7.9 KiB

15 years ago
/*=====================================================================
QGroundControl Open Source Ground Control Station
15 years ago
(c) 2009 - 2011 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
15 years ago
This file is part of the QGROUNDCONTROL project
15 years ago
QGROUNDCONTROL is free software: you can redistribute it and/or modify
15 years ago
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
15 years ago
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
15 years ago
======================================================================*/
/**
* @file
* @brief Main executable
* @author Lorenz Meier <mavteam@student.ethz.ch>
*
*/
#include <QtGlobal>
#include <QApplication>
11 years ago
#include <QSslSocket>
#include <QProcessEnvironment>
#include <QHostAddress>
#include <QUdpSocket>
#include <QtPlugin>
#include <QStringListModel>
#include "AppMessagesDialog.h"
11 years ago
#include "QGCApplication.h"
#define SINGLE_INSTANCE_PORT 14499
#ifndef __mobile__
#include "QGCSerialPortInfo.h"
#endif
#ifdef QT_DEBUG
#ifndef __mobile__
#include "UnitTest.h"
#endif
#include "CmdLineOptParser.h"
#ifdef Q_OS_WIN
#include <crtdbg.h>
#endif
#endif
10 years ago
#ifdef QGC_ENABLE_BLUETOOTH
#include <QtBluetooth/QBluetoothSocket>
#endif
#include <iostream>
#include "QGCMapEngine.h"
/* SDL does ugly things to main() */
#ifdef main
#undef main
#endif
#ifndef __mobile__
Q_DECLARE_METATYPE(QGCSerialPortInfo)
#endif
#ifdef Q_OS_WIN
/// @brief CRT Report Hook installed using _CrtSetReportHook. We install this hook when
/// we don't want asserts to pop a dialog on windows.
int WindowsCrtReportHook(int reportType, char* message, int* returnValue)
{
Q_UNUSED(reportType);
std::cerr << message << std::endl; // Output message to stderr
*returnValue = 0; // Don't break into debugger
return true; // We handled this fully ourselves
}
#endif
#ifdef __android__
#include <jni.h>
#include "qserialport.h"
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
Q_UNUSED(reserved);
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
QSerialPort::setNativeMethods();
return JNI_VERSION_1_6;
}
#endif
15 years ago
/**
* @brief Starts the application
*
* @param argc Number of commandline arguments
* @param argv Commandline arguments
* @return exit code, 0 for normal exit and !=0 for error cases
*/
15 years ago
int main(int argc, char *argv[])
{
#ifndef __mobile__
//-- Test for another instance already running. If that's the case, we simply exit.
QHostAddress host("127.0.0.1");
QUdpSocket socket;
if(!socket.bind(host, SINGLE_INSTANCE_PORT, QAbstractSocket::DontShareAddress)) {
qWarning() << "Another instance already running. Exiting.";
exit(-1);
}
#endif
#ifdef Q_OS_MAC
#ifndef __ios__
// Prevent Apple's app nap from screwing us over
// tip: the domain can be cross-checked on the command line with <defaults domains>
QProcess::execute("defaults write org.qgroundcontrol.qgroundcontrol NSAppSleepDisabled -bool YES");
#endif
#endif
// install the message handler
AppMessagesDialog::installHandler();
#ifdef Q_OS_WIN
// Set our own OpenGL buglist
qputenv("QT_OPENGL_BUGLIST", ":/opengl/resources/opengl/buglist.json");
// Allow for command line override of renderer
for (int i = 0; i < argc; i++) {
const QString arg(argv[i]);
if (arg == QStringLiteral("-angle")) {
QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
break;
} else if (arg == QStringLiteral("-swrast")) {
QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
break;
}
}
#endif
// The following calls to qRegisterMetaType are done to silence debug output which warns
// that we use these types in signals, and without calling qRegisterMetaType we can't queue
// these signals. In general we don't queue these signals, but we do what the warning says
// anyway to silence the debug output.
#ifndef __ios__
qRegisterMetaType<QSerialPort::SerialPortError>();
#endif
10 years ago
#ifdef QGC_ENABLE_BLUETOOTH
qRegisterMetaType<QBluetoothSocket::SocketError>();
qRegisterMetaType<QBluetoothServiceInfo>();
#endif
qRegisterMetaType<QAbstractSocket::SocketError>();
#ifndef __mobile__
qRegisterMetaType<QGCSerialPortInfo>();
#endif
10 years ago
// We statically link our own QtLocation plugin
#ifdef Q_OS_WIN
// In Windows, the compiler doesn't see the use of the class created by Q_IMPORT_PLUGIN
#pragma warning( disable : 4930 4101 )
#endif
Q_IMPORT_PLUGIN(QGeoServiceProviderFactoryQGC)
bool runUnitTests = false; // Run unit tests
#ifdef QT_DEBUG
// We parse a small set of command line options here prior to QGCApplication in order to handle the ones
// which need to be handled before a QApplication object is started.
bool stressUnitTests = false; // Stress test unit tests
bool quietWindowsAsserts = false; // Don't let asserts pop dialog boxes
QString unitTestOptions;
CmdLineOpt_t rgCmdLineOptions[] = {
{ "--unittest", &runUnitTests, &unitTestOptions },
{ "--unittest-stress", &stressUnitTests, &unitTestOptions },
{ "--no-windows-assert-ui", &quietWindowsAsserts, NULL },
// Add additional command line option flags here
};
ParseCmdLineOptions(argc, argv, rgCmdLineOptions, sizeof(rgCmdLineOptions)/sizeof(rgCmdLineOptions[0]), false);
if (stressUnitTests) {
runUnitTests = true;
}
if (quietWindowsAsserts) {
#ifdef Q_OS_WIN
_CrtSetReportHook(WindowsCrtReportHook);
#endif
}
#ifdef Q_OS_WIN
if (runUnitTests) {
// Don't pop up Windows Error Reporting dialog when app crashes. This prevents TeamCity from
// hanging.
DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
SetErrorMode(dwMode | SEM_NOGPFAULTERRORBOX);
}
#endif
#endif // QT_DEBUG
QGCApplication* app = new QGCApplication(argc, argv, runUnitTests);
Q_CHECK_PTR(app);
// There appears to be a threading issue in qRegisterMetaType which can cause it to throw a qWarning
// about duplicate type converters. This is caused by a race condition in the Qt code. Still working
// with them on tracking down the bug. For now we register the type which is giving us problems here
// while we only have the main thread. That should prevent it from hitting the race condition later
// on in the code.
qRegisterMetaType<QList<QPair<QByteArray,QByteArray> > >();
app->_initCommon();
//-- Initialize Cache System
getQGCMapEngine()->init();
int exitCode = 0;
#ifndef __mobile__
#ifdef QT_DEBUG
if (runUnitTests) {
for (int i=0; i < (stressUnitTests ? 20 : 1); i++) {
if (!app->_initForUnitTests()) {
return -1;
}
// Run the test
int failures = UnitTest::run(unitTestOptions);
if (failures == 0) {
qDebug() << "ALL TESTS PASSED";
exitCode = 0;
} else {
qDebug() << failures << " TESTS FAILED!";
exitCode = -failures;
break;
}
}
} else
#endif
#endif
{
if (!app->_initForNormalAppBoot()) {
return -1;
}
exitCode = app->exec();
}
delete app;
//-- Shutdown Cache System
destroyMapEngine();
qDebug() << "After app delete";
return exitCode;
15 years ago
}