ProcessReporter::ProcessReporter(QProcess* process, QString name) : mName(name) { CX_ASSERT(process); mProcess = process; connect(mProcess, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(processStateChanged(QProcess::ProcessState))); connect(mProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError))); connect(mProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(processFinished(int, QProcess::ExitStatus))); connect(mProcess, SIGNAL(readyRead()), this, SLOT(processReadyRead())); }
KegMeterConnection::KegMeterConnection(MainWindow* mainWindow, QObject* parent) : QTcpSocket(parent), mainWindow(mainWindow) { assert(mainWindow != NULL); QObject::connect(this, SIGNAL(readyRead()), this, SLOT(processReadyRead())); QObject::connect(this, SIGNAL(disconnected()), &this->pingTimer, SLOT(stop())); QObject::connect(&this->pingTimer, SIGNAL(timeout()), this, SLOT(sendPing())); QObject::connect(this, SIGNAL(connected()), this, SLOT(onConnected())); }
Connection::Connection(Identity identity, QObject *parent ) : QTcpSocket(parent) { m_currentDataType = Undefined; m_transferTimerId = 0; m_numBytesForCurrentDataType = -1; m_identity = identity; m_buffer.clear(); QObject::connect(this, SIGNAL(readyRead()), this, SLOT(processReadyRead())); QObject::connect(this, SIGNAL(connected()), this, SLOT(sendGreetingMessage())); }
DkConnection::DkConnection(QObject* parent) : QTcpSocket(parent) { mNumBytesForCurrentDataType = -1; mIsGreetingMessageSent = false; mIsSynchronizeMessageSent = false; connectionCreated = false; mSynchronizedTimer = new QTimer(this); connect(mSynchronizedTimer, SIGNAL(timeout()), this, SLOT(synchronizedTimerTimeout())); connect(this, SIGNAL(readyRead()), this, SLOT(processReadyRead())); setReadBufferSize(MaxBufferSize); }
Connection::Connection(QObject *parent) : QTcpSocket(parent) { m_connectedMessage = tr("Unknow"); m_userName = tr("Unknown Name"); // m_localHostName = localHostName(); // m_localHostAddress = peerAddress().toString(); // m_localHostPort = QString::number(peerPort()); QObject::connect(this, SIGNAL(readyRead()), this, SLOT(processReadyRead())); QObject::connect(this, SIGNAL(disconnected()), this, SLOT(stop())); connect(this, SIGNAL(connected()), this, SLOT(connected())); }
Connection::Connection(QObject *parent) : QTcpSocket(parent) { greetingMessage = tr("undefined"); username = tr("unknown"); state = Waiting; currentDataType = Undefined; numBytesForCurrentDataType = -1; transferTimerId = 0; isGreetingMessageSent = false; QObject::connect(this, SIGNAL(readyRead()), this, SLOT(processReadyRead())); QObject::connect(this, SIGNAL(connected()), this, SLOT(sendGreetingMessage())); QObject::connect(this, SIGNAL(connected()), this, SLOT(sendGreetingMessage())); }
// ChatConnection初始化和信号槽连接 ChatConnection::ChatConnection(QObject *parent) : QTcpSocket(parent) { this->greetingMessage = QObject::tr("undefined"); this->userName = QObject::tr("unknown"); this->state = WaitingForGreeting; this->currentDataType = UNDEFINED; this->numBytesForCurrentDataType = -1; this->transferTimerId = 0; this->isGreetingMessageSent = false; connect(this, SIGNAL(readyRead()), this, SLOT(processReadyRead())); connect(this, SIGNAL(connected()), this, SLOT(sendGreetingMessage())); connect(this, SIGNAL(disconnected()), this, SLOT(handleDisconnected())); connect(this, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(handleSocketError(QAbstractSocket::SocketError))); }
Connection::Connection(QObject *parent) : QTcpSocket(parent) { greetingMessage = tr("undefined"); username = tr("unknown"); state = WaitingForGreeting; currentDataType = Undefined; numBytesForCurrentDataType = -1; transferTimerId = 0; isGreetingMessageSent = false; pingTimer.setInterval(PingInterval); QObject::connect(this, SIGNAL(readyRead()), this, SLOT(processReadyRead())); QObject::connect(this, SIGNAL(disconnected()), &pingTimer, SLOT(stop())); QObject::connect(&pingTimer, SIGNAL(timeout()), this, SLOT(sendPing())); QObject::connect(this, SIGNAL(connected()), this, SLOT(sendGreetingMessage())); }
/*! * \reimp */ void QxtWebCgiService::pageRequestedEvent(QxtWebRequestEvent* event) { // Create the process object and initialize connections QProcess* process = new QProcess(this); qxt_d().requests[process] = QxtCgiRequestInfo(event); qxt_d().processes[event->content] = process; QxtCgiRequestInfo& requestInfo = qxt_d().requests[process]; QObject::connect(process, SIGNAL(readyRead()), &qxt_d(), SLOT(processReadyRead())); QObject::connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), &qxt_d(), SLOT(processFinished())); QObject::connect(process, SIGNAL(error(QProcess::ProcessError)), &qxt_d(), SLOT(processFinished())); requestInfo.timeout = new QTimer(process); qxt_d().timeoutMapper.setMapping(requestInfo.timeout, process); QObject::connect(requestInfo.timeout, SIGNAL(timeout()), &qxt_d().timeoutMapper, SLOT(map())); // Initialize the system environment QStringList s_env = process->systemEnvironment(); QMap<QString, QString> env; foreach(const QString& entry, s_env) { int pos = entry.indexOf('='); env[entry.left(pos)] = entry.mid(pos + 1); }
SslConnect::SslConnect(QObject *parent) : QObject(parent) { pSkt = new QSslSocket(this); connect(pSkt, SIGNAL(encrypted()), this, SLOT(ready())); connect(pSkt, SIGNAL(sslErrors(const QList<QSslError>&)),this,SLOT(processSslErrors(const QList<QSslError>&) )); connect(pSkt, SIGNAL(peerVerifyError(const QSslError&)), this, SLOT(processPeerVerifyError(const QSslError&))); connect(pSkt, SIGNAL(modeChanged(QSslSocket::SslMode)), this, SLOT(processModeChanged(QSslSocket::SslMode))); connect(pSkt, SIGNAL(readyRead()), this, SLOT(processReadyRead())); //char * strNoChecksum = "$PMWLSS,1398447044,1,Quintillus_LSS,,2*"; //char * strWithChecksum = "$PMWLSS,1398447044,1,Quintillus_LSS,,2*06"; //char * strNoChecksum = "$PMWTS2,28,1,1398444310,1398446921,2,0,2*"; //char * strWithChecksum = "$PMWTS2,28,1,1398444310,1398446921,2,0,2*52"; //char * strNoChecksum = "$PMWLSS,1398444859,4,Quintillus_LSS,eJ4bY7z3,1*"; //char * strWithChecksum = "$PMWLSS,1398444859,4,Quintillus_LSS,eJ4bY7z3,1*25"; //char * strNoChecksum = "$PMWLSS,1398452889,4,BNESystems_LSS,uQy73FTw,1*"; //char * strWithChecksum = ""; //char * strNoChecksum = "$PMWLSS,1398778321,4,Kordia_LSS,bU3Ezf85,1"; //char * strWithChecksum = "$PMWLSS,1398778321,4,Kordia_LSS,bU3Ezf85,1*5D"; //char * strNoChecksum = "$PMWLSS,1398782052,4,OtherCompany,TheirPassword,1*"; //char * strWithChecksum = ""; //char * strNoChecksum = "$PMWLSS,1398782048,2,OtherCompany,,2"; char * strNoChecksum = "$PMWLSS,1401779508153,4,CLS_LSS,Zf92pL7g,1"; //QByteArray res = computeCheksum(strNoChecksum); //qDebug() << res; }
Connection::~Connection () { qDebug("Connection::~Connection() this=0x%08x", this); m_main_window->dockManager().removeActionAble(*this); recurse(m_data, UnregisterDockedWidgets(*m_main_window)); if (m_tcpstream) { QObject::disconnect(m_tcpstream, SIGNAL(readyRead()), this, SLOT(processReadyRead())); QObject::disconnect(m_tcpstream, SIGNAL(disconnected()), this, SLOT(onDisconnected())); } if (m_tcpstream) m_tcpstream->close(); closeStorage(); qDebug("destroying docked widgets"); recurse(m_data, DestroyDockedWidgets(*m_main_window, *this)); if (m_file_tlv_stream) { QIODevice * const f = m_file_tlv_stream->device(); f->close(); delete m_file_tlv_stream; m_file_tlv_stream = 0; delete f; } if (m_file_csv_stream) { QIODevice * const f = m_file_csv_stream->device(); f->close(); delete m_file_csv_stream; m_file_csv_stream = 0; delete f; } }
int main(int argc, char *argv[]) { Q_INIT_RESOURCE(asebaqtabout); QApplication app(argc, argv); QCoreApplication::setOrganizationName(ASEBA_ORGANIZATION_NAME); QCoreApplication::setOrganizationDomain(ASEBA_ORGANIZATION_DOMAIN); app.setApplicationName("Playground"); QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8")); QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); // Translation support QTranslator qtTranslator; qtTranslator.load("qt_" + QLocale::system().name()); app.installTranslator(&qtTranslator); QTranslator translator; translator.load(QString(":/asebaplayground_") + QLocale::system().name()); app.installTranslator(&translator); QTranslator aboutTranslator; aboutTranslator.load(QString(":/qtabout_") + QLocale::system().name()); app.installTranslator(&aboutTranslator); // create document QDomDocument domDocument("aseba-playground"); QString sceneFileName; // Get cmd line arguments bool ask = true; if (argc > 1) { sceneFileName = argv[1]; ask = false; } // Try to load xml config file do { if (ask) { QString lastFileName = QSettings("EPFL-LSRO-Mobots", "Aseba Playground").value("last file").toString(); sceneFileName = QFileDialog::getOpenFileName(0, app.tr("Open Scenario"), lastFileName, app.tr("playground scenario (*.playground)")); } ask = true; if (sceneFileName.isEmpty()) { std::cerr << "You must specify a valid setup scenario on the command line or choose one in the file dialog." << std::endl; exit(1); } QFile file(sceneFileName); if (file.open(QIODevice::ReadOnly)) { QString errorStr; int errorLine, errorColumn; if (!domDocument.setContent(&file, false, &errorStr, &errorLine, &errorColumn)) { QMessageBox::information(0, "Aseba Playground", app.tr("Parse error at file %1, line %2, column %3:\n%4") .arg(sceneFileName) .arg(errorLine) .arg(errorColumn) .arg(errorStr)); } else { QSettings("EPFL-LSRO-Mobots", "Aseba Playground").setValue("last file", sceneFileName); break; } } } while (true); // Scan for colors typedef QMap<QString, Enki::Color> ColorsMap; ColorsMap colorsMap; QDomElement colorE = domDocument.documentElement().firstChildElement("color"); while (!colorE.isNull()) { colorsMap[colorE.attribute("name")] = Enki::Color( colorE.attribute("r").toDouble(), colorE.attribute("g").toDouble(), colorE.attribute("b").toDouble() ); colorE = colorE.nextSiblingElement ("color"); } // Scan for areas typedef QMap<QString, Enki::Polygon> AreasMap; AreasMap areasMap; QDomElement areaE = domDocument.documentElement().firstChildElement("area"); while (!areaE.isNull()) { Enki::Polygon p; QDomElement pointE = areaE.firstChildElement("point"); while (!pointE.isNull()) { p.push_back(Enki::Point( pointE.attribute("x").toDouble(), pointE.attribute("y").toDouble() )); pointE = pointE.nextSiblingElement ("point"); } areasMap[areaE.attribute("name")] = p; areaE = areaE.nextSiblingElement ("area"); } // Create the world QDomElement worldE = domDocument.documentElement().firstChildElement("world"); Enki::Color worldColor(Enki::Color::gray); if (!colorsMap.contains(worldE.attribute("color"))) std::cerr << "Warning, world walls color " << worldE.attribute("color").toStdString() << " undefined\n"; else worldColor = colorsMap[worldE.attribute("color")]; Enki::World::GroundTexture groundTexture; if (worldE.hasAttribute("groundTexture")) { const QString groundTextureFileName(QFileInfo(sceneFileName).absolutePath() + QDir::separator() + worldE.attribute("groundTexture")); QImage image(groundTextureFileName); if (!image.isNull()) { // flip vertically as y-coordinate is inverted in an image image = image.mirrored(); // convert to a specific format and copy the underlying data to Enki image = image.convertToFormat(QImage::Format_ARGB32); groundTexture.width = image.width(); groundTexture.height = image.height(); const uint32_t* imageData(reinterpret_cast<const uint32_t*>(image.constBits())); std::copy(imageData, imageData+image.width()*image.height(), std::back_inserter(groundTexture.data)); // Note: this works in little endian, in big endian data should be swapped } else { qDebug() << "Could not load ground texture file named" << groundTextureFileName; } } Enki::World world( worldE.attribute("w").toDouble(), worldE.attribute("h").toDouble(), worldColor, groundTexture ); // Create viewer Enki::PlaygroundViewer viewer(&world, worldE.attribute("energyScoringSystemEnabled", "false").toLower() == "true"); if (Enki::simulatorEnvironment) qDebug() << "A simulator environment already exists, replacing"; Enki::simulatorEnvironment.reset(new Enki::PlaygroundSimulatorEnvironment(sceneFileName, viewer)); // Zeroconf support to advertise targets #ifdef ZEROCONF_SUPPORT Aseba::QtZeroconf zeroconf; #endif // ZEROCONF_SUPPORT // Scan for camera QDomElement cameraE = domDocument.documentElement().firstChildElement("camera"); if (!cameraE.isNull()) { const double largestDim(qMax(world.h, world.w)); viewer.setCamera( QPointF( cameraE.attribute("x", QString::number(world.w / 2)).toDouble(), cameraE.attribute("y", QString::number(0)).toDouble() ), cameraE.attribute("altitude", QString::number(0.85 * largestDim)).toDouble(), cameraE.attribute("yaw", QString::number(-M_PI/2)).toDouble(), cameraE.attribute("pitch", QString::number((3*M_PI)/8)).toDouble() ); } // Scan for walls QDomElement wallE = domDocument.documentElement().firstChildElement("wall"); while (!wallE.isNull()) { Enki::PhysicalObject* wall = new Enki::PhysicalObject(); if (!colorsMap.contains(wallE.attribute("color"))) std::cerr << "Warning, color " << wallE.attribute("color").toStdString() << " undefined\n"; else wall->setColor(colorsMap[wallE.attribute("color")]); wall->pos.x = wallE.attribute("x").toDouble(); wall->pos.y = wallE.attribute("y").toDouble(); wall->setRectangular( wallE.attribute("l1").toDouble(), wallE.attribute("l2").toDouble(), wallE.attribute("h").toDouble(), !wallE.attribute("mass").isNull() ? wallE.attribute("mass").toDouble() : -1 // normally -1 because immobile ); if (! wallE.attribute("angle").isNull()) wall->angle = wallE.attribute("angle").toDouble(); // radians world.addObject(wall); wallE = wallE.nextSiblingElement ("wall"); } // Scan for cylinders QDomElement cylinderE = domDocument.documentElement().firstChildElement("cylinder"); while (!cylinderE.isNull()) { Enki::PhysicalObject* cylinder = new Enki::PhysicalObject(); if (!colorsMap.contains(cylinderE.attribute("color"))) std::cerr << "Warning, color " << cylinderE.attribute("color").toStdString() << " undefined\n"; else cylinder->setColor(colorsMap[cylinderE.attribute("color")]); cylinder->pos.x = cylinderE.attribute("x").toDouble(); cylinder->pos.y = cylinderE.attribute("y").toDouble(); cylinder->setCylindric( cylinderE.attribute("r").toDouble(), cylinderE.attribute("h").toDouble(), !cylinderE.attribute("mass").isNull() ? cylinderE.attribute("mass").toDouble() : -1 // normally -1 because immobile ); world.addObject(cylinder); cylinderE = cylinderE.nextSiblingElement("cylinder"); } // Scan for feeders QDomElement feederE = domDocument.documentElement().firstChildElement("feeder"); while (!feederE.isNull()) { Enki::EPuckFeeder* feeder = new Enki::EPuckFeeder; feeder->pos.x = feederE.attribute("x").toDouble(); feeder->pos.y = feederE.attribute("y").toDouble(); world.addObject(feeder); feederE = feederE.nextSiblingElement ("feeder"); } // TODO: if needed, custom color to feeder // Scan for doors typedef QMap<QString, Enki::SlidingDoor*> DoorsMap; DoorsMap doorsMap; QDomElement doorE = domDocument.documentElement().firstChildElement("door"); while (!doorE.isNull()) { Enki::SlidingDoor *door = new Enki::SlidingDoor( Enki::Point( doorE.attribute("closedX").toDouble(), doorE.attribute("closedY").toDouble() ), Enki::Point( doorE.attribute("openedX").toDouble(), doorE.attribute("openedY").toDouble() ), Enki::Point( doorE.attribute("l1").toDouble(), doorE.attribute("l2").toDouble() ), doorE.attribute("h").toDouble(), doorE.attribute("moveDuration").toDouble() ); if (!colorsMap.contains(doorE.attribute("color"))) std::cerr << "Warning, door color " << doorE.attribute("color").toStdString() << " undefined\n"; else door->setColor(colorsMap[doorE.attribute("color")]); doorsMap[doorE.attribute("name")] = door; world.addObject(door); doorE = doorE.nextSiblingElement ("door"); } // Scan for activation, and link them with areas and doors QDomElement activationE = domDocument.documentElement().firstChildElement("activation"); while (!activationE.isNull()) { if (areasMap.find(activationE.attribute("area")) == areasMap.end()) { std::cerr << "Warning, area " << activationE.attribute("area").toStdString() << " undefined\n"; activationE = activationE.nextSiblingElement ("activation"); continue; } if (doorsMap.find(activationE.attribute("door")) == doorsMap.end()) { std::cerr << "Warning, door " << activationE.attribute("door").toStdString() << " undefined\n"; activationE = activationE.nextSiblingElement ("activation"); continue; } const Enki::Polygon& area = *areasMap.find(activationE.attribute("area")); Enki::Door* door = *doorsMap.find(activationE.attribute("door")); Enki::DoorButton* activation = new Enki::DoorButton( Enki::Point( activationE.attribute("x").toDouble(), activationE.attribute("y").toDouble() ), Enki::Point( activationE.attribute("l1").toDouble(), activationE.attribute("l2").toDouble() ), area, door ); world.addObject(activation); activationE = activationE.nextSiblingElement ("activation"); } // load all robots in one loop std::map<std::string, RobotType> robotTypes { { "thymio2", { "Thymio II", createRobotSingleVMNode<Enki::DashelAsebaThymio2> } }, { "e-puck", { "E-Puck", createRobotSingleVMNode<Enki::DashelAsebaFeedableEPuck> } }, }; QDomElement robotE = domDocument.documentElement().firstChildElement("robot"); unsigned asebaServerCount(0); while (!robotE.isNull()) { const auto type(robotE.attribute("type", "thymio2")); auto typeIt(robotTypes.find(type.toStdString())); if (typeIt != robotTypes.end()) { // retrieve informations const auto& cppTypeName(typeIt->second.prettyName); const auto qTypeName(QString::fromStdString(cppTypeName)); auto& countOfThisType(typeIt->second.number); const auto qRobotNameRaw(robotE.attribute("name", QString("%1 %2").arg(qTypeName).arg(countOfThisType))); const auto qRobotNameFull(QObject::tr("%2 on %3").arg(qRobotNameRaw).arg(QHostInfo::localHostName())); const auto cppRobotName(qRobotNameFull.toStdString()); const unsigned port(robotE.attribute("port", QString("%1").arg(ASEBA_DEFAULT_PORT+asebaServerCount)).toUInt()); const int16_t nodeId(robotE.attribute("nodeId", "1").toInt()); // create const auto& creator(typeIt->second.factory); #ifdef ZEROCONF_SUPPORT auto robot(creator(zeroconf, port, cppRobotName, cppTypeName, nodeId)); #else // ZEROCONF_SUPPORT auto robot(creator(port, cppRobotName, cppTypeName, nodeId)); #endif // ZEROCONF_SUPPORT asebaServerCount++; countOfThisType++; // setup in the world robot->pos.x = robotE.attribute("x").toDouble(); robot->pos.y = robotE.attribute("y").toDouble(); robot->angle = robotE.attribute("angle").toDouble(); world.addObject(robot); // log viewer.log(app.tr("New robot %0 of type %1 on port %2").arg(qRobotNameRaw).arg(qTypeName).arg(port), Qt::white); } else viewer.log("Error, unknown robot type " + type, Qt::red); robotE = robotE.nextSiblingElement ("robot"); } // Scan for external processes QList<QProcess*> processes; QDomElement procssE(domDocument.documentElement().firstChildElement("process")); while (!procssE.isNull()) { QString command(procssE.attribute("command")); // create process processes.push_back(new QProcess()); processes.back()->setProcessChannelMode(QProcess::MergedChannels); // make sure it is killed when we close the window QObject::connect(processes.back(), SIGNAL(started()), &viewer, SLOT(processStarted())); QObject::connect(processes.back(), SIGNAL(error(QProcess::ProcessError)), &viewer, SLOT(processError(QProcess::ProcessError))); QObject::connect(processes.back(), SIGNAL(readyReadStandardOutput()), &viewer, SLOT(processReadyRead())); QObject::connect(processes.back(), SIGNAL(finished(int, QProcess::ExitStatus)), &viewer, SLOT(processFinished(int, QProcess::ExitStatus))); // check whether it is a relative command bool isRelative(false); if (!command.isEmpty() && command[0] == ':') { isRelative = true; command = command.mid(1); } // process the command into its components QStringList args(command.split(" ", QString::SkipEmptyParts)); if (args.size() == 0) { viewer.log(app.tr("Missing program in command"), Qt::red); } else { const QString program(QDir::toNativeSeparators(args[0])); args.pop_front(); if (isRelative) processes.back()->start(QCoreApplication::applicationDirPath() + QDir::separator() + program, args, QIODevice::ReadOnly); else processes.back()->start(program, args, QIODevice::ReadOnly); } procssE = procssE.nextSiblingElement("process"); } // Show and run viewer.setWindowTitle(app.tr("Aseba Playground - Simulate your robots!")); viewer.show(); // If D-Bus is used, register the viewer object #ifdef HAVE_DBUS new Enki::EnkiWorldInterface(&viewer); QDBusConnection::sessionBus().registerObject("/world", &viewer); QDBusConnection::sessionBus().registerService("ch.epfl.mobots.AsebaPlayground"); #endif // HAVE_DBUS // Run the application const int exitValue(app.exec()); // Stop and delete ongoing processes foreach(QProcess*process,processes) { process->terminate(); if (!process->waitForFinished(1000)) process->kill(); delete process; }
Connection::Connection(QObject *parent) : QTcpSocket(parent) { QObject::connect(this, SIGNAL(readyRead()), this, SLOT(processReadyRead())); }
cUpdater::cUpdater(QObject *parent) : QObject(parent) { connect(&m_Socket, SIGNAL(disconnected()), this, SLOT(processDisconnected())); connect(&m_Socket, SIGNAL(readyRead()), this, SLOT(processReadyRead())); connect(&m_Socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(processError(QAbstractSocket::SocketError))); }
bool FGSimulator::setupProcess() { QMutexLocker locker(&lock); // Copy FlightGear generic protocol configuration file to the FG protocol directory // NOTE: Not working on Windows 7, if FG is installed in the "Program Files", // likelly due to permissions. The file should be manually copied to data/Protocol/opfgprotocol.xml // QFile xmlFile(":/flightgear/genericprotocol/opfgprotocol.xml"); // xmlFile.open(QIODevice::ReadOnly | QIODevice::Text); // QString xml = xmlFile.readAll(); // xmlFile.close(); // QFile xmlFileOut(pathData + "/Protocol/opfgprotocol.xml"); // xmlFileOut.open(QIODevice::WriteOnly | QIODevice::Text); // xmlFileOut.write(xml.toAscii()); // xmlFileOut.close(); Qt::HANDLE mainThread = QThread::currentThreadId(); qDebug() << "setupProcess Thread: " << mainThread; simProcess = new QProcess(); simProcess->setReadChannelMode(QProcess::MergedChannels); connect(simProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(processReadyRead())); // Note: Only tested on windows 7 #if defined(Q_WS_WIN) QString cmdShell("c:/windows/system32/cmd.exe"); #else QString cmdShell("bash"); #endif // Start shell (Note: Could not start FG directly on Windows, only through terminal!) simProcess->start(cmdShell); if (simProcess->waitForStarted() == false) { emit processOutput("Error:" + simProcess->errorString()); return false; } // Setup arguments // Note: The input generic protocol is set to update at a much higher rate than the actual updates are sent by the GCS. // If this is not done then a lag will be introduced by FlightGear, likelly because the receive socket buffer builds up during startup. QString args("--fg-root=\"" + settings.dataPath + "\" " + "--timeofday=noon " + "--httpd=5400 " + "--enable-hud " + "--in-air " + "--altitude=3000 " + "--vc=100 " + "--log-level=alert " + "--generic=socket,out,20," + settings.hostAddress + "," + QString::number(settings.inPort) + ",udp,opfgprotocol"); if (settings.manualControlEnabled) { // <--[BCH] What does this do? Why does it depend on ManualControl? args.append(" --generic=socket,in,400," + settings.remoteAddress + "," + QString::number(settings.outPort) + ",udp,opfgprotocol"); } // Start FlightGear - only if checkbox is selected in HITL options page if (settings.startSim) { QString cmd("\"" + settings.binPath + "\" " + args + "\n"); simProcess->write(cmd.toAscii()); } else { emit processOutput("Start Flightgear from the command line with the following arguments: \n\n" + args + "\n\n" + "You can optionally run Flightgear from a networked computer.\n" + "Make sure the computer running Flightgear can can ping your local interface adapter. ie." + settings.hostAddress + "\n" "Remote computer must have the correct OpenPilot protocol installed."); } udpCounterGCSsend = 0; return true; }
FGSimulator::~FGSimulator() { disconnect(simProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(processReadyRead())); }