MNE-CPP  beta 1.0
fiffsimulator.cpp
1 //=============================================================================================================
36 //*************************************************************************************************************
37 //=============================================================================================================
38 // INCLUDES
39 //=============================================================================================================
40 
41 #include "fiffsimulator.h"
42 #include "fiffsimulatorproducer.h"
43 
45 
46 #include <utils/ioutils.h>
47 
48 
49 //*************************************************************************************************************
50 //=============================================================================================================
51 // QT INCLUDES
52 //=============================================================================================================
53 
54 #include <QtCore/QtPlugin>
55 #include <QtCore/QTextStream>
56 #include <QtCore/QFile>
57 #include <QMutexLocker>
58 #include <QList>
59 
60 #include <QDebug>
61 
62 
63 //*************************************************************************************************************
64 //=============================================================================================================
65 // USED NAMESPACES
66 //=============================================================================================================
67 
68 using namespace FiffSimulatorPlugin;
69 using namespace UTILSLIB;
70 
71 
72 //*************************************************************************************************************
73 //=============================================================================================================
74 // DEFINE MEMBER METHODS
75 //=============================================================================================================
76 
78 : m_sFiffSimulatorClientAlias("mne-x")
79 , m_pRtCmdClient(NULL)
80 , m_bCmdClientIsConnected(false)
81 , m_sFiffSimulatorIP("127.0.0.1")//("172.21.16.88")
82 , m_pFiffSimulatorProducer(new FiffSimulatorProducer(this))
83 , m_iBufferSize(-1)
84 , m_pRawMatrixBuffer_In(0)
85 , m_bIsRunning(false)
86 {
87 
88 }
89 
90 
91 //*************************************************************************************************************
92 
94 {
95  if(m_pFiffSimulatorProducer->isRunning() || this->isRunning())
96  stop();
97 }
98 
99 
100 //*************************************************************************************************************
101 
102 QSharedPointer<IPlugin> FiffSimulator::clone() const
103 {
104  QSharedPointer<FiffSimulator> pFiffSimulatorClone(new FiffSimulator());
105  return pFiffSimulatorClone;
106 }
107 
108 
109 //*************************************************************************************************************
110 
111 void FiffSimulator::init()
112 {
113  m_pRTMSA_FiffSimulator = PluginOutputData<NewRealTimeMultiSampleArray>::create(this, "FiffSimulator", "Fiff Simulator Output");
114  m_pRTMSA_FiffSimulator->data()->setName(this->getName());//Provide name to auto store widget settings
115  m_outputConnectors.append(m_pRTMSA_FiffSimulator);
116 
117  // Start FiffSimulatorProducer
118  m_pFiffSimulatorProducer->start();
119 
120  //init channels when fiff info is available
121  connect(this, &FiffSimulator::fiffInfoAvailable, this, &FiffSimulator::initConnector);
122 
123  //Try to connect the cmd client on start up using localhost connection
124  this->connectCmdClient();
125 }
126 
127 
128 //*************************************************************************************************************
129 
131 {
132  qDebug() << "void FiffSimulator::unload()";
133 }
134 
135 
136 //*************************************************************************************************************
137 //=============================================================================================================
138 // Create measurement instances and config them
139 //=============================================================================================================
140 
141 void FiffSimulator::initConnector()
142 {
143  if(m_pFiffInfo)
144  {
145  m_pRTMSA_FiffSimulator->data()->initFromFiffInfo(m_pFiffInfo);
146  m_pRTMSA_FiffSimulator->data()->setMultiArraySize(1);
147  m_pRTMSA_FiffSimulator->data()->setVisibility(true);
148  m_pRTMSA_FiffSimulator->data()->setXMLLayoutFile("./mne_x_plugins/resources/FiffSimulator/VectorViewSimLayout.xml");
149  }
150 }
151 
152 
153 //*************************************************************************************************************
154 
155 void FiffSimulator::changeConnector(qint32 p_iNewConnectorId)
156 {
157  if(p_iNewConnectorId != m_iActiveConnectorId)
158  {
159  //
160  // read meas info
161  //
162  (*m_pRtCmdClient)["selcon"].pValues()[0].setValue(p_iNewConnectorId);
163  (*m_pRtCmdClient)["selcon"].send();
164 
165  m_iActiveConnectorId = p_iNewConnectorId;
166 
167  //
168  // clear all and request everything new
169  //
170  clear();
171 
172  //
173  // request available commands
174  //
175  m_pRtCmdClient->requestCommands();
176 
177  //
178  // Read Info
179  //
180  if(!m_pFiffInfo)
181  requestInfo();
182 
183  //
184  // Read Buffer Size
185  //
186  m_iBufferSize = m_pRtCmdClient->requestBufsize();
187 
188  emit cmdConnectionChanged(m_bCmdClientIsConnected);
189  }
190 }
191 
192 
193 //*************************************************************************************************************
194 
196 {
197  QMutexLocker locker(&m_qMutex);
198  m_pFiffInfo.reset();
199  m_iBufferSize = -1;
200 }
201 
202 
203 //*************************************************************************************************************
204 
206 {
207  if(m_pRtCmdClient.isNull())
208  m_pRtCmdClient = QSharedPointer<RtCmdClient>(new RtCmdClient);
209  else if(m_bCmdClientIsConnected)
210  this->disconnectCmdClient();
211 
212  m_pRtCmdClient->connectToHost(m_sFiffSimulatorIP);
213  m_pRtCmdClient->waitForConnected(1000);
214 
215  if(m_pRtCmdClient->state() == QTcpSocket::ConnectedState)
216  {
217  m_qMutex.lock();
218 
219  if(!m_bCmdClientIsConnected)
220  {
221  //
222  // request available commands
223  //
224  m_pRtCmdClient->requestCommands();
225 
226  //
227  // set cmd client is connected
228  //
229  m_bCmdClientIsConnected = true;
230 
231  //
232  // Read Info
233  //
234  if(!m_pFiffInfo)
235  requestInfo();
236 
237  //
238  // Read Connectors
239  //
240  if(m_qMapConnectors.size() == 0)
241  m_iActiveConnectorId = m_pRtCmdClient->requestConnectors(m_qMapConnectors);
242 
243  QMap<qint32, QString>::const_iterator it;
244  for(it = m_qMapConnectors.begin(); it != m_qMapConnectors.end(); ++it)
245  if(it.value().compare("Fiff File Simulator") == 0 && m_iActiveConnectorId != it.key())
246  changeConnector(it.key());
247 
248  //
249  // Read Buffer Size
250  //
251  m_iBufferSize = m_pRtCmdClient->requestBufsize();
252 
253  emit cmdConnectionChanged(m_bCmdClientIsConnected);
254  }
255  m_qMutex.unlock();
256  }
257 }
258 
259 
260 //*************************************************************************************************************
261 
263 {
264  QMutexLocker locker(&m_qMutex);
265  if(m_bCmdClientIsConnected)
266  {
267  m_pRtCmdClient->disconnectFromHost();
268  if(m_pRtCmdClient->ConnectedState != QTcpSocket::UnconnectedState)
269  m_pRtCmdClient->waitForDisconnected();
270  m_bCmdClientIsConnected = false;
271  emit cmdConnectionChanged(m_bCmdClientIsConnected);
272  }
273 }
274 
275 
276 //*************************************************************************************************************
277 
279 {
280  while(!(m_pFiffSimulatorProducer->m_iDataClientId > -1 && m_bCmdClientIsConnected))
281  qWarning() << "FiffSimulatorProducer is not running! Retry...";
282 
283  if(m_pFiffSimulatorProducer->m_iDataClientId > -1 && m_bCmdClientIsConnected)
284  {
285  // read meas info
286  (*m_pRtCmdClient)["measinfo"].pValues()[0].setValue(m_pFiffSimulatorProducer->m_iDataClientId);
287  (*m_pRtCmdClient)["measinfo"].send();
288 
289  m_pFiffSimulatorProducer->producerMutex.lock();
290  m_pFiffSimulatorProducer->m_bFlagInfoRequest = true;
291  m_pFiffSimulatorProducer->producerMutex.unlock();
292  }
293  else
294  qWarning() << "FiffSimulatorProducer is not connected!";
295 }
296 
297 
298 //*************************************************************************************************************
299 
301 {
302  //Check if the thread is already or still running. This can happen if the start button is pressed immediately after the stop button was pressed. In this case the stopping process is not finished yet but the start process is initiated.
303  if(this->isRunning())
304  QThread::wait();
305 
306  if(m_bCmdClientIsConnected && m_pFiffInfo)
307  {
308  //Set buffer size
309  (*m_pRtCmdClient)["bufsize"].pValues()[0].setValue(m_iBufferSize);
310  (*m_pRtCmdClient)["bufsize"].send();
311 
312  // Buffer
313  m_qMutex.lock();
314  m_pRawMatrixBuffer_In = QSharedPointer<RawMatrixBuffer>(new RawMatrixBuffer(8,m_pFiffInfo->nchan,m_iBufferSize));
315  m_bIsRunning = true;
316  m_qMutex.unlock();
317 
318  // Start threads
319  QThread::start();
320 
321  m_pFiffSimulatorProducer->start();
322 
323  while(!m_pFiffSimulatorProducer->m_bFlagMeasuring)
324  msleep(1);
325 
326  // Start Measurement at rt_Server
327  // start measurement
328  (*m_pRtCmdClient)["start"].pValues()[0].setValue(m_pFiffSimulatorProducer->m_iDataClientId);
329  (*m_pRtCmdClient)["start"].send();
330 
331  return true;
332  }
333  else
334  return false;
335 }
336 
337 
338 //*************************************************************************************************************
339 
340 bool FiffSimulator::stop()
341 {
342  if(m_pFiffSimulatorProducer->isRunning())
343  m_pFiffSimulatorProducer->stop();
344 
345  //Wait until this thread is stopped
346  m_qMutex.lock();
347  m_bIsRunning = false;
348  m_qMutex.unlock();
349 
350  if(this->isRunning())
351  {
352  //In case the semaphore blocks the thread -> Release the QSemaphore and let it exit from the pop function (acquire statement)
353  m_pRawMatrixBuffer_In->releaseFromPop();
354 
355  m_pRawMatrixBuffer_In->clear();
356 
357  m_pRTMSA_FiffSimulator->data()->clear();
358  }
359 
360  return true;
361 }
362 
363 
364 //*************************************************************************************************************
365 
367 {
368  return _ISensor;
369 }
370 
371 
372 //*************************************************************************************************************
373 
374 QString FiffSimulator::getName() const
375 {
376  return "Fiff Simulator";
377 }
378 
379 
380 //*************************************************************************************************************
381 
383 {
384  FiffSimulatorSetupWidget* widget = new FiffSimulatorSetupWidget(this);//widget is later distroyed by CentralWidget - so it has to be created everytime new
385 
386  return widget;
387 }
388 
389 
390 //*************************************************************************************************************
391 
392 void FiffSimulator::run()
393 {
394  MatrixXf matValue;
395  while(true)
396  {
397  {
398  QMutexLocker locker(&m_qMutex);
399  if(!m_bIsRunning)
400  break;
401  }
402  //pop matrix
403  matValue = m_pRawMatrixBuffer_In->pop();
404 
405  //emit values
406  m_pRTMSA_FiffSimulator->data()->setValue(matValue.cast<double>());
407  }
408 }
Contains the declaration of the FiffSimulatorProducer class.
virtual IPlugin::PluginType getType() const
The FiffSimulatorSetupWidget class provides the Fiff configuration window.
OutputConnectorList m_outputConnectors
Definition: IPlugin.h:222
Real-time command client.
Definition: rtcmdclient.h:86
void cmdConnectionChanged(bool p_bStatus)
virtual QSharedPointer< IPlugin > clone() const
void changeConnector(qint32 p_iNewConnectorId)
static QSharedPointer< PluginOutputData< T > > create(IPlugin *parent, const QString &name, const QString &descr)
The FiffSimulatorProducer class provides a Fiff data producer for a given sampling rate...
Contains the declaration of the FiffSimulatorSetupWidget class.
IOUtils class declaration.
virtual const char * getName() const