UsTK : Ultrasound ToolKit  version 2.0.1 under development (2023-12-07)
usNetworkGrabber.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ustk software.
4  * Copyright (C) 2016 - 2017 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ustk with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * This software was developed at:
17  * Inria Rennes - Bretagne Atlantique
18  * Campus Universitaire de Beaulieu
19  * 35042 Rennes Cedex
20  * France
21  *
22  * If you have questions regarding the use of this file, please contact
23  * Inria at ustk@inria.fr
24  *
25  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27  *
28  * Authors:
29  * Pedro Patlan
30  * Marc Pouliquen
31  *
32  *****************************************************************************/
33 
34 #include <visp3/ustk_grabber/usNetworkGrabber.h>
35 
36 #if defined(USTK_HAVE_QT5) || defined(USTK_HAVE_VTK_QT)
37 
38 #include <fstream>
39 #include <iostream>
40 #include <visp3/io/vpImageIo.h>
41 
42 #include <QtCore/QDataStream>
43 #include <QtCore/QEventLoop>
44 
45 using namespace std;
46 
51 usNetworkGrabber::usNetworkGrabber(QObject *parent) : QObject(parent)
52 {
53  m_ip = "192.168.100.2";
54 
55  m_tcpSocket = new QTcpSocket(this);
56 
58 
59  m_verbose = false;
60 
61  m_connect = false;
62 
66 
67  m_isInit = false;
68  m_isRunning = false;
69 
70  m_thread = NULL;
71 
72  QObject::connect(this, SIGNAL(serverUpdateEnded(bool)), this, SLOT(serverUpdated(bool)));
73  QObject::connect(this, SIGNAL(runAcquisitionSignal(bool)), this, SLOT(sendRunSignal(bool)));
74  QObject::connect(this, SIGNAL(sendAcquisitionParametersSignal()), this, SLOT(sendAcquisitionParametersSlot()));
75 }
76 
81 {
82  this->stopAcquisition();
83  if(m_thread) {
84  m_thread->quit();
85  m_thread->wait();
86  delete m_thread;
87  m_thread = NULL;
88  }
89  if (m_tcpSocket->isOpen())
90  m_tcpSocket->close();
91 }
92 
97 {
98  m_connect = true;
100 }
101 
105 void usNetworkGrabber::connectToServer(QHostAddress address)
106 {
107  setIPAddress(address.toString().toStdString());
108  m_connect = true;
110 }
111 
116 {
117  m_connect = false;
118 
119  emit(endConnection());
120  // wait disconnection is effective
121  QEventLoop loop;
122  loop.connect(m_tcpSocket, SIGNAL(disconnected()), SLOT(quit()));
123  loop.exec();
124 }
125 
130 {
131  if (m_connect) {
132  if (m_verbose)
133  std::cout << "ip listening : " << m_ip.c_str() << std::endl;
134  QHostAddress addr(m_ip.c_str());
135  m_tcpSocket->connectToHost(addr, 8080);
136 
137  connect(m_tcpSocket, SIGNAL(connected()), this, SLOT(connected()));
138  connect(this, SIGNAL(endConnection()), this, SLOT(disconnected()));
139  connect(m_tcpSocket, SIGNAL(disconnected()), this, SLOT(disconnected()));
140  connect(m_tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this,
141  SLOT(handleError(QAbstractSocket::SocketError)));
142 
143  if (m_tcpSocket->isOpen()) {
144  if (m_verbose) {
145  std::cout << "socket is open." << std::endl;
146  }
147  } else {
148  if (m_verbose) {
149  std::cout << "socket not is open." << std::endl;
150  }
151  }
152 
153  if (m_tcpSocket->isReadable()) {
154  if (m_verbose) {
155  std::cout << "socket is readable." << std::endl;
156  }
157  }
158  } else
159  m_tcpSocket->close();
160 }
161 
166 {
167  if (m_verbose) {
168  std::cout << "connected to server" << std::endl;
169  std::cout << "local port : " << m_tcpSocket->localPort() << std::endl;
170  std::cout << "local addr : " << m_tcpSocket->localAddress().toString().toStdString() << std::endl;
171  std::cout << "peer port : " << m_tcpSocket->peerPort() << std::endl;
172  std::cout << "peer addr : " << m_tcpSocket->peerAddress().toString().toStdString() << std::endl;
173  }
174 }
175 
180 {
181  if (m_verbose)
182  std::cout << "Disconnected .... \n";
183  m_tcpSocket->close();
184 }
185 
189 void usNetworkGrabber::handleError(QAbstractSocket::SocketError err)
190 {
191  Q_UNUSED(err);
192  // Notify an error. tcpSocket.errorString() automatically gets an error message (in english).
193  throw(vpException(vpException::fatalError, m_tcpSocket->errorString().toStdString()));
194 
195  // Formally close the connection
196  m_tcpSocket->close();
197 }
198 
207 {
208 
209  if (m_isRunning)
210  stopAcquisition();
211 
212  QByteArray block;
213  QDataStream out(&block, QIODevice::WriteOnly);
214 #if (defined(USTK_HAVE_QT5) || defined(USTK_HAVE_VTK_QT5))
215  out.setVersion(QDataStream::Qt_5_0);
216 #elif defined(USTK_HAVE_VTK_QT4)
217  out.setVersion(QDataStream::Qt_4_8);
218 #else
219  throw(vpException(vpException::fatalError, "your Qt version is not managed in ustk"));
220 #endif
221 
222  // Writing on the stream. Warning : order matters ! (must be the same as on server side when reading)
223 
224  out << header.headerId;
225  out << header.probeId;
226  out << header.slotId;
227  out << header.imagingMode;
228  m_tcpSocket->write(block);
229 
230  if (m_verbose)
231  std::cout << "INIT SENT, waiting server confirmation..." << std::endl;
232  // loop to wait update on server
233  QEventLoop *loop = new QEventLoop;
234  QObject::connect(this, SIGNAL(endBlockingLoop()), loop, SLOT(quit()));
235  loop->exec();
236 
238 
239  if (m_verbose)
240  std::cout << "server confirmation : " << (int)m_updateParametersSucess << std::endl;
241 
243 }
244 
252 {
253 
254  if (m_isRunning)
255  stopAcquisition();
256 
257  QByteArray block;
258  QDataStream out(&block, QIODevice::WriteOnly);
259 #if (defined(USTK_HAVE_QT5) || defined(USTK_HAVE_VTK_QT5))
260  out.setVersion(QDataStream::Qt_5_0);
261 #elif defined(USTK_HAVE_VTK_QT4)
262  out.setVersion(QDataStream::Qt_4_8);
263 #else
264  throw(vpException(vpException::fatalError, "your Qt version is not managed in ustk"));
265 #endif
266 
267  // Writing on the stream. Warning : order matters ! (must be the same as on server side when reading)
268 
269  out << header.headerId;
270  out << header.probeId;
271  out << header.slotId;
272  out << header.imagingMode;
273  m_tcpSocket->write(block);
274 
275  if (m_verbose)
276  std::cout << "INIT SENT, waiting server confirmation..." << std::endl;
277  // loop to wait update on server
278  QEventLoop *loop = new QEventLoop;
279  QObject::connect(this, SIGNAL(endBlockingLoop()), loop, SLOT(quit()));
280  loop->exec();
281 
283 
284  if (m_verbose)
285  std::cout << "server confirmation : " << (int)m_updateParametersSucess << std::endl;
286 
288 }
289 
293 void usNetworkGrabber::disconnect() { m_tcpSocket->disconnect(); }
294 
299 {
300 
301  if (m_isRunning)
302  stopAcquisition();
303 
305 
307 }
308 
313 {
314 
315  QByteArray block;
316  QDataStream stream(&block, QIODevice::WriteOnly);
317 #if (defined(USTK_HAVE_QT5) || defined(USTK_HAVE_VTK_QT5))
318  stream.setVersion(QDataStream::Qt_5_0);
319 #elif defined(USTK_HAVE_VTK_QT4)
320  stream.setVersion(QDataStream::Qt_4_8);
321 #else
322  throw(vpException(vpException::fatalError, "your Qt version is not managed in ustk"));
323 #endif
324 
325  // Writing on the stream. Warning : order matters ! (must be the same as on server side when reading)
326 
327  stream << 2; // update id = 2
340 
341  if (m_verbose) {
342  std::cout << "UPDATE SENT : " << std::endl;
343  std::cout << "TransmitFrequency = " << m_acquisitionParameters.getTransmitFrequency() << std::endl;
344  std::cout << "SamplingFrequency = " << m_acquisitionParameters.getSamplingFrequency() << std::endl;
345  std::cout << "ImagingMode = " << m_acquisitionParameters.getImagingMode() << std::endl;
346  std::cout << "PostScanMode = " << m_acquisitionParameters.getPostScanMode() << std::endl;
347  std::cout << "PostScanHeigh = " << m_acquisitionParameters.getPostScanHeigh() << std::endl;
348  std::cout << "PostScanWidth = " << m_acquisitionParameters.getPostScanWidth() << std::endl;
349  std::cout << "ImageDepth = " << m_acquisitionParameters.getImageDepth() << std::endl;
350  std::cout << "Sector = " << m_acquisitionParameters.getSector() << std::endl;
351  std::cout << "ActivateMotor = " << m_acquisitionParameters.getActivateMotor() << std::endl;
352  std::cout << "MotorPosition = " << m_acquisitionParameters.getMotorPosition() << std::endl;
353  std::cout << "FramesPerVolume = " << m_acquisitionParameters.getFramesPerVolume() << std::endl;
354  std::cout << "anglePerFrame = " << m_acquisitionParameters.getSepsPerFrame() << std::endl;
355  }
356  m_tcpSocket->write(block);
357 
358  if (m_verbose)
359  std::cout << "waiting server confirmation..." << std::endl;
360 
361  // loop to wait update on server side
362  QEventLoop *loop = new QEventLoop;
363  QObject::connect(this, SIGNAL(endBlockingLoop()), loop, SLOT(quit()));
364  loop->exec();
365 
366  if (m_verbose)
367  std::cout << "Update server confirmation : " << (int)m_updateParametersSucess << std::endl;
368 }
369 
374 {
375  m_updateParametersSucess = sucess;
376  emit(endBlockingLoop());
377 }
378 
384 {
385 
386  int transmitFrequency;
387  int samplingFrequency;
388  int imagingMode;
389  bool postScanMode;
390  int postScanHeigh;
391  int postScanWidth;
392  int imageDepth;
393  int sector;
394  bool activateMotor;
395  int motorPosition;
396  int framesPerVolume;
397  int anglePerFrame;
398  int transmitFrequencyMin;
399  int samplingFrequencyMin;
400  int imagingModeMin;
401  int imageDepthMin;
402  int sectorMin;
403  int motorPositionMin;
404  int framesPerVolumeMin;
405  int anglePerFrameMin;
406  int transmitFrequencyMax;
407  int samplingFrequencyMax;
408  int imagingModeMax;
409  int imageDepthMax;
410  int sectorMax;
411  int motorPositionMax;
412  int framesPerVolumeMax;
413  int anglePerFrameMax;
414 
415  stream >> transmitFrequency;
416  stream >> samplingFrequency;
417  stream >> imagingMode;
418  stream >> postScanMode;
419  stream >> postScanHeigh;
420  stream >> postScanWidth;
421  stream >> imageDepth;
422  stream >> sector;
423  stream >> activateMotor;
424  stream >> motorPosition;
425  stream >> framesPerVolume;
426  stream >> anglePerFrame;
427  stream >> transmitFrequencyMin;
428  stream >> samplingFrequencyMin;
429  stream >> imagingModeMin;
430  stream >> imageDepthMin;
431  stream >> sectorMin;
432  stream >> motorPositionMin;
433  stream >> framesPerVolumeMin;
434  stream >> anglePerFrameMin;
435  stream >> transmitFrequencyMax;
436  stream >> samplingFrequencyMax;
437  stream >> imagingModeMax;
438  stream >> imageDepthMax;
439  stream >> sectorMax;
440  stream >> motorPositionMax;
441  stream >> framesPerVolumeMax;
442  stream >> anglePerFrameMax;
443 
444  if (m_verbose) {
445  std::cout << "transmitFrequency = " << transmitFrequency << std::endl;
446  std::cout << "samplingFrequency = " << samplingFrequency << std::endl;
447  std::cout << "imagingMode = " << imagingMode << std::endl;
448  std::cout << "postScanMode = " << postScanMode << std::endl;
449  std::cout << "postScanHeigh = " << postScanHeigh << std::endl;
450  std::cout << "postScanWidth = " << postScanWidth << std::endl;
451  std::cout << "imageDepth = " << imageDepth << std::endl;
452  std::cout << "sector = " << sector << std::endl;
453  std::cout << "activateMotor = " << activateMotor << std::endl;
454  std::cout << "motorPosition = " << motorPosition << std::endl;
455  std::cout << "framesPerVolume = " << framesPerVolume << std::endl;
456  std::cout << "anglePerFrame = " << anglePerFrame << std::endl;
457  std::cout << "transmitFrequencyMin = " << transmitFrequencyMin << std::endl;
458  std::cout << "samplingFrequencyMin = " << samplingFrequencyMin << std::endl;
459  std::cout << "imagingModeMin = " << imagingModeMin << std::endl;
460  std::cout << "imageDepthMin = " << imageDepthMin << std::endl;
461  std::cout << "sectorMin = " << sectorMin << std::endl;
462  std::cout << "motorPositionMin = " << motorPositionMin << std::endl;
463  std::cout << "framesPerVolumeMin = " << framesPerVolumeMin << std::endl;
464  std::cout << "anglePerFrameMin = " << anglePerFrameMin << std::endl;
465  std::cout << "transmitFrequencyMax = " << transmitFrequencyMax << std::endl;
466  std::cout << "samplingFrequencyMax = " << samplingFrequencyMax << std::endl;
467  std::cout << "imagingModeMax = " << imagingModeMax << std::endl;
468  std::cout << "imageDepthMax = " << imageDepthMax << std::endl;
469  std::cout << "sectorMax = " << sectorMax << std::endl;
470  std::cout << "motorPositionMax = " << motorPositionMax << std::endl;
471  std::cout << "framesPerVolumeMax = " << framesPerVolumeMax << std::endl;
472  std::cout << "anglePerFrameMax = " << anglePerFrameMax << std::endl;
473  }
474 
486  if (anglePerFrame == 0)
488  else if (anglePerFrame == 2)
490  else if (anglePerFrame == 4)
492  else if (anglePerFrame == 8)
494  else if (anglePerFrame == 16)
496  else if (anglePerFrame == 32)
498 
499  m_acquisitionParameters.setTransmitFrequencyMin(transmitFrequencyMin);
500  m_acquisitionParameters.setSamplingFrequencyMin(samplingFrequencyMin);
505  if (anglePerFrame == 0)
507  else if (anglePerFrame == 2)
509  else if (anglePerFrame == 4)
511  else if (anglePerFrame == 8)
513  else if (anglePerFrame == 16)
515  else if (anglePerFrame == 32)
517 
518  m_acquisitionParameters.setTransmitFrequencyMax(transmitFrequencyMax);
519  m_acquisitionParameters.setSamplingFrequencyMax(samplingFrequencyMax);
525  if (anglePerFrame == 0)
527  else if (anglePerFrame == 2)
529  else if (anglePerFrame == 4)
531  else if (anglePerFrame == 8)
533  else if (anglePerFrame == 16)
535  else if (anglePerFrame == 32)
537 }
538 
542 void usNetworkGrabber::setMotorActivation(bool activateMotor)
543 {
545 }
546 
551 {
553 }
554 
558 void usNetworkGrabber::setFramesPerVolume(int framesPerVolume)
559 {
560  if (framesPerVolume < m_acquisitionParameters.getFramesPerVolumeMin() ||
561  framesPerVolume > m_acquisitionParameters.getFramesPerVolumeMax() ||
562  framesPerVolume % 2 == 0) // odd number of frames per volume required
563  throw(vpException(vpException::badValue),
564  "Number of frames per volume must be odd, and between min and max values");
566 }
567 
572 {
574  throw(vpException(vpException::badValue), "Image depth must be included between min and max values");
576 }
577 
581 void usNetworkGrabber::setImagingMode(int imagingMode)
582 {
583  if (imagingMode < m_acquisitionParameters.getImagingModeMin() ||
585  throw(vpException(vpException::badValue), "Imaging mode out of range");
587 }
588 
592 void usNetworkGrabber::setMotorPosition(int motorPosition)
593 {
594  if (motorPosition < m_acquisitionParameters.getMotorPositionMin() ||
596  throw(vpException(vpException::badValue), "Motor poisition out of range");
598 }
599 
604 
609 
614 
618 void usNetworkGrabber::setSamplingFrequency(int samplingFrequency)
619 {
620  if (samplingFrequency < m_acquisitionParameters.getSamplingFrequencyMin() ||
621  samplingFrequency > m_acquisitionParameters.getSamplingFrequencyMax())
622  throw(vpException(vpException::badValue), "Sampling frequency out of range");
624 }
625 
630 {
632  throw(vpException(vpException::badValue), "Sector out of range");
634 }
635 
639 void usNetworkGrabber::setTransmitFrequency(int transmitFrequency)
640 {
641  if (transmitFrequency < m_acquisitionParameters.getTransmitFrequencyMin() ||
642  transmitFrequency > m_acquisitionParameters.getTransmitFrequencyMax())
643  throw(vpException(vpException::badValue), "Transmit frequency out of range");
644 
646 }
647 
652 {
653  if (m_thread == NULL) {
654  m_thread = new QThread;
655  this->moveToThread(m_thread);
656  m_thread->start();
657  }
658  emit runAcquisitionSignal(true);
659 
660  //vpTime::wait(10); // workaround to allow calling run / stop methods one just after another
661 }
662 
670 {
671  emit runAcquisitionSignal(false);
672 
673  vpTime::wait(10); // workaround to allow calling run / stop methods one just after another
674 }
675 
681 {
682  usRunControlHeaderSent header;
683  header.run = run;
684 
685  QByteArray block;
686  QDataStream out(&block, QIODevice::WriteOnly);
687 #if (defined(USTK_HAVE_QT5) || defined(USTK_HAVE_VTK_QT5))
688  out.setVersion(QDataStream::Qt_5_0);
689 #elif defined(USTK_HAVE_VTK_QT4)
690  out.setVersion(QDataStream::Qt_4_8);
691 #else
692  throw(vpException(vpException::fatalError, "your Qt version is not managed in ustk"));
693 #endif
694 
695  // Writing on the stream. Warning : order matters ! (must be the same as on server side when reading)
696  out << header.headerId;
697  out << header.run;
698  m_tcpSocket->write(block);
699  m_isRunning = run;
700 }
701 
706 
711 {
713 }
714 
719 
724 
729 
734 
739 
744 
749 
754 
759 
764 
769 {
770  setMotorPosition(40);
772 }
773 
774 #endif
Class to store acquisition parameters for ultrasound station.
void setFramesPerVolumeMax(int framesPerVolumeMax)
void setImageDepthMin(int imageDepthMin)
void setImageDepth(int imageDepth)
void setPostScanHeigh(int postScanHeigh)
void setImageDepthMax(int imageDepthMax)
void setFramesPerVolume(int framesPerVolume)
void setImagingMode(int imagingMode)
void setPostScanWidth(int postScanWidth)
void setImagingModeMin(int imagingModeMin)
void setMotorPositionMin(int motorPositionMin)
usMotorStep
For 4DC7 3D probe motor movement.
@ US_STATIC_MOTOR
motor not moving (2D case)
@ US_ANGLE_PITCH_1
2 motor steps per frame = 0.36585 degrees. Not working for 4DC7 probe !
@ US_ANGLE_PITCH_3
8 motor steps per frame = 1.4634 degrees
@ US_ANGLE_PITCH_5
8 motor steps per frame = 5.8536 degrees. Not working for 4DC7 probe !
@ US_ANGLE_PITCH_4
8 motor steps per frame = 2.9268 degrees. Not working for 4DC7 probe !
@ US_ANGLE_PITCH_2
4 motor steps per frame = 0.7317 degrees
void setSamplingFrequency(int samplingFrequency)
void setSamplingFrequencyMax(int samplingFrequencyMax)
void setTransmitFrequency(int transmitFrequency)
void setTransmitFrequencyMax(int transmitFrequencyMax)
void setSamplingFrequencyMin(int samplingFrequencyMin)
void setTransmitFrequencyMin(int transmitFrequencyMin)
void setPostScanMode(bool postScanMode)
void setImagingModeMax(int imagingModeMax)
void setActivateMotor(bool activateMotor)
void setMotorPositionMax(int motorPositionMax)
void setSepsPerFrameMin(usMotorStep anglePerFrameMin)
void setSepsPerFrameMax(usMotorStep anglePerFrameMax)
void setSepsPerFrame(usMotorStep anglePerFrame)
void setMotorPosition(int motorPosition)
usMotorStep getSepsPerFrame() const
void serverUpdated(bool sucess)
void setTransmitFrequency(int transmitFrequency)
usInitHeaderConfirmation m_confirmHeader
void sendAcquisitionParametersSignal()
void readAcquisitionParameters(QDataStream &stream)
void setFramesPerVolume(int framesPerVolume)
bool initAcquisition(const usNetworkGrabber::usInitHeaderSent &header)
void serverUpdateEnded(bool success)
us::usImageHeader m_imageHeader
void setIPAddress(const std::string &s_ip)
void setPostScanWidth(int postScanWidth)
void endBlockingLoop()
void setPostScanHeigh(int postScanHeigh)
usAcquisitionParameters::usMotorStep getStepsPerFrame()
void initAcquisitionSlot(usNetworkGrabber::usInitHeaderSent header)
void setImagingMode(int imagingMode)
void setSector(int sector)
void setPostScanMode(bool postScanMode)
QTcpSocket * m_tcpSocket
void handleError(QAbstractSocket::SocketError err)
usNetworkGrabber(QObject *parent=0)
void setImageDepth(int imageDepth)
void acquisitionInitialized(bool)
void runAcquisitionSignal(bool run)
void setSamplingFrequency(int samplingFrequency)
void sendRunSignal(bool run)
void setStepsPerFrame(usAcquisitionParameters::usMotorStep stepsPerFrame)
usAcquisitionParameters m_acquisitionParameters
void sendAcquisitionParametersSlot()
void setMotorActivation(bool activateMotor)
void setMotorPosition(int motorPosition)