Skip to content

Commit d5486f2

Browse files
Fixed bug with incorrect detection, some cleanup
1 parent 8abf165 commit d5486f2

File tree

8 files changed

+103
-37
lines changed

8 files changed

+103
-37
lines changed

trikControl/config.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,6 @@ Use it if JCx ports are configured to work as PWM signal generators.
191191
<i2c path="/dev/i2c-2" deviceId="0x48" />
192192

193193
<!-- Settings for virtual camera line sensor provided by rover-cv application. -->
194-
<cameraLineDetector roverCv="/home/root/video-module/rover-cv" inputFile="/tmp/dsp-detector.in.fifo" outputFile="/tmp/dsp-detector.out.fifo" />
194+
<cameraLineDetector roverCv="/home/root/video-module/rover-cv" inputFile="/tmp/dsp-detector.in.fifo" outputFile="/tmp/dsp-detector.out.fifo" toleranceFactor="5" />
195195

196196
</config>

trikControl/include/trikControl/cameraLineDetectorSensor.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,15 @@ class TRIKCONTROL_EXPORT CameraLineDetectorSensor : public Sensor
3333
Q_OBJECT
3434

3535
public:
36-
CameraLineDetectorSensor(QString const &roverCvBinary, QString const &inputFile, QString const &outputFile);
36+
/// Constructor.
37+
/// @param roverCvBinary - binary file of rover-cv program which is used to work with video
38+
/// @param inputFile - rover-cv input fifo. Note that we will write data here, not read it.
39+
/// @param outputFile - rover-cv output fifo. Note that we will read sensor data from here.
40+
/// @param toleranceFactor - a value on which hueTolerance, saturationTolerance and valueTolerance is multiplied
41+
/// after "detect" command. Higher values allow to count more points on an image as tracked object.
42+
CameraLineDetectorSensor(QString const &roverCvBinary, QString const &inputFile
43+
, QString const &outputFile, double toleranceFactor);
44+
3745
~CameraLineDetectorSensor();
3846

3947
public slots:
@@ -47,7 +55,10 @@ public slots:
4755
int read();
4856

4957
private:
58+
/// Worker object that handles sensor in separate thread.
5059
QScopedPointer<CameraLineDetectorSensorWorker> mCameraLineDetectorSensorWorker;
60+
61+
/// Worker thread.
5162
QThread mWorkerThread;
5263
};
5364

trikControl/src/brick.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ Brick::Brick(QThread &guiThread, QString const &configFilePath)
127127
mCameraLineDetectorSensor = new CameraLineDetectorSensor(mConfigurer->roverCvBinary()
128128
, mConfigurer->roverCvInputFile()
129129
, mConfigurer->roverCvOutputFile()
130+
, mConfigurer->roverCvToleranceFactor()
130131
);
131132
}
132133

trikControl/src/cameraLineDetectorSensorWorker.cpp

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,18 @@
2525

2626
using namespace trikControl;
2727

28-
CameraLineDetectorSensorWorker::CameraLineDetectorSensorWorker(
29-
QString const &roverCvBinary
28+
CameraLineDetectorSensorWorker::CameraLineDetectorSensorWorker(QString const &roverCvBinary
3029
, QString const &inputFile
31-
, QString const &outputFile)
30+
, QString const &outputFile
31+
, double toleranceFactor)
3232
: mReading(0)
3333
, mRoverCvBinary(roverCvBinary)
34-
, mOutputFileDescriptor(0)
34+
, mOutputFileDescriptor(-1)
35+
, mRoverCvProcess(this)
3536
, mInputFile(inputFile)
3637
, mOutputFile(outputFile)
3738
, mReady(false)
39+
, mToleranceFactor(toleranceFactor)
3840
{
3941
qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
4042

@@ -53,13 +55,9 @@ CameraLineDetectorSensorWorker::~CameraLineDetectorSensorWorker()
5355
deinitialize();
5456
}
5557

56-
void CameraLineDetectorSensorWorker::moveChildrenToCorrectThread()
57-
{
58-
mRoverCvProcess.moveToThread(this->thread());
59-
}
60-
6158
void CameraLineDetectorSensorWorker::init()
6259
{
60+
// Since rover-cv can die silently, we need to check not only mReady flag, but also input and output fifos.
6361
if (!mReady || !mInputFile.exists() || !mOutputFile.exists()) {
6462
initDetector();
6563
}
@@ -162,15 +160,16 @@ void CameraLineDetectorSensorWorker::readFile()
162160
int const value = parsedLine[5].toInt();
163161
int const valueTolerance = parsedLine[6].toInt();
164162

165-
// These values are not needed in current implementation, but are left here for reference too.
166-
Q_UNUSED(hue)
167-
Q_UNUSED(hueTolerance)
168-
Q_UNUSED(saturation)
169-
Q_UNUSED(saturationTolerance)
170-
Q_UNUSED(value)
171-
Q_UNUSED(valueTolerance)
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";
172172

173-
mInputStream << QString(line).remove(":") << "\n";
174173
mInputStream.flush();
175174
}
176175
}
@@ -214,7 +213,7 @@ void CameraLineDetectorSensorWorker::openFifos()
214213
{
215214
qDebug() << "opening" << mOutputFile.fileName();
216215

217-
if (!mOutputFileDescriptor) {
216+
if (mOutputFileDescriptor == -1) {
218217
mOutputFileDescriptor = open(mOutputFile.fileName().toStdString().c_str(), O_SYNC | O_NONBLOCK, O_RDONLY);
219218
}
220219

@@ -223,12 +222,10 @@ void CameraLineDetectorSensorWorker::openFifos()
223222
return;
224223
}
225224

226-
qDebug() << mOutputFileDescriptor;
227-
228225
mSocketNotifier.reset(new QSocketNotifier(mOutputFileDescriptor, QSocketNotifier::Read));
229226

230227
connect(mSocketNotifier.data(), SIGNAL(activated(int)), this, SLOT(readFile()));
231-
mSocketNotifier->setEnabled(false);
228+
mSocketNotifier->setEnabled(true);
232229

233230
qDebug() << "opening" << mInputFile.fileName();
234231

@@ -260,8 +257,10 @@ void CameraLineDetectorSensorWorker::tryToExecute()
260257

261258
void CameraLineDetectorSensorWorker::deinitialize()
262259
{
263-
disconnect(mSocketNotifier.data(), SIGNAL(activated(int)), this, SLOT(readFile()));
264-
mSocketNotifier->setEnabled(false);
260+
if (mSocketNotifier) {
261+
disconnect(mSocketNotifier.data(), SIGNAL(activated(int)), this, SLOT(readFile()));
262+
mSocketNotifier->setEnabled(false);
263+
}
265264
if (::close(mOutputFileDescriptor) != 0) {
266265
qDebug() << mOutputFile.fileName() << ": fifo close failed: " << errno;
267266
}

trikControl/src/cameraLineDetectorSensorWorker.h

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,25 @@
2323
#include <QtCore/QTextStream>
2424
#include <QtCore/QList>
2525

26-
#include "declSpec.h"
27-
#include "sensor.h"
28-
2926
namespace trikControl {
3027

31-
class TRIKCONTROL_EXPORT CameraLineDetectorSensorWorker : public Sensor
28+
/// Worker object that processes rover-cv fifo and updates stored reading.
29+
class CameraLineDetectorSensorWorker : public QObject
3230
{
3331
Q_OBJECT
3432

3533
public:
36-
CameraLineDetectorSensorWorker(QString const &roverCvBinary, QString const &inputFile, QString const &outputFile);
34+
/// Constructor.
35+
/// @param roverCvBinary - binary file of rover-cv program which is used to work with video
36+
/// @param inputFile - rover-cv input fifo. Note that we will write data here, not read it.
37+
/// @param outputFile - rover-cv output fifo. Note that we will read sensor data from here.
38+
/// @param toleranceFactor - a value on which hueTolerance, saturationTolerance and valueTolerance is multiplied
39+
/// after "detect" command. Higher values allow to count more points on an image as tracked object.
40+
CameraLineDetectorSensorWorker(QString const &roverCvBinary, QString const &inputFile
41+
, QString const &outputFile, double toleranceFactor);
42+
43+
/// Destructor.
3744
~CameraLineDetectorSensorWorker();
38-
void moveChildrenToCorrectThread();
3945

4046
public slots:
4147
/// Initializes a camera and begins showing image from it on display.
@@ -49,30 +55,68 @@ public slots:
4955
int read();
5056

5157
private slots:
58+
/// Called when rover-cv reports error. Note that it can still die silently.
5259
void onRoverCvError(QProcess::ProcessError error);
60+
61+
/// Called when new data is available on stdout of rover-cv. Note that process stdout is buffered, so this method
62+
/// can be called much later than expected.
5363
void onRoverCvReadyReadStandardOutput();
64+
65+
/// Called when new data is available on stderr of rover-cv.
5466
void onRoverCvReadyReadStandardError();
5567

5668
/// Updates current reading when new value is ready.
5769
void readFile();
5870

5971
private:
72+
/// Starts rover-cv if needed and opens its fifos.
6073
void initDetector();
74+
75+
/// Starts rover-cv process.
6176
void startRoverCv();
77+
78+
/// Opens input and output fifos for rover-cv.
6279
void openFifos();
80+
81+
/// Puts queued commands to rover-cv input fifo and clears queue if rover-cv is ready, otherwise does nothing.
82+
/// Life without continuations is pain.
6383
void tryToExecute();
84+
85+
/// Closes fifos. Does not kill rover-cv.
6486
void deinitialize();
6587

88+
/// Listener for output fifo.
6689
QScopedPointer<QSocketNotifier> mSocketNotifier;
90+
91+
/// Current stored reading of a sensor.
6792
int mReading;
93+
94+
/// File name (with path) of rover-cv binary.
6895
QString mRoverCvBinary;
96+
97+
/// File descriptor for output fifo.
6998
int mOutputFileDescriptor;
99+
100+
/// rover-cv process.
70101
QProcess mRoverCvProcess;
102+
103+
/// Input fifo.
71104
QFile mInputFile;
105+
106+
/// Output fifo.
72107
QFile mOutputFile;
108+
109+
/// File stream for command fifo. Despite its name it is used to output commands. It is input for rover-cv.
73110
QTextStream mInputStream;
111+
112+
/// Flag that sensor is ready and waiting for commands.
74113
bool mReady;
114+
115+
/// A queue of commands to be passed to input fifo when it is ready.
75116
QList<QString> mCommandQueue;
117+
118+
/// A value on which hueTolerance, saturationTolerance and valueTolerance is multiplied after "detect" command.
119+
double mToleranceFactor;
76120
};
77121

78122
}

trikControl/src/configurer.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,11 @@ QString Configurer::roverCvOutputFile() const
299299
return mRoverCvOutputFile;
300300
}
301301

302+
double Configurer::roverCvToleranceFactor() const
303+
{
304+
return mRoverCvToleranceFactor;
305+
}
306+
302307
void Configurer::loadInit(QDomElement const &root)
303308
{
304309
if (root.elementsByTagName("initScript").isEmpty()) {
@@ -626,4 +631,5 @@ void Configurer::loadCameraLineDetector(QDomElement const &root)
626631
mRoverCvBinary = cameraLineDetector.attribute("roverCv");
627632
mRoverCvInputFile = cameraLineDetector.attribute("inputFile");
628633
mRoverCvOutputFile = cameraLineDetector.attribute("outputFile");
634+
mRoverCvToleranceFactor = cameraLineDetector.attribute("toleranceFactor").toDouble();
629635
}

trikControl/src/configurer.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright 2013 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.
@@ -132,6 +132,8 @@ class Configurer {
132132

133133
QString roverCvOutputFile() const;
134134

135+
double roverCvToleranceFactor() const;
136+
135137
private:
136138
struct ServoMotorType {
137139
int min;
@@ -233,6 +235,7 @@ class Configurer {
233235
QString mRoverCvBinary;
234236
QString mRoverCvInputFile;
235237
QString mRoverCvOutputFile;
238+
double mRoverCvToleranceFactor;
236239
};
237240

238241
}

trikControl/src/linux/cameraLineDetectorSensor.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,15 @@
2020

2121
using namespace trikControl;
2222

23-
CameraLineDetectorSensor::CameraLineDetectorSensor(
24-
QString const &roverCvBinary
23+
CameraLineDetectorSensor::CameraLineDetectorSensor(QString const &roverCvBinary
2524
, QString const &inputFile
26-
, QString const &outputFile)
27-
: mCameraLineDetectorSensorWorker(new CameraLineDetectorSensorWorker(roverCvBinary, inputFile, outputFile))
25+
, QString const &outputFile
26+
, double toleranceFactor)
27+
: mCameraLineDetectorSensorWorker(
28+
new CameraLineDetectorSensorWorker(roverCvBinary, inputFile, outputFile, toleranceFactor)
29+
)
2830
{
2931
mCameraLineDetectorSensorWorker->moveToThread(&mWorkerThread);
30-
mCameraLineDetectorSensorWorker->moveChildrenToCorrectThread();
3132
mWorkerThread.start();
3233
}
3334

@@ -49,5 +50,6 @@ void CameraLineDetectorSensor::detect()
4950

5051
int CameraLineDetectorSensor::read()
5152
{
53+
// Read is called synchronously and only takes prepared value from sensor.
5254
return mCameraLineDetectorSensorWorker->read();
5355
}

0 commit comments

Comments
 (0)