PDA

View Full Version : QStateMachine for camera acquisition



go9kata
13th July 2018, 16:11
Hi,

I am trying to implement camera acquisition class with OpenCV and QStateMachine.
I have the following state machine definition:



DriverVideoCapture::DriverVideoCapture(QObject *parent, const int camid) : QObject(parent)
{
// configure state machine
m_engine = new QStateMachine(this);
QState *state_idle = new QState(m_engine);
QState *state_acquire = new QState(m_engine);
QState *state_error = new QState(m_engine);

state_idle->addTransition(this, &DriverVideoCapture::start, state_acquire);
state_idle->addTransition(this, &DriverVideoCapture::error, state_error);
state_acquire->addTransition(this, &DriverVideoCapture::grab, state_acquire);
state_acquire->addTransition(this, &DriverVideoCapture::stop, state_idle);
state_acquire->addTransition(this, &DriverVideoCapture::error, state_error);
connect(state_acquire, &QState::entered, this, &DriverVideoCapture::on_stateAcquire);
m_engine->setInitialState(state_idle);
m_engine->start();

m_videoCapture = new cv::VideoCapture(camid);
if (!m_videoCapture->isOpened())
emit error();
}


Now inside state_acquire I will do the blocking operation of frame reading



void DriverVideoCapture::on_stateAcquire()
{
cv::Mat frame;
if (!m_videoCapture->isOpened())
return;

if (!m_videoCapture->read(frame))
emit error();

emit grab();
}


And I will connect buttons to start and stop the process:



m_driverVideoCapture = new DriverVideoCapture(this);
connect(ui->pushButton_start, &QPushButton::clicked, m_driverVideoCapture, &DriverVideoCapture::start);
connect(ui->pushButton_stop, &QPushButton::clicked, m_driverVideoCapture, &DriverVideoCapture::stop);


The state machine get's a transition from state_idle to state_acquire after the start signal. Then it continues looping inside state_acquire. Once the stop signal is emitted though, it does not get detected and the state machine fails to do the transition from state_acquire to state_idle again. Any clues?

Second question, the event loop created by QStateMachine should be in the current thread. If I move the DriverVideoCapture to a worker thread, as in QThread, is the state machine getting an event loop different from the main GUI event loop?

Thank you in advance for any clarifications and tips!