Skip to content

Commit d8858f5

Browse files
- windows build restored
- some tweaks to build system
1 parent 8f50776 commit d8858f5

File tree

12 files changed

+344
-52
lines changed

12 files changed

+344
-52
lines changed

global.pri

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@
1515
# Build settings common to all projects in TrikRuntime.
1616
# Provides:
1717
# CONFIGURATION_SUFFIX variable that shall be consistently used in TARGET and LIBS variables in all projects.
18-
#
19-
# Depends on:
20-
# FILES_TO_COPY variable for a list of additional files and directories which needed to be copied after build to
21-
# target directory.
2218

2319
CROSS_COMPILE = $$(CROSS_COMPILE)
2420

@@ -59,10 +55,24 @@ unix {
5955
INSTALLS += target
6056
}
6157

62-
!isEmpty(FILES_TO_COPY) {
63-
win32 {
64-
QMAKE_POST_LINK = "xcopy $$replace(FILES_TO_COPY, /, \\) $$replace(DESTDIR, /, \\) /s /e /q /y /i"
65-
} else {
66-
QMAKE_POST_LINK = "cp -rf $$FILES_TO_COPY $$DESTDIR"
58+
# Useful function to copy additional files to destination,
59+
# from http://stackoverflow.com/questions/3984104/qmake-how-to-copy-a-file-to-the-output
60+
defineTest(copyToDestdir) {
61+
FILES = $$1
62+
63+
for (FILE, FILES) {
64+
# This ugly code is needed because xcopy requires to add source directory name to target directory name when copying directories
65+
win32:AFTER_SLASH = $$section(FILE, "/", -1, -1)
66+
win32:BASE_NAME = $$section(FILE, "/", -2, -2)
67+
win32:equals(AFTER_SLASH, ""):DESTDIR_SUFFIX = /$$BASE_NAME
68+
69+
win32:FILE ~= s,/$,,g
70+
71+
FILE = $$shell_path($$FILE)
72+
DDIR = $$shell_path($$DESTDIR$$DESTDIR_SUFFIX/)
73+
74+
QMAKE_POST_LINK += $(COPY_DIR) $$quote($$FILE) $$quote($$DDIR) $$escape_expand(\\n\\t)
6775
}
76+
77+
export(QMAKE_POST_LINK)
6878
}
File renamed without changes.
File renamed without changes.
Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
/* Copyright 2014 CyberTech Labs Ltd.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License. */
14+
15+
#include "src/cameraLineDetectorSensorWorker.h"
16+
17+
#include <QtCore/QDebug>
18+
#include <QtCore/QFileInfo>
19+
#include <QtCore/QWaitCondition>
20+
#include <QtCore/QMutex>
21+
22+
using namespace trikControl;
23+
24+
CameraLineDetectorSensorWorker::CameraLineDetectorSensorWorker(QString const &roverCvBinary
25+
, QString const &inputFile
26+
, QString const &outputFile
27+
, double toleranceFactor
28+
, QString const &params
29+
)
30+
: mReading(0)
31+
, mRoverCvBinary(roverCvBinary)
32+
, mOutputFileDescriptor(-1)
33+
, mRoverCvProcess(this)
34+
, mInputFile(inputFile)
35+
, mOutputFile(outputFile)
36+
, mReady(false)
37+
, mToleranceFactor(toleranceFactor)
38+
, mParams(params)
39+
{
40+
qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
41+
42+
connect(&mRoverCvProcess, SIGNAL(error(QProcess::ProcessError))
43+
, this, SLOT(onRoverCvError(QProcess::ProcessError)), Qt::QueuedConnection);
44+
45+
connect(&mRoverCvProcess, SIGNAL(readyReadStandardError())
46+
, this, SLOT(onRoverCvReadyReadStandardError()), Qt::QueuedConnection);
47+
48+
connect(&mRoverCvProcess, SIGNAL(readyReadStandardOutput())
49+
, this, SLOT(onRoverCvReadyReadStandardOutput()), Qt::QueuedConnection);
50+
}
51+
52+
CameraLineDetectorSensorWorker::~CameraLineDetectorSensorWorker()
53+
{
54+
deinitialize();
55+
}
56+
57+
void CameraLineDetectorSensorWorker::init()
58+
{
59+
// Since rover-cv can die silently, we need to check not only mReady flag, but also input and output fifos.
60+
if (!mReady || !mInputFile.exists() || !mOutputFile.exists()) {
61+
initDetector();
62+
}
63+
}
64+
65+
void CameraLineDetectorSensorWorker::detect()
66+
{
67+
if (!mReady || !mInputFile.exists() || !mOutputFile.exists()) {
68+
init();
69+
}
70+
71+
mCommandQueue << "detect";
72+
tryToExecute();
73+
}
74+
75+
int CameraLineDetectorSensorWorker::read()
76+
{
77+
return mReading;
78+
}
79+
80+
void CameraLineDetectorSensorWorker::initDetector()
81+
{
82+
if (!mInputFile.exists() || !mOutputFile.exists()) {
83+
startRoverCv();
84+
} else {
85+
openFifos();
86+
}
87+
}
88+
89+
void CameraLineDetectorSensorWorker::onRoverCvError(QProcess::ProcessError error)
90+
{
91+
qDebug() << "rover-cv error: " << error;
92+
93+
mReady = false;
94+
deinitialize();
95+
}
96+
97+
void CameraLineDetectorSensorWorker::onRoverCvReadyReadStandardOutput()
98+
{
99+
QString const data = mRoverCvProcess.readAllStandardOutput();
100+
QStringList const lines = data.split("\n");
101+
foreach (QString const line, lines) {
102+
qDebug() << "From rover-cv:" << line;
103+
if (line == "Entering video thread loop") {
104+
openFifos();
105+
}
106+
107+
if (line == "Terminating") {
108+
mReady = false;
109+
deinitialize();
110+
}
111+
}
112+
}
113+
114+
void CameraLineDetectorSensorWorker::onRoverCvReadyReadStandardError()
115+
{
116+
QString const data = mRoverCvProcess.readAllStandardError();
117+
QStringList const lines = data.split("\n");
118+
foreach (QString const line, lines) {
119+
qDebug() << "From rover-cv standard error:" << line;
120+
}
121+
}
122+
123+
void CameraLineDetectorSensorWorker::readFile()
124+
{
125+
char data[4000] = {0};
126+
int size = 0;
127+
128+
mSocketNotifier->setEnabled(false);
129+
130+
if ((size = mOutputFile.read(data, 4000)) < 0) {
131+
qDebug() << mOutputFile.fileName() << ": fifo read failed: " << errno;
132+
return;
133+
}
134+
135+
QString const linesRead(data);
136+
QStringList const lines = linesRead.split('\n', QString::SkipEmptyParts);
137+
138+
foreach (QString const line, lines) {
139+
QStringList const parsedLine = line.split(" ", QString::SkipEmptyParts);
140+
141+
qDebug() << "parsed: " << parsedLine;
142+
143+
if (parsedLine[0] == "loc:") {
144+
int const x = parsedLine[1].toInt();
145+
int const angle = parsedLine[2].toInt();
146+
int const mass = parsedLine[3].toInt();
147+
148+
mReading = x;
149+
150+
// These values are not needed in current implementation, but are left here for reference.
151+
Q_UNUSED(angle)
152+
Q_UNUSED(mass)
153+
}
154+
155+
if (parsedLine[0] == "hsv:") {
156+
int const hue = parsedLine[1].toInt();
157+
int const hueTolerance = parsedLine[2].toInt();
158+
int const saturation = parsedLine[3].toInt();
159+
int const saturationTolerance = parsedLine[4].toInt();
160+
int const value = parsedLine[5].toInt();
161+
int const valueTolerance = parsedLine[6].toInt();
162+
163+
mInputStream
164+
<< QString("hsv %0 %1 %2 %3 %4 %5 %6")
165+
.arg(hue)
166+
.arg(hueTolerance * mToleranceFactor)
167+
.arg(saturation)
168+
.arg(saturationTolerance * mToleranceFactor)
169+
.arg(value)
170+
.arg(valueTolerance * mToleranceFactor)
171+
<< "\n";
172+
173+
mInputStream.flush();
174+
}
175+
}
176+
177+
mSocketNotifier->setEnabled(true);
178+
}
179+
180+
void CameraLineDetectorSensorWorker::startRoverCv()
181+
{
182+
QFileInfo roverCvBinaryFileInfo(mRoverCvBinary);
183+
184+
qDebug() << "Starting rover-cv";
185+
186+
if (mRoverCvProcess.state() == QProcess::Running) {
187+
mRoverCvProcess.close();
188+
}
189+
190+
QStringList const params = mParams.split(" ", QString::SkipEmptyParts);
191+
192+
mRoverCvProcess.setWorkingDirectory(roverCvBinaryFileInfo.absolutePath());
193+
mRoverCvProcess.start(roverCvBinaryFileInfo.filePath(), params, QIODevice::ReadOnly | QIODevice::Unbuffered);
194+
195+
mRoverCvProcess.waitForStarted();
196+
197+
if (mRoverCvProcess.state() != QProcess::Running)
198+
{
199+
qDebug() << "Cannot launch detector application " << roverCvBinaryFileInfo.filePath() << " in "
200+
<< roverCvBinaryFileInfo.absolutePath();
201+
return;
202+
}
203+
204+
qDebug() << "rover-cv started, waiting for it to initialize...";
205+
206+
/// @todo Remove this hack! QProcess does not deliver messages from rover-cv during startup.
207+
QMutex mutex;
208+
QWaitCondition wait;
209+
wait.wait(&mutex, 1000);
210+
211+
openFifos();
212+
}
213+
214+
void CameraLineDetectorSensorWorker::openFifos()
215+
{
216+
qDebug() << "opening" << mOutputFile.fileName();
217+
218+
if (mInputFile.isOpen()) {
219+
mInputFile.close();
220+
}
221+
222+
mOutputFile.open(QIODevice::ReadOnly);
223+
mOutputFileDescriptor = mOutputFile.handle();
224+
225+
if (mOutputFileDescriptor == -1) {
226+
qDebug() << "Cannot open sensor output file " << mOutputFile.fileName();
227+
return;
228+
}
229+
230+
mSocketNotifier.reset(new QSocketNotifier(mOutputFileDescriptor, QSocketNotifier::Read));
231+
232+
connect(mSocketNotifier.data(), SIGNAL(activated(int)), this, SLOT(readFile()));
233+
mSocketNotifier->setEnabled(true);
234+
235+
qDebug() << "opening" << mInputFile.fileName();
236+
237+
if (!mInputFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
238+
qDebug() << "Sensor input file" << mInputFile.fileName() << " failed to open";
239+
return;
240+
}
241+
242+
mInputStream.setDevice(&mInputFile);
243+
244+
mReady = true;
245+
246+
qDebug() << "initialization completed";
247+
248+
tryToExecute();
249+
}
250+
251+
void CameraLineDetectorSensorWorker::tryToExecute()
252+
{
253+
if (mReady) {
254+
foreach (QString const &command, mCommandQueue) {
255+
mInputStream << command + "\n";
256+
mInputStream.flush();
257+
}
258+
259+
mCommandQueue.clear();
260+
}
261+
}
262+
263+
void CameraLineDetectorSensorWorker::deinitialize()
264+
{
265+
if (mSocketNotifier) {
266+
disconnect(mSocketNotifier.data(), SIGNAL(activated(int)), this, SLOT(readFile()));
267+
mSocketNotifier->setEnabled(false);
268+
}
269+
270+
mOutputFile.close();
271+
272+
mOutputFileDescriptor = -1;
273+
mInputFile.close();
274+
}
Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright 2013 Matvey Bryksin, Yurii Litvinov
1+
/* Copyright 2014 CyberTech Labs Ltd.
22
*
33
* Licensed under the Apache License, Version 2.0 (the "License");
44
* you may not use this file except in compliance with the License.
@@ -12,15 +12,28 @@
1212
* See the License for the specific language governing permissions and
1313
* limitations under the License. */
1414

15-
#include "keys.h"
15+
#include "src/keysWorker.h"
16+
17+
#include <QtCore/QDebug>
1618

1719
using namespace trikControl;
1820

19-
Keys::Keys(const QString &keysPath)
21+
KeysWorker::KeysWorker(QString const &keysPath)
22+
{
23+
Q_UNUSED(keysPath)
24+
}
25+
26+
void KeysWorker::reset()
2027
{
21-
Q_UNUSED(keysPath);
2228
}
2329

24-
void Keys::readKeysEvent()
30+
bool KeysWorker::wasPressed(int code)
31+
{
32+
Q_UNUSED(code)
33+
34+
return false;
35+
}
36+
37+
void KeysWorker::readKeysEvent()
2538
{
2639
}

0 commit comments

Comments
 (0)