CustusX  2023.01.05-dev+develop.0da12
An IGT application
cxEBUSCalibrationWidget.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
11 
12 
14 
15 #include <QPushButton>
16 #include <QTextStream>
17 #include <QFileDialog>
18 #include <QMessageBox>
19 #include "cxTypeConversions.h"
20 #include "cxLogger.h"
21 #include "cxTrackingService.h"
22 #include "cxVector3D.h"
24 #include "cxTool.h"
25 #include "cxTrackingService.h"
26 #include <cxActiveToolWidget.h>
27 #include "cxDoubleWidgets.h"
28 #include "cxVisServices.h"
30 #include "cxSettings.h"
31 #include "cxTransformFile.h"
32 #include "cxFrame3D.h"
33 
34 namespace cx
35 {
36 
37 //------------------------------------------------------------------------------
39  BaseWidget(parent, "ebus_calibration_widget", "EBUS Calibrate"),
40  mServices(services),
41  mCalibrateButton(new QPushButton("Calibrate")),
42  mReferencePointLabel(new QLabel("Ref. point:")),
43  mCalibrationLabel(new QLabel("Calibration: \n")),
44  mDeltaLabel(new QLabel("Delta:"))
45 {
46  QVBoxLayout* toplayout = new QVBoxLayout(this);
47 
48  mCalibRefTool = StringPropertySelectTool::New(mServices->tracking());
49  mCalibRefTool->setValueName("Calibration Adapter");
50  mCalibRefTool->setHelp("Select Calibration Adapter sensor");
51 
52  mCalibratingTool = StringPropertySelectTool::New(mServices->tracking());
53  mCalibratingTool->setValueName("Tool");
54  mCalibratingTool->setHelp("Select which Tool to calibrate");
55 
56  // Adapter calibration matrix path
57  mAdapterCalibrationPath = settings()->value("EBUScalibration/path").toString();
58 
59  QLabel* adapterCalibrationPathLabel = new QLabel(tr("EBUS adapter calibration matrix path:"));
60  mAdapterCalibrationPathComboBox = new QComboBox();
61  mAdapterCalibrationPathComboBox->addItem(mAdapterCalibrationPath);
62  mAdapterCalibrationPathComboBox->setMaximumWidth(500);
63  QAction* browseAdapterCalibrationPathAction = new QAction(QIcon(":/icons/open.png"), tr("Browse for EBUS adapter calibration matrix..."), this);
64  connect(browseAdapterCalibrationPathAction, &QAction::triggered, this, &EBUSCalibrationWidget::browseAdapterCalibrationPathSlot);
65  QToolButton* browseAdapterCalibrationPathButton = new QToolButton(this);
66  browseAdapterCalibrationPathButton->setDefaultAction(browseAdapterCalibrationPathAction);
67 
68  QGridLayout* gridLayout = new QGridLayout();
69 
70  gridLayout->addWidget(adapterCalibrationPathLabel, 0, 0);
71  gridLayout->addWidget(mAdapterCalibrationPathComboBox, 1, 0);
72  gridLayout->addWidget(browseAdapterCalibrationPathButton, 1, 1);
73 
74  toplayout->addWidget(mReferencePointLabel);
75  toplayout->addWidget(new LabeledComboBoxWidget(this, mCalibRefTool));
76  toplayout->addWidget(new LabeledComboBoxWidget(this, mCalibratingTool));
77  toplayout->addLayout(gridLayout);
78  toplayout->addWidget(mCalibrateButton);
79  toplayout->addWidget(mCalibrationLabel);
80  toplayout->addWidget(this->createHorizontalLine());
81  toplayout->addStretch();
82 
83  mReferencePointLabel->setText("<b>EBUS calibration adapter - Use sensor on adapter as reference</b>");
84 
85  connect(mCalibrateButton, SIGNAL(clicked()), this, SLOT(calibrateSlot()));
86 
87  connect(mCalibRefTool.get(), SIGNAL(changed()), this, SLOT(toolSelectedSlot()));
88 
89  //setting default state
90  this->toolSelectedSlot();
91 
92  connect(mServices->tracking().get(), &cx::TrackingService::stateChanged, this, &EBUSCalibrationWidget::trackingStartedSlot);
93 }
94 
96 {}
97 
98 void EBUSCalibrationWidget::calibrateSlot()
99 {
100  ToolPtr refTool = mCalibRefTool->getTool();
101  ToolPtr tool = mCalibratingTool->getTool();
102  if(!refTool || !tool)
103  {
104  reportError(QString("Calibration prerequisited not met: calref:%1, tool:%2").arg(refTool!=0).arg(tool!=0) );
105  return;
106  }
107  if(!refTool->getVisible() || !tool->getVisible())
108  {
109  reportError(QString("Calibration prerequisited not met: calref vis:%1, tool vis :%2").arg(refTool->getVisible()).arg(tool->getVisible()) );
110  return;
111  }
112 
113  EBUSCalibrationCalculator calc(tool, refTool);
114  Transform3D adapterCalibration = readCalibrationFile(mAdapterCalibrationPath);
115  Transform3D calibration = calc.get_calibration_sMt(adapterCalibration);
116 
117  QMessageBox msgBox;
118  msgBox.setText("Do you want to overwrite "+tool->getName()+"'s calibration file?");
119  msgBox.setInformativeText("This cannot be undone.");
120  msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
121  msgBox.setDefaultButton(QMessageBox::Ok);
122  int ret = msgBox.exec();
123 
124  if(ret == QMessageBox::Ok)
125  {
126  try
127  {
128  tool->setCalibration_sMt(calibration);
129  }
130  catch(std::exception& e)
131  {
132  QMessageBox msgBox2;
133  msgBox2.setText("Unknown error, could not calibrate the tool: "+tool->getName()+".");
134  msgBox2.setInformativeText(QString(e.what()));
135  msgBox2.setStandardButtons(QMessageBox::Ok);
136  msgBox2.setDefaultButton(QMessageBox::Ok);
137  int ret2 = msgBox2.exec();
138  return;
139  }
140  mCalibrationLabel->setText(QString("Calibration matrix for %1:\n%2").arg(tool->getName(), qstring_cast(calibration)));
141  }
142 }
143 
144 void EBUSCalibrationWidget::toolSelectedSlot()
145 {
146  // QString text("Ref. point: <UNDEFINED POINT>");
147  mCalibrateButton->setEnabled(false);
148 
149  if (mCalibRefTool->getTool())
150  {
151 // mCalibrationLabel->setText("Calibration:\n" + qstring_cast(mCalibratingTool->getTool()->getCalibration_sMt()));
152 // Transform3D calibration = mCalibratingTool->getTool()->getCalibration_sMt();
153 // mCalibrationLabel->setText(QString("Calibration matrix for %1:\n%2").arg(tool->getName(), qstring_cast(calibration)));
154  mCalibrateButton->setEnabled(true);
155  }
156 
157  // mReferencePointLabel->setText(text);
158 }
159 
160 void EBUSCalibrationWidget::browseAdapterCalibrationPathSlot()
161 {
162  QFileInfo fileInfo(mAdapterCalibrationPath);
163  mAdapterCalibrationPath = QFileDialog::getOpenFileName(this, tr("Find adapter calibration matrix file"), fileInfo.absolutePath());
164 
165  settings()->setValue("EBUScalibration/path", mAdapterCalibrationPath);
166 
167  if(!mAdapterCalibrationPath.isEmpty())
168  {
169  mAdapterCalibrationPathComboBox->addItem( mAdapterCalibrationPath );
170  mAdapterCalibrationPathComboBox->setCurrentIndex( mAdapterCalibrationPathComboBox->currentIndex() + 1 );
171  }
172 }
173 
174 Transform3D EBUSCalibrationWidget::readCalibrationFile(QString absoluteFilePath)
175 {
176  bool ok = true;
177  TransformFile file(absoluteFilePath);
178  Transform3D retval = file.read(&ok);
179 
180  if (ok)
181  retval = Frame3D::create(retval).transform(); // clean rotational parts, transform should now be pure rotation+translation
182 
183  return retval;
184 }
185 
186 
187 //------------------------------------------------------------------------------
188 
189 void EBUSCalibrationWidget::trackingStartedSlot()
190 {
191  ToolPtr ref = mServices->tracking()->getTool("calibration_tool");
192  if (ref)
193  mCalibRefTool->setValue(ref->getUid());
194 }
195 
196 //------------------------------------------------------------------------------
197 //------------------------------------------------------------------------------
198 //------------------------------------------------------------------------------
199 
200 
201 
202 
204  mTool(tool), mCalibrationRef(calRef)
205 {
206  m_sMpr = mTool->getCalibration_sMt() * mTool->get_prMt().inv();
207 
208  m_qMcr = Transform3D::Identity();
209  m_qMpr = m_qMcr * mCalibrationRef->get_prMt().inv();
210 }
211 
213 {
214  Transform3D tool_prMs = mTool->get_prMt() * mTool->getCalibration_sMt().inverse();
215 
216  Transform3D calibration = tool_prMs.inverse() * adapterCalibration;
217 
218  return calibration;
219 }
220 
221 }
QString qstring_cast(const T &val)
void reportError(QString msg)
Definition: cxLogger.cpp:71
File format for storing a 4x4 matrix.The read/write methods emit error messages if you dont use the o...
Transform3D get_calibration_sMt(Transform3D adapterCalibration)
new calibration matrix for the input tool.
boost::shared_ptr< class VisServices > VisServicesPtr
Definition: cxMainWindow.h:40
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
Transform3D transform() const
Definition: cxFrame3D.cpp:140
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
Definition: cxSettings.cpp:66
Composite widget for string selection.
Transform3D read(bool *ok=0)
void setValue(const QString &key, const QVariant &value)
Definition: cxSettings.cpp:58
EBUSCalibrationWidget(VisServicesPtr services, QWidget *parent)
static QFrame * createHorizontalLine()
Creates a horizontal line which can be inserted into widgets.
static Frame3D create(const Transform3D &transform)
Definition: cxFrame3D.cpp:128
Settings * settings()
Shortcut for accessing the settings instance.
Definition: cxSettings.cpp:21
Interface for QWidget which handles widgets uniformly for the system.
Definition: cxBaseWidget.h:88
static StringPropertySelectToolPtr New(TrackingServicePtr trackingService)
EBUSCalibrationCalculator(ToolPtr tool, ToolPtr calRef)
Namespace for all CustusX production code.
boost::shared_ptr< class Tool > ToolPtr