openpilot is an open source driver assistance system. openpilot performs the functions of Automated Lane Centering and Adaptive Cruise Control for over 200 supported car makes and models.
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.

140 lines
3.8 KiB

#include "tools/clip/application.h"
#include <QApplication>
#include <QTranslator>
#include <selfdrive/ui/qt/util.h>
#include <selfdrive/ui/qt/window.h>
#include "recorder/widget.h"
2 months ago
Application::Application(int argc, char *argv[], QObject *parent) : QObject(parent) {
argc_ = argc;
argv_ = argv;
initApp(argc_, argv_);
app = new QApplication(argc_, argv_);
2 months ago
QCommandLineParser parser;
parser.setApplicationDescription("Clip your ride!");
parser.addHelpOption();
const QCommandLineOption start({"s", "start"}, "start time", "start");
parser.addOption(start);
const QCommandLineOption output({"o", "output"}, "output file", "output");
parser.addOption(output);
parser.addPositionalArgument("route", "route string");
parser.process(*app);
int startTime = 0;
if (parser.isSet(start)) {
bool ok;
int parsed = parser.value(start).toInt(&ok);
if (!ok) {
qDebug() << "start time must be an integer\n";
fprintf(stderr, "%s", parser.helpText().toStdString().c_str());
exit(1);
}
startTime = parsed;
}
if (!parser.isSet(output)) {
qDebug() << "output is required\n";
fprintf(stderr, "%s", parser.helpText().toStdString().c_str());
exit(1);
}
QString outputFile = parser.value(output);
QString route;
QStringList positionalArgs = parser.positionalArguments();
if (!positionalArgs.isEmpty()) {
route = positionalArgs.at(0);
} else {
qDebug() << "No file specified\n";
fprintf(stderr, "%s", parser.helpText().toStdString().c_str());
exit(1);
}
QTranslator translator;
QString translation_file = QString::fromStdString(Params().get("LanguageSetting"));
if (!translator.load(QString(":/%1").arg(translation_file)) && translation_file.length()) {
qCritical() << "Failed to load translation file:" << translation_file;
}
app->installTranslator(&translator);
window = new OnroadWindow();
recorderThread = new QThread;
2 months ago
recorder = new Recorder(outputFile.toStdString());
recorder->moveToThread(recorderThread);
QObject::connect(recorderThread, &QThread::finished, recorder, &QObject::deleteLater);
2 months ago
QObject::connect(window, &OnroadWindow::redrew, this, [&]() {
recorder->saveFrame(std::make_shared<QPixmap>(std::move(window->grab())));
}, Qt::DirectConnection);
2 months ago
QObject::connect(app, &QCoreApplication::aboutToQuit, recorderThread, &QThread::quit);
window->setAttribute(Qt::WA_DontShowOnScreen);
window->setAttribute(Qt::WA_Mapped);
window->setAttribute(Qt::WA_NoSystemBackground);
2 months ago
recorderThread->start();
// Initialize and start replay
2 months ago
initReplay(route.toStdString());
replayThread = QThread::create([this, startTime] { startReplay(startTime); });
2 months ago
replayThread->start();
}
2 months ago
void Application::initReplay(const std::string& route) {
2 months ago
std::vector<std::string> allow;
std::vector<std::string> block;
2 months ago
replay = std::make_unique<Replay>(route, allow, block, nullptr, REPLAY_FLAG_NONE);
replay->setSegmentCacheLimit(1);
2 months ago
}
2 months ago
void Application::startReplay(int start) {
2 months ago
if (!replay || !replay->load()) {
qWarning() << "Failed to load replay";
2 months ago
QApplication::instance()->quit();
2 months ago
}
qInfo() << "Replay started.";
replayRunning = true;
2 months ago
replay->setEndSeconds(start + 60);
replay->start(start + 2);
2 months ago
replay->waitUntilEnd();
qInfo() << "Replay ended.";
replayRunning = false;
QMetaObject::invokeMethod(app, "quit", Qt::QueuedConnection);
}
Application::~Application() {
2 months ago
if (replayThread) {
replayThread->quit();
replayThread->wait();
delete replayThread;
}
if (recorderThread) {
recorderThread->quit();
recorderThread->wait();
}
delete window;
delete app;
}
int Application::exec() const {
2 months ago
// TODO: modify Replay to block until all OnroadWindow required messages have been broadcast at least once
std::this_thread::sleep_for(std::chrono::seconds(5));
setMainWindow(window);
2 months ago
return app->exec();
}