4 #include <visp3/ustk_core/usConfig.h>
6 #if (defined(USTK_HAVE_QT5) || defined(USTK_HAVE_VTK_QT)) && (defined(VISP_HAVE_X11) || defined(VISP_HAVE_GDI)) && \
7 defined(VISP_HAVE_VIPER850)
9 #include <QApplication>
10 #include <QStringList>
11 #include <QtCore/QThread>
13 #include <visp3/ustk_grabber/usNetworkGrabberPreScan2D.h>
15 #include <visp3/ustk_confidence_map/usScanlineConfidence2D.h>
17 #include <visp3/gui/vpDisplayX.h>
18 #include <visp3/robot/vpRobotViper850.h>
22 vpMutex s_mutex_control_velocity;
23 vpColVector s_controlVelocity(6, 0.);
25 vpMutex s_mutex_capture;
26 typedef enum { capture_waiting, capture_started, capture_stopped } t_CaptureState;
27 t_CaptureState s_capture_state = capture_waiting;
30 vpThread::Return controlFunction(vpThread::Args args)
33 vpRobotViper850 robot;
40 vpHomogeneousMatrix eMs;
45 vpHomogeneousMatrix sMp;
48 vpHomogeneousMatrix sMe;
53 vpVelocityTwistMatrix sVe;
57 vpColVector sHs_star(6);
58 vpColVector pHp_star(6);
60 vpMatrix lambdaProportionnal(6, 6);
61 vpMatrix lambdaDerivate(6, 6);
62 vpMatrix lambdaIntegral(6, 6);
63 vpColVector sEs(6, 0);
64 vpColVector sEs_last(6, 0);
65 vpColVector sEs_sum(6, 0);
67 vpTranslationVector stg;
68 vpColVector sHs_bias(6);
78 lambdaProportionnal = 0;
79 for (
int i = 0; i < 3; i++)
80 lambdaProportionnal[i][i] = 0.015;
82 for (
int i = 3; i < 6; i++)
83 lambdaProportionnal[i][i] = 0;
86 for (
int i = 0; i < 3; i++)
87 lambdaDerivate[i][i] = 0.09;
89 for (
int i = 3; i < 6; i++)
90 lambdaDerivate[i][i] = 0;
93 for (
int i = 0; i < 3; i++)
94 lambdaIntegral[i][i] = 0;
96 for (
int i = 3; i < 6; i++)
97 lambdaIntegral[i][i] = 0;
115 gHg[2] = -(0.696 + 0.476) * 9.81;
122 vpHomogeneousMatrix eMp = eMs * sMp;
124 vpVelocityTwistMatrix eVp(eMp);
128 vpHomogeneousMatrix fMe;
129 vpHomogeneousMatrix fMs;
130 vpRotationMatrix sRf;
131 robot.getPosition(vpRobot::ARTICULAR_FRAME, q);
132 robot.get_fMe(q, fMe);
135 vpHomogeneousMatrix sMf;
141 vpForceTwistMatrix sFg(sMf);
143 for (
int i = 0; i < 3; i++)
144 for (
int j = 0; j < 3; j++)
145 sFg[i + 3][j] = (stg.skew() * sRf)[i][j];
149 vpForceTwistMatrix sFp(sMp);
152 std::cout <<
"\nBias the force/torque sensor...\n " << std::endl;
153 robot.biasForceTorqueSensor();
156 robot.setRobotState(vpRobot::STATE_VELOCITY_CONTROL);
158 unsigned int iter = 0;
159 t_CaptureState capture_state_;
162 unsigned int bufferSize = 80;
163 double signalBuffer[bufferSize];
164 for (
unsigned int i = 0; i < bufferSize; i++)
167 std::cout <<
"Starting control loop..." << std::endl;
168 double t0 = vpTime::measureTimeMs();
169 double deltaTmilliseconds = 1;
171 t0 = vpTime::measureTimeMs();
172 s_mutex_capture.lock();
173 capture_state_ = s_capture_state;
174 s_mutex_capture.unlock();
177 if (capture_state_ == capture_started) {
180 sHs = robot.getForceTorque();
187 robot.getPosition(vpRobot::ARTICULAR_FRAME, q);
188 robot.get_fMe(q, fMe);
198 for (
int i = 0; i < 3; i++)
199 for (
int j = 0; j < 3; j++)
200 sFg[i + 3][j] = (stg.skew() * sRf)[i][j];
203 sHs_bias = sHs - sFg * gHg;
209 vpMutex::vpScopedLock lock(s_mutex_control_velocity);
210 v_p = s_controlVelocity;
223 sEs = sFp * pHp_star - (sHs - sFg * gHg - sHs_bias);
226 signalBuffer[iter % bufferSize] = sEs[2];
230 unsigned int realBufferSize = iter + 1 < bufferSize ? iter + 1 : bufferSize;
231 for (
unsigned int i = 0; i < realBufferSize; i++) {
232 sum += signalBuffer[i];
234 sEs[2] = sum / realBufferSize;
245 lambdaProportionnal * sEs + lambdaDerivate * (sEs - sEs_last) / deltaTmilliseconds + lambdaIntegral * sEs_sum;
253 vpVelocityTwistMatrix eVs;
256 vpColVector v_e = eVs * v_s + eVp * v_p;
262 q_dot = eJe.pseudoInverse() * v_e;
265 robot.setVelocity(vpRobot::ARTICULAR_FRAME, q_dot);
269 vpTime::wait(t0, deltaTmilliseconds);
270 }
while (capture_state_ != capture_stopped);
272 std::cout <<
"End of control thread" << std::endl;
276 int main(
int argc,
char **argv)
279 QApplication app(argc, argv);
286 if (qApp->arguments().contains(QString(
"--probeID"))) {
287 header.
probeId = qApp->arguments().at(qApp->arguments().indexOf(QString(
"--probeID")) + 1).toInt();
291 if (qApp->arguments().contains(QString(
"--slotID"))) {
292 header.
slotId = qApp->arguments().at(qApp->arguments().indexOf(QString(
"--slotID")) + 1).toInt();
296 if (qApp->arguments().contains(QString(
"--imagingMode"))) {
297 header.
imagingMode = qApp->arguments().at(qApp->arguments().indexOf(QString(
"--imagingMode")) + 1).toInt();
307 double lambdaVisualError = 5;
311 vpDisplay *displayConf = NULL;
312 bool displayInit =
false;
317 bool captureRunning =
true;
328 vpThread thread_control((vpThread::Fn)controlFunction);
330 std::cout <<
"waiting ultrasound initialisation..." << std::endl;
334 grabbedFrame = qtGrabber->
acquire();
335 confidenceProcessor.
run(confidence, *grabbedFrame);
341 for (
unsigned int i = 0; i < confidence.getHeight(); ++i)
342 for (
unsigned int j = 0; j < confidence.getWidth(); ++j)
343 I_sum +=
static_cast<double>(confidence[i][j]);
346 for (
unsigned int x = 0; x < confidence.getHeight(); ++x)
347 for (
unsigned int y = 0; y < confidence.getWidth(); ++y) {
348 yc += y * confidence[x][y];
355 vpMutex::vpScopedLock lock(s_mutex_control_velocity);
356 s_controlVelocity = 0.0;
357 s_controlVelocity[5] = lambdaVisualError * tc;
360 s_mutex_capture.lock();
361 s_capture_state = capture_started;
362 s_mutex_capture.unlock();
367 if (!displayInit && grabbedFrame->getHeight() != 0 && grabbedFrame->getWidth() != 0) {
369 display =
new vpDisplayX(*grabbedFrame);
370 displayConf =
new vpDisplayX(confidence, (*grabbedFrame).getWidth() + 60, 10);
371 #elif defined(VISP_HAVE_GDI)
372 display =
new vpDisplayGDI(*grabbedFrame);
373 displayConf =
new vpDisplayGDI(confidence, (*grabbedFrame).getWidth() + 60, 10);
381 vpDisplay::display(*grabbedFrame);
382 vpDisplay::display(confidence);
385 vpDisplay::displayText(confidence, 10, 10,
"target", vpColor::green);
386 vpDisplay::displayLine(confidence, 0, confidence.getWidth() / 2 - 1, confidence.getHeight() - 1,
387 confidence.getWidth() / 2 - 1, vpColor::green);
390 vpDisplay::displayText(confidence, 25, 10,
"current", vpColor::red);
391 vpDisplay::displayLine(confidence, 0,
static_cast<int>(yc), confidence.getHeight() - 1,
static_cast<int>(yc),
393 if (vpDisplay::getClick(confidence,
false))
394 captureRunning =
false;
395 if (vpDisplay::getClick(*grabbedFrame,
false))
396 captureRunning =
false;
398 vpDisplay::flush(*grabbedFrame);
399 vpDisplay::flush(confidence);
402 }
while (captureRunning);
406 std::cout <<
"stop capture" << std::endl;
417 vpMutex::vpScopedLock lock(s_mutex_control_velocity);
418 s_controlVelocity = 0.0;
419 s_controlVelocity[5] = -0.05;
423 vpMutex::vpScopedLock lock(s_mutex_control_velocity);
424 s_controlVelocity = 0.0;
427 s_mutex_capture.lock();
428 s_capture_state = capture_stopped;
429 s_mutex_capture.unlock();
430 thread_control.join();
436 std::cout <<
"end main thread" << std::endl;
444 std::cout <<
"You should intall Qt5 (with wigdets and network modules), and display X to run this tutorial"
Class to store additionnal informations arriving on the network with ultrasound images grabbed,...
Specific class to grab pre-scan frames from the ultrasound station on the network.
usFrameGrabbedInfo< usImagePreScan2D< unsigned char > > * acquire()
void useVpDisplay(vpDisplay *display)
bool initAcquisition(const usNetworkGrabber::usInitHeaderSent &header)
bool sendAcquisitionParameters()
void setMotorPosition(int motorPosition)
Process a pre-scan image to determine the confidence map.
void run(usImagePreScan2D< unsigned char > &preScanConfidence, const usImagePreScan2D< unsigned char > &preScanImage)
double getFieldOfView() const
double getScanLinePitch() const