iCub-main
calibrationwindow.cpp
Go to the documentation of this file.
1 #include "calibrationwindow.h"
2 #include "ui_calibrationwindow.h"
3 #include <qdebug.h>
4 #include <QLabel>
5 #include <QHBoxLayout>
6 #include <QtConcurrent/QtConcurrent>
7 #include <QFileDialog>
8 #include <QMessageBox>
9 #include <strain.h>
10 
11 #define CHANNEL_COUNT 6
12 #define HEX_VALC 0x8000
13 #define RANGE32K 32768
14 
15 #define COL_CURRMEASURE 0
16 
17 #define COL_GAIN 0
18 #define COL_OFFSET 1
19 #define COL_TARGET 2
20 #define COL_REGISTERS 3
21 
22 #define COL_CALIBBIAS 0
23 
24 #define COL_FULLSCALE 0
25 
26 #define COL_MAXMEASURE 0
27 #define COL_MINMEASURE 1
28 #define COL_DIFFMEASURE 2
29 #define COL_NEWTONMEASURE 3
30 
31 #define MATRIX_COUNT 1
32 
33 
34 using namespace strain::dsp;
35 
36 int convert_to_signed32k(unsigned int v)
37 {
38  return static_cast<int>(v)-32768; // it is the 0x8000 used in q15 transformation
39 }
40 
41 int showasQ15(int v)
42 {
43  return static_cast<std::int16_t>(v&0xffff);
44 }
45 
46 // bias, tare, offset. in here we mean what we add to the six values before or after matyrix multiplication.
47 int showBias(unsigned int v)
48 {
49  // marco.accame:
50  // the gui has always shown the value at it is.
51  // it should however show the value w/ showasQ15()
52  return v;
53 }
54 
55 
56 
57 unsigned int q15_from(int v)
58 {
59  return v+0x8000;
60 }
61 
62 const strain2_ampl_discretegain_t CalibrationWindow::defaultStrain2AmplGains[6] =
63 {
65 };
66 
67 const uint16_t CalibrationWindow::defaultStrain2AmplOffsets[6] =
68 {
69  32767, 32767, 32767, 32767, 32767, 32767
70 };
71 
72 const uint16_t CalibrationWindow::defaultStrain1DACoffsets[6] =
73 {
74  511, 511, 511, 511, 511, 511
75 };
76 
77 
78 CalibrationWindow::CalibrationWindow(FirmwareUpdaterCore *core, icubCanProto_boardType_t b, CustomTreeWidgetItem *item, QWidget *parent) :
79  QMainWindow(parent),mutex(QMutex::Recursive),
80  ui(new Ui::CalibrationWindow)
81 {
82  ui->setupUi(this);
83  setWindowModality(Qt::ApplicationModal);
84 
85  this->core = core;
86  this->selected = item->getIndexOfBoard();
87  this->item = item;
88  bus = ((CustomTreeWidgetItem*)item->getParentNode())->getCanBoard(selected).bus;
89  id = ((CustomTreeWidgetItem*)item->getParentNode())->getCanBoard(selected).pid;
90  calibration_value = 32767;
91 #if defined(MARCO_ACCAME_19SEP2018)
92  calib_const[0] = 1;
93  calib_const[1] = 1;
94  calib_const[2] = 1;
95 #else
96  calib_const[0] = 0;
97  calib_const[1] = 0;
98  calib_const[2] = 0;
99 #endif
100  serial_number_changed = false;
101  matrix_changed[0] = false;
102  matrix_changed[1] = false;
103  matrix_changed[2] = false;
104  fullScaleChanged = false;
105 
106  boardtype = b; // we can have either a icubCanProto_boardType__strain or a icubCanProto_boardType__strain2 ...
107  eeprom_saved_status=true;
108  first_time = true;
109  refresh_serialnumber = true;
110  clearStats = false;
111  for(int i=0;i<CHANNEL_COUNT;i++){
112  ch[i] = i;
113  adc[i] = 0;
114  calib_bias[i] = 0;
115  curr_bias[i] = 0;
116  // marco.accame: we want to show the maximum / minimum values in the same way the adc values are displayed: in range [-32k, +32k)
117  maxadc[i] = -32768;
118  minadc[i] = +32767;
119 
120  maxft[i] = -32768;
121  minft[i] = +32767;
122 
123  offsetSliderPressed[i] = false;
124  amp_gain1[i] = 0;
125  amp_gain2[i] = 0;
126  }
127  strncpy(serial_no,"UNDEF",8);
128 
129  for(int m=0;m<MATRIX_COUNT;m++){
130  for(int i=0;i<CHANNEL_COUNT;i++){
131  full_scale_const[m][i] = 0;
132  }
133  }
134 
135  if(icubCanProto_boardType__strain == boardtype){
136  ui->tableParamters->hideColumn(COL_GAIN);
137  }
138 
139 
140 
141  for (int i=0;i <CHANNEL_COUNT;i++) {
142  QWidget *container = new QWidget(ui->tableParamters);
143  /*****************************************************/
144  CustomSpinBox *spinner = new CustomSpinBox(boardtype,container);
145  slider_offset.append(spinner);
146 
147  ui->tableParamters->setCellWidget(i,COL_OFFSET,spinner);
148  ui->tableParamters->cellWidget(i,COL_OFFSET)->setEnabled(false);
149 
150  CustomComboBox *gainCombo = new CustomComboBox(container);
151 
152  ui->tableParamters->setCellWidget(i,COL_GAIN,gainCombo);
153  ui->tableParamters->cellWidget(i,COL_GAIN)->setEnabled(false);
154 
155  /*****************************************************/
156 
157  QSpinBox *spinnerTarget = new QSpinBox(container);
158  spinnerTarget->setMinimum(0);
159  spinnerTarget->setMaximum(32767);
160  spinnerTarget->setMinimum(-32768);
161  spinnerTarget->setValue(0);
162  ui->tableParamters->setCellWidget(i,COL_TARGET,spinnerTarget);
163 
164  if(icubCanProto_boardType__strain == boardtype && i > 0){
165  spinnerTarget->setEnabled(false);
166  } else if(icubCanProto_boardType__strain == boardtype && i == 0){
167  connect(spinnerTarget,SIGNAL(valueChanged(int)),this,SLOT(onTargetValueChanged(int)));
168  }
169 
170 
171 
172  /*****************************************************/
173 
174  QTableWidgetItem *item = new QTableWidgetItem("-");
175  item->setFlags(item->flags() ^ Qt::ItemIsEditable);
176  ui->tableCurr->setItem(i,COL_CURRMEASURE,item);
177 
178  ui->tableCurr->setHorizontalHeaderItem(0, new QTableWidgetItem("ADC"));
179 
180 
181  QTableWidgetItem *item1 = new QTableWidgetItem("-");
182  item1->setFlags(item1->flags() ^ Qt::ItemIsEditable);
183  ui->tableUseMatrix->setItem(i,COL_MAXMEASURE,item1);
184 
185 
186  QTableWidgetItem *item2 = new QTableWidgetItem("-");
187  item2->setFlags(item2->flags() ^ Qt::ItemIsEditable);
188  ui->tableUseMatrix->setItem(i,COL_MINMEASURE,item2);
189 
190 
191  QTableWidgetItem *item3 = new QTableWidgetItem("-");
192  item3->setFlags(item3->flags() ^ Qt::ItemIsEditable);
193  ui->tableUseMatrix->setItem(i,COL_DIFFMEASURE,item3);
194 
195 
196  QTableWidgetItem *item4 = new QTableWidgetItem("-");
197  item4->setFlags(item4->flags() ^ Qt::ItemIsEditable);
198  ui->tableUseMatrix->setItem(i,COL_NEWTONMEASURE,item4);
199 
200  for(int j=0;j<CHANNEL_COUNT;j++){
201  QTableWidgetItem *item = new QTableWidgetItem("-");
202  item->setFlags(item->flags() ^ Qt::ItemIsEditable);
203  ui->matrixA->setItem(i,j,item);
204 
205 
206 // QTableWidgetItem *item1 = new QTableWidgetItem("-");
207 // ui->matrixB->setItem(i,j,item1);
208 
209 // QTableWidgetItem *item2 = new QTableWidgetItem("-");
210 // ui->matrixC->setItem(i,j,item2);
211  }
212 
213 
214  QTableWidgetItem *item001 = new QTableWidgetItem("-");
215  item001->setFlags(item001->flags() ^ Qt::ItemIsEditable);
216  ui->tableParamters->setItem(i,COL_GAIN,item001);
217 
218 
219  QTableWidgetItem *item5 = new QTableWidgetItem("-");
220  item5->setFlags(item5->flags() ^ Qt::ItemIsEditable);
221  ui->tableParamters->setItem(i,COL_TARGET,item5);
222 
223 
224 // QTableWidgetItem *item6 = new QTableWidgetItem("-");
225 // item6->setFlags(item6->flags() ^ Qt::ItemIsEditable);
226 // ui->tableParamters->setItem(i,COL_CURRBIAS,item6);
227 
228  QTableWidgetItem *item6 = new QTableWidgetItem("-");
229  item6->setFlags(item6->flags() ^ Qt::ItemIsEditable);
230  ui->tableBias->setItem(i,COL_CALIBBIAS,item6);
231 
232  QTableWidgetItem *item7 = new QTableWidgetItem("-");
233  item7->setFlags(item7->flags() ^ Qt::ItemIsEditable);
234  ui->tableFullScaleA->setItem(i,COL_FULLSCALE,item7);
235 
236 // QTableWidgetItem *item8 = new QTableWidgetItem("-");
237 // item8->setFlags(item8->flags() ^ Qt::ItemIsEditable);
238 // ui->tableFullScaleB->setItem(i,COL_FULLSCALE,item8);
239 
240 // QTableWidgetItem *item9 = new QTableWidgetItem("-");
241 // item9->setFlags(item9->flags() ^ Qt::ItemIsEditable);
242 // ui->tableFullScaleC->setItem(i,COL_FULLSCALE,item9);
243 
244  fullScales.append(ui->tableFullScaleA);
245 // fullScales.append(ui->tableFullScaleB);
246 // fullScales.append(ui->tableFullScaleC);
247 
248  }
249 
250  ui->tableParamters->setColumnWidth(COL_OFFSET,150);
251  //ui->tableUseMatrix->hideColumn(COL_NEWTONMEASURE);
252 
253 
254 
255  progress = new QProgressBar(this);
256  progress->setFixedWidth(100);
257  progress->setMinimum(0);
258  progress->setMaximum(100);
259  progress->setVisible(false);
260  ui->statusbar->addWidget(progress);
261 
262 // matrixGain.append(ui->editMatrixGainA);
263 // matrixGain.append(ui->editMatrixGainB);
264 // matrixGain.append(ui->editMatrixGainC);
265 
266  matrices.append(ui->matrixA);
267 // matrices.append(ui->matrixB);
268 // matrices.append(ui->matrixC);
269 
270  if(boardtype == icubCanProto_boardType__strain){
271  ui->comboRegSet->setEnabled(false);
272  ui->comboRegSetBoot->setEnabled(false);
273  }
274 
275 
276  //connect(ui->comboUseMatrix,SIGNAL(currentIndexChanged(int)),this,SLOT(onUseMatrixChanged(int)),Qt::QueuedConnection);
277  connect(ui->comboRegSet,SIGNAL(currentIndexChanged(int)),this,SLOT(onChangeRegSet(int)));
278  connect(ui->comboRegSetBoot,SIGNAL(currentIndexChanged(int)),this,SLOT(onChangeRegSetBoot(int)));
279  connect(this,SIGNAL(applyDone()),this,SLOT(onApplyDone()));
280  connect(ui->btnClose,SIGNAL(clicked(bool)),this,SLOT(close()));
281  connect(ui->edit_serial,SIGNAL(textEdited(QString)),this,SLOT(onSerialChanged(QString)));
282  connect(this,SIGNAL(loading(bool)),this,SLOT(onLoading(bool)),Qt::QueuedConnection);
283  connect(this,SIGNAL(setText(QLineEdit*,QString)),this,SLOT(onSetText(QLineEdit*,QString)),Qt::QueuedConnection);
284  connect(this,SIGNAL(setText(QTableWidgetItem*,QString)),this,SLOT(onSetText(QTableWidgetItem*,QString)),Qt::QueuedConnection);
285  connect(this,SIGNAL(setTableVisible(QTableWidget*,bool)),this,SLOT(onSetTableVisible(QTableWidget*,bool)),Qt::QueuedConnection);
286  connect(this,SIGNAL(setOffsetSliderValue(CustomSpinBox*,int)),this,SLOT(onOffsetSpinnerValue(CustomSpinBox*,int)),Qt::BlockingQueuedConnection);
287 
288  connect(ui->btnParametersClear,SIGNAL(clicked(bool)),this,SLOT(onParametersClear(bool)));
289  connect(ui->btnParametersApply,SIGNAL(clicked(bool)),this,SLOT(onParametersApply(bool)));
290  connect(ui->checkAutoTune,SIGNAL(toggled(bool)),this,SLOT(onCheckAutoTune(bool)));
291  connect(ui->btnSetCalibBias,SIGNAL(clicked(bool)),this,SLOT(onSetCalibBias(bool)));
292  connect(ui->btnResetCalibBias,SIGNAL(clicked(bool)),this,SLOT(onResetCalibBias(bool)));
293 
294  connect(ui->btnSetSerial,SIGNAL(clicked(bool)),this,SLOT(onSetSerial(bool)),Qt::QueuedConnection);
295  connect(this,SIGNAL(setSerialChanged(bool)),this,SLOT(onSetSerialChanged(bool)));
296  //connect(ui->btnResetCalib,SIGNAL(clicked(bool)),this,SLOT(onResetCalibMatrix(bool)),Qt::QueuedConnection);
297  connect(this,SIGNAL(setFullScale()),this,SLOT(onSetFullScale()),Qt::QueuedConnection);
298  connect(this,SIGNAL(setMatrix(int)),this,SLOT(onSetMatrix(int)),Qt::QueuedConnection);
299  connect(ui->actionSave_To_Eproom,SIGNAL(triggered(bool)),this,SLOT(onSaveToEeprom(bool)),Qt::QueuedConnection);
300  connect(ui->actionClear_Statistics,SIGNAL(triggered(bool)),this,SLOT(onClear_Statistics(bool)),Qt::QueuedConnection);
301  connect(ui->actionClear_the_full_regulation,SIGNAL(triggered(bool)),this,SLOT(onClear_FullRegulation(bool)),Qt::QueuedConnection);
302  connect(ui->actionClear_the_regulation_set_in_use,SIGNAL(triggered(bool)),this,SLOT(onClear_Regulation(bool)),Qt::QueuedConnection);
303  connect(ui->btnSetCalibration,SIGNAL(clicked(bool)),this,SLOT(onSetCalibration(bool)),Qt::QueuedConnection);
304  connect(this,SIGNAL(resetMatrices(int)),this,SLOT(resetMatricesState(int)),Qt::QueuedConnection);
305  connect(this,SIGNAL(updateTitle()),this,SLOT(onUpdateTitle()),Qt::QueuedConnection);
306  connect(this,SIGNAL(appendLogMsg(QString)),this,SLOT(onAppendLogMsg(QString)),Qt::QueuedConnection);
307  connect(ui->btnClearLog,SIGNAL(clicked(bool)),this,SLOT(onClearLog()));
308  connect(ui->btnLoadCalibFile,SIGNAL(clicked(bool)),this,SLOT(onLoadCalibrationFile(bool)));
309  connect(ui->btnSaveCalibFile,SIGNAL(clicked(bool)),this,SLOT(onSaveCalibrationFile(bool)));
310  connect(ui->btnImportCalibMatrix,SIGNAL(clicked(bool)),this,SLOT(onImportCalibrationFile(bool)));
311  //connect(ui->checkDigital,SIGNAL(toggled(bool)),this,SLOT(onDigitalRegulation(bool)));
312 
313 
314  ui->actionImport_Calib_Matrix->setEnabled(false);
315  ui->actionLoad_Calibration_File->setEnabled(false);
316  ui->actionSave_Calibration_File->setEnabled(false);
317  // timer = new QTimer();
318  // timer->setInterval(500);
319  // timer->setSingleShot(false);
320  // connect(timer,SIGNAL(timeout()),this,SLOT(onTimeout()),Qt::DirectConnection);
321  // timer->start();
322 
323  QtConcurrent::run(this,&CalibrationWindow::onTimeout);
324 
325 }
326 
328 {
329  // timer->stop();
330  // delete timer;
331 
332  mutex.lock();
333  keepRunning = false;
334  delete ui;
335  mutex.unlock();
336 }
337 
338 void CalibrationWindow::onTargetValueChanged(int v)
339 {
340 
341 
342  if(boardtype == icubCanProto_boardType__strain){
343  for(int i=1;i<CHANNEL_COUNT;i++){
344  QSpinBox *spinnerTarget = (QSpinBox*)ui->tableParamters->cellWidget(i,COL_TARGET);
345  spinnerTarget->setValue(v);
346  }
347 
348  }
349 }
350 
351 void CalibrationWindow::onChangeRegSet(int regSet)
352 {
353  QtConcurrent::run(this,&CalibrationWindow::useMatrix,regSet,false);
354 }
355 
356 void CalibrationWindow::onChangeRegSetBoot(int regSet)
357 {
358  QtConcurrent::run(this,&CalibrationWindow::useMatrix,regSet,true);
359 }
360 
361 
362 void CalibrationWindow::onDigitalRegulation(bool checked)
363 {
364  ui->digitalContainer->setEnabled(checked);
365  if(checked){
366  ui->tableUseMatrix->horizontalHeaderItem(COL_NEWTONMEASURE)->setText("FT");
367 // ui->tableUseMatrix->showColumn(COL_NEWTONMEASURE);
368 // ui->tableUseMatrix->setColumnWidth(0,60);
369 // ui->tableUseMatrix->setColumnWidth(1,60);
370 // ui->tableUseMatrix->setColumnWidth(2,60);
371  }else{
372  //ui->tableUseMatrix->hideColumn(COL_NEWTONMEASURE);
373  ui->tableUseMatrix->horizontalHeaderItem(COL_NEWTONMEASURE)->setText("Empty");
374 
375  }
376 
377 }
378 void CalibrationWindow::onCheckAutoTune(bool checked)
379 {
380  if(checked){
381  for(int i=0; i<CHANNEL_COUNT;i++){
382  if(icubCanProto_boardType__strain == boardtype){
383  if(i == 0){
384  ui->tableParamters->cellWidget(i,COL_TARGET)->setEnabled(true);
385  }
386  } else {
387  ui->tableParamters->cellWidget(i,COL_TARGET)->setEnabled(true);
388  }
389  ui->tableParamters->cellWidget(i,COL_OFFSET)->setEnabled(false);
390  ui->tableParamters->cellWidget(i,COL_GAIN)->setEnabled(false);
391  }
392  } else {
393  for(int i=0; i<CHANNEL_COUNT;i++){
394  ui->tableParamters->cellWidget(i,COL_TARGET)->setEnabled(false);
395  ui->tableParamters->cellWidget(i,COL_OFFSET)->setEnabled(true);
396  ui->tableParamters->cellWidget(i,COL_GAIN)->setEnabled(true);
397  }
398  }
399 }
400 
401 void CalibrationWindow::onParametersClear(bool click)
402 {
403 
404  for(int i=0; i<CHANNEL_COUNT;i++){
405  CustomComboBox *combo = ((CustomComboBox*)ui->tableParamters->cellWidget(i,COL_GAIN));
406 
407  if(icubCanProto_boardType__strain2 == boardtype || icubCanProto_boardType__strain2c == boardtype)
408  {
409  combo->setIndexFromAmpGain(defaultStrain2AmplGains[i]);
410  ((CustomSpinBox*)ui->tableParamters->cellWidget(i,COL_OFFSET))->setValue(defaultStrain2AmplOffsets[i]);
411  }
412  else
413  {
414  ((CustomSpinBox*)ui->tableParamters->cellWidget(i,COL_OFFSET))->setValue(defaultStrain1DACoffsets[i]);
415  }
416 
417  }
418 }
419 
420 void CalibrationWindow::onParametersApply(bool click)
421 {
422  if(ui->checkAutoTune->isChecked()){
423  QtConcurrent::run(this,&CalibrationWindow::autoAdjust);
424  } else {
425  QtConcurrent::run(this,&CalibrationWindow::applyParameters);
426  }
427 }
428 
429 void CalibrationWindow::onOffsetEditingFinished()
430 {
431  qDebug() << "EDIT FINISH FOR " << sender();
432 }
433 
434 void CalibrationWindow::onTabMatrixCahnged(int index)
435 {
436  // This will be removed in the future
437  switch (index) {
438  case 0:
439  ui->btnLoadCalibFile->setEnabled(true);
440  ui->btnSaveCalibFile->setEnabled(true);
441  ui->btnImportCalibMatrix->setEnabled(true);
442  //ui->btnResetCalib->setEnabled(true);
443  ui->btnSetCalibration->setEnabled(true);
444  break;
445  default:
446  ui->btnLoadCalibFile->setEnabled(false);
447  ui->btnSaveCalibFile->setEnabled(false);
448  ui->btnImportCalibMatrix->setEnabled(false);
449  //ui->btnResetCalib->setEnabled(false);
450  ui->btnSetCalibration->setEnabled(false);
451  break;
452  }
453 
454 }
455 
456 void CalibrationWindow::onOffsetSliderPressed()
457 {
458  int index = slider_offset.indexOf((CustomSpinBox*)sender());
459  offsetSliderPressed[index] = true;
460 }
461 
462 void CalibrationWindow::onOffsetSliderReleased()
463 {
464  int index = slider_offset.indexOf((CustomSpinBox*)sender());
465 
466  QtConcurrent::run(this,&CalibrationWindow::setOffset,index,((CustomSpinBox*)sender())->value());
467 
468  offsetSliderPressed[index] = false;
469 
470 }
471 
473 {
474  mutex.lock();
475  loading();
476  string msg;
477  core->getDownloader()->strain_set_calib_bias(bus,id,&msg);
478  appendLogMsg(msg.c_str());
479  loading(false);
480  mutex.unlock();
481 }
482 
484 {
485  mutex.lock();
486  loading();
487  string msg;
488  core->getDownloader()->strain_reset_calib_bias(bus,id,&msg);
489  appendLogMsg(msg.c_str());
490  loading(false);
491  mutex.unlock();
492 }
493 
495 {
496  mutex.lock();
497  loading();
498  string msg;
499  core->getDownloader()->strain_reset_curr_bias(bus,id,&msg);
500  appendLogMsg(msg.c_str());
501  loading(false);
502  mutex.unlock();
503 }
504 
506 {
507  mutex.lock();
508  loading();
509  string msg;
510  core->getDownloader()->strain_set_curr_bias(bus,id,&msg);
511  appendLogMsg(msg.c_str());
512  loading(false);
513  mutex.unlock();
514 }
515 
517 {
518  mutex.lock();
519  loading();
520  string msg;
521 
522 
523  std::vector<strain2_ampl_discretegain_t> gains(0);
524  std::vector<int16_t> targets(0);
525  if(icubCanProto_boardType__strain == boardtype)
526  {
527  CustomSpinBox *spin = (CustomSpinBox*)ui->tableParamters->cellWidget(0,COL_TARGET);
528  std::int16_t target = spin->value();
529  gains.resize(0);
530  targets.push_back(target);
531  }
532  else
533  {
534  for(int i=0;i<CHANNEL_COUNT;i++)
535  {
536  QComboBox *combo = (QComboBox*)ui->tableParamters->cellWidget(i,COL_GAIN);
537  CustomSpinBox *spin = (CustomSpinBox*)ui->tableParamters->cellWidget(i,COL_TARGET);
538  gains.push_back(static_cast<strain2_ampl_discretegain_t>(combo->itemData(combo->currentIndex(),GAINAMPROLE).toInt()));
539  targets.push_back(spin->value());
540  }
541 
542  }
543  core->getDownloader()->set_external_logger(this, logger);
544  core->getDownloader()->strain_calibrate_offset2(bus, id, boardtype, gains, targets, &msg);
545  core->getDownloader()->set_external_logger(NULL, NULL);
546 
547  loading(false);
548  applyDone();
549  mutex.unlock();
550 }
551 
553 {
554  mutex.lock();
555  loading();
556  string msg;
557 
558  for(int i=0;i<CHANNEL_COUNT;i++)
559  {
560  QComboBox *combo = (QComboBox*)ui->tableParamters->cellWidget(i,COL_GAIN);
561  CustomSpinBox *spin = (CustomSpinBox*)ui->tableParamters->cellWidget(i,COL_OFFSET);
562 
563  if(icubCanProto_boardType__strain2 == boardtype || icubCanProto_boardType__strain2c == boardtype)
564  {
565  int lastOffset = spin->value();
566  uint16_t offset = lastOffset; // 32*1024 - 1;
567  int g = combo->itemData(combo->currentIndex(),GAINAMPROLE).toInt();
569  float gain = core->getDownloader()->strain_amplifier_discretegain2float(dg);
570  if(0 != gain){
572  }
573  }
574  else
575  {
576  int lastOffset = spin->value();
577  uint16_t offset = lastOffset;
579  }
580  }
581  //connect(this,SIGNAL(setOffsetSliderValue(CustomSpinBox*,int)),this,SLOT(onOffsetSliderValue(CustomSpinBox*,int)),Qt::BlockingQueuedConnection);
582  loading(false);
583  applyDone();
584  mutex.unlock();
585 }
586 
587 
589 {
590  mutex.lock();
591  loading();
592  string msg;
593 
594 
595  core->getDownloader()->strain_set_serial_number(bus,id,ui->edit_serial->text().toLatin1().data(),&msg);
596  appendLogMsg(msg.c_str());
597  serial_number_changed = false;
598  loading(false);
599  mutex.unlock();
600 }
601 
603 {
604  mutex.lock();
605  loading();
606  drv_sleep (1000);
607  string msg;
608  core->getDownloader()->strain_save_to_eeprom(bus,id,&msg);
609  appendLogMsg(msg.c_str());
610  drv_sleep (1000);
611  //resetMatrices();
612  loading(false);
613  mutex.unlock();
614 }
615 
617 {
618  mutex.lock();
619  clearStats = true;
620  mutex.unlock();
621 }
622 
624 {
625  mutex.lock();
626 
627  const bool alsoserialnumber = true;
628  if((icubCanProto_boardType__strain2 == boardtype) || (icubCanProto_boardType__strain2c == boardtype))
629  {
633  useMatrix(0, true);
634  useMatrix(0, false);
635  }
636  else
637  {
639  }
640 
641  refresh_serialnumber = alsoserialnumber;
642 
643  mutex.unlock();
644 }
645 
647 {
648  mutex.lock();
649 
650  const bool alsoserialnumber = false;
652  refresh_serialnumber = alsoserialnumber;
653 
654  mutex.unlock();
655 }
656 
657 
658 void CalibrationWindow::resetMatricesState(int index)
659 {
660 
661  for(int i=0;i<MATRIX_COUNT;i++){
662  matrix_changed[i] = false;
663  if(index >=0){
664  if(i != index){
665  continue;
666  }
667  }
668  QTableWidget *table = matrices.at(i);
669  //QLineEdit *gain = matrixGain.at(i);
670 
671  //disconnect(table,SIGNAL(itemChanged(QTableWidgetItem*)), this,SLOT( onMatrixChanged(QTableWidgetItem*)));
672  for(int r=0;r<CHANNEL_COUNT;r++){
673  for(int c=0;c<CHANNEL_COUNT;c++){
674  table->item(r,c)->setTextColor("");
675  }
676  }
677  //connect(table,SIGNAL(itemChanged(QTableWidgetItem*)), this,SLOT( onMatrixChanged(QTableWidgetItem*)),Qt::UniqueConnection);
678  //gain->setStyleSheet("");
679  }
680 }
681 
683 {
684  mutex.lock();
685  loading();
686 
687  int index = 0;
688  //QTableWidget *table = matrices.at(index);
689 
690  // marco.accame: the regulation set to be sent to the board is the one in use in its inside
691 
692 
693  if(matrix_changed[0]){
694  for (int ri=0; ri<CHANNEL_COUNT; ri++){
695  for (int ci=0; ci<CHANNEL_COUNT; ci++){
696  string msg;
697  core->getDownloader()->strain_set_matrix_rc(bus,id,ri,ci,calib_matrix[index][ri][ci], cDownloader::strain_regset_inuse, &msg);
698  appendLogMsg(msg.c_str());
699  }
700  }
701  }
702 
703 
704  if(fullScaleChanged){
705  for (int i=0;i<CHANNEL_COUNT; i++){
706  string msg;
707  core->getDownloader()->strain_set_full_scale(bus,id,i,full_scale_calib[index][i], cDownloader::strain_regset_inuse, &msg);
708  appendLogMsg(msg.c_str());
709  }
710  }
711 
712 // string msg;
713 // core->getDownloader()->strain_set_matrix_gain(bus,id,calib_const[index], regset, &msg);
714 // appendLogMsg(msg.c_str());
715 
716 
717 
718  int ri=0;
719  int ci=0;
720 
721  drv_sleep (1000);
722  for (ri=0;ri<CHANNEL_COUNT;ri++){
723  for (ci=0;ci<CHANNEL_COUNT;ci++){
724  string msg;
725  core->getDownloader()->strain_get_matrix_rc(bus,id,ri,ci,matrix[index][ri][ci], cDownloader::strain_regset_inuse, &msg);
726  appendLogMsg(msg.c_str());
727  }
728  }
729  setMatrix(index);
730  setFullScale();
731  //resetMatrices(index);
732 
733 // int count_ok=0;
734 // for (int i=0;i<36; i++){
735 // ri=i/6;
736 // ci=i%6;
737 // if (calib_matrix[index][ri][ci]==matrix[index][ri][ci]) {
738 // count_ok++;
739 // } else {
740 // printf ("Found 1 error on element %d,%d !!\n",ri, ci);
741 // appendLogMsg("Found 1 error on element %d,%d !!");
742 // }
743 // }
744 
745 // if (count_ok==36){
746 // printf ("Calibration file applied with no errors\n");
747 // appendLogMsg(QString("Calibration file applied with no errors"));
748 // matrix_changed[0]=false;
749 // } else {
750 // printf ("Found %d errors applying the calibration file!!\n",36-count_ok);
751 // appendLogMsg(QString("Found %1 errors applying the calibration file!!").arg(36-count_ok));
752 // }
753 
754  printf ("Calibration file applied with no errors\n");
755  appendLogMsg(QString("Calibration file applied with no errors"));
756  matrix_changed[0]=false;
757  fullScaleChanged = false;
758  loading(false);
759  mutex.unlock();
760 }
761 
763 {
764  // marco.accame: the regulation set to be sent to the board is the one in use in its inside
765 
766  mutex.lock();
767  int index = 0;//ui->tabWidget->currentIndex();
768  loading();
769  //load data file
770  if(!calibration_load_v3 (fileName.toLatin1().data(), bus, id, index, cDownloader::strain_regset_inuse)){
771  loading(false);
772  mutex.unlock();
773  }
774 
775  //update windows graphics
776  int i=0;
777  int ri=0;
778  int ci=0;
779  string msg;
780  char buffer[256];
781 
782  drv_sleep (500);
783  core->getDownloader()->strain_get_serial_number(bus,id, buffer, &msg);
784 
785  setText(ui->edit_serial,QString(buffer));
786  serial_number_changed=false;
787 
788  drv_sleep (500);
789  for (ri=0;ri<CHANNEL_COUNT;ri++){
790  for (ci=0;ci<CHANNEL_COUNT;ci++){
791  core->getDownloader()->strain_get_matrix_rc(bus,id, ri, ci, matrix[index][ri][ci], cDownloader::strain_regset_inuse, &msg);
792  appendLogMsg(msg.c_str());
793  sprintf(buffer,"%x",matrix[index - 1][ri][ci]);
794  setMatrix(index);
795  //resetMatrices(index);
796  }
797  }
798 
799 
800  drv_sleep (500);
801 
802  int count_ok=0;
803  for (i=0;i<36; i++){
804  ri=i/6;
805  ci=i%6;
806  if (calib_matrix[index][ri][ci]==matrix[index][ri][ci]){
807  count_ok++;
808  } else {
809  QString s = QString("Found 1 error on element %1,%2 !!").arg(ri).arg(ci);
810  appendLogMsg(s);
811  }
812  }
813 
814  if (count_ok==36){
815  QString s = QString("Calibration file applied with no errors");
816  appendLogMsg(s);
817  matrix_changed[index]=false;
818  } else {
819  QString s = QString("Found %1 errors applying the calibration file!!").arg(36-count_ok);
820  appendLogMsg(s);
821  }
822 
823 
824 
825 
826  fullScaleChanged = false;
827  loading(false);
828  mutex.unlock();
829 
830 }
831 
832 void CalibrationWindow::onLoadCalibrationFile(bool click)
833 {
834  QString filename = QFileDialog::getOpenFileName(this,"Choose File",QDir::home().absolutePath(),"dat(*.dat)");
835 
836  if(filename.isEmpty()){
837  return;
838  }
839 
840  QtConcurrent::run(this,&CalibrationWindow::loadCalibrationFile,filename);
841 }
842 
844 {
845  mutex.lock();
846  loading();
847  int index = 0;
848 
849  char path[256] = { 0 };
850  snprintf(path, sizeof(path), "%s", filePath.toLatin1().data());
851  std::string filename = std::string(path);
852 
853  filename += "/calibrationData";
854  filename += serial_no;
855  filename += ".dat";
856  fstream filestr;
857  filestr.open (filename.c_str(), fstream::out);
858  int i=0;
859  char buffer[256];
860 
861 
862  if((icubCanProto_boardType__strain2 == boardtype || icubCanProto_boardType__strain2c == boardtype))
863  {
864  // file version
865  filestr<<"File version:"<<endl;
866  filestr<<"3"<<endl;
867  // board type
868  filestr<<"Board type:"<<endl;
869  filestr<<"strain2"<<endl;
870  // serial number
871  filestr<<"Serial number:"<<endl;
872  sprintf (buffer,"%s",serial_no);
873  filestr<<buffer<<endl;
874  // amplifier registers
875  filestr<<"Amplifier registers:"<<endl;
876  for (i=0;i<CHANNEL_COUNT; i++){
877  sprintf (buffer,"0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
878  amp_registers[i].data[0], amp_registers[i].data[1], amp_registers[i].data[2],
879  amp_registers[i].data[3], amp_registers[i].data[4], amp_registers[i].data[5]);
880  filestr<<buffer<<endl;
881  }
882  }
883  else
884  {
885  //file version
886  filestr<<"File version:"<<endl;
887  filestr<<"2"<<endl;
888 
889  //serial number
890  filestr<<"Serial number:"<<endl;
891  sprintf (buffer,"%s",serial_no);
892  filestr<<buffer<<endl;
893 
894  //offsets
895  filestr<<"Offsets:"<<endl;
896  for (i=0;i<CHANNEL_COUNT; i++){
897  sprintf (buffer,"%d",offset[i]);
898  filestr<<buffer<<endl;
899  }
900  }
901 
902 
903 
904  //calibration matrix
905  filestr<<"Calibration matrix:"<<endl;
906  for (i=0;i<36; i++){
907  sprintf (buffer,"%x",matrix[index][i/6][i%6]);
908  filestr<<buffer<<endl;
909  }
910 
911 
912  //matrix gain
913  filestr<<"Matrix gain:"<<endl;
914  sprintf (buffer,"%d",calib_const[index]);
915  filestr<<buffer<<endl;
916 
917 
918  //tare
919  filestr<<"Tare:"<<endl;
920  for (i=0;i<CHANNEL_COUNT; i++){
921  sprintf (buffer,"%d",calib_bias[i]);
922  filestr<<buffer<<endl;
923  }
924 
925  //full scale values
926  filestr<<"Full scale values:"<<endl;
927  for (i=0;i<CHANNEL_COUNT; i++){
928  sprintf (buffer,"%d",full_scale_const[index][i]);
929  filestr<<buffer<<endl;
930  }
931 
932 
933 
934  printf ("Calibration file saved!\n");
935  appendLogMsg("Calibration file saved!");
936  filestr.close();
937  loading(false);
938  mutex.unlock();
939 }
940 
941 void CalibrationWindow::onSaveCalibrationFile(bool click)
942 {
943  QString filePath = QFileDialog::getExistingDirectory(this,"Choose File",QDir::home().absolutePath());
944 
945  if(filePath.isEmpty()){
946  return;
947  }
948 
949  QtConcurrent::run(this,&CalibrationWindow::saveCalibrationFile,filePath);
950 }
951 
953 {
954  // marco.accame: the regulation set to be sent to the board is the one in use in its inside
955 
956  mutex.lock();
957  loading();
958  int index = 0;//ui->tabWidget->currentIndex();
959  char* buff = fileName.toLatin1().data();
960 
961  if (buff==NULL){
962  yError("File not found!\n");
963  appendLogMsg("File not found!");
964  loading(false);
965  mutex.unlock();
966  return;
967  }
968 
969  //fstream filestr;
970  QFile filestr(fileName);
971 
972  if (!filestr.open (QIODevice::ReadOnly)){
973  yError("Error opening calibration file!\n");
974  appendLogMsg("Error opening calibration file!");
975  loading(false);
976  mutex.unlock();
977  return;
978  }
979 
980  int i=0;
981 
982  QByteArray line = filestr.readLine();
983 #if defined(MARCO_ACCAME_19SEP2018)
984  if(line.at(0) != '#')
985  {
986  // it must be a hex file: close it and call importCalibrationFileHEX()
987  filestr.close();
988  loading(false);
989  mutex.unlock();
990  importCalibrationFileHEX(fileName);
991  return;
992  }
993 #endif
994  while(!line.isEmpty() && line.at(0) == '#' && !filestr.atEnd()){
995  line = filestr.readLine();
996  continue;
997  }
998 
999  if(filestr.atEnd()){
1000  filestr.close();
1001 
1002  printf ("No calib file loaded!\n");
1003  appendLogMsg("No calib file loaded!");
1004  loading(false);
1005  mutex.unlock();
1006  return;
1007 
1008  }
1009 
1010  QString s = QString(line);
1011 
1012  //for (i=0;i<36; i++){
1013  for (i=0;i<CHANNEL_COUNT; i++){
1014 
1015  QTextStream t(&s);
1016  float val[6];//1,val2,val3,val4,val5,val6;
1017  t >> val[0] >> val[1] >> val[2] >> val[3] >> val[4] >> val[5];
1018 
1019  bool saturated;
1020  //sscanf (line.data(),"%f",&val);
1021  for (int j=0;j<CHANNEL_COUNT; j++){
1022  Q15 value = q15::convert(val[j],saturated);
1023  calib_matrix[index][i][j] = value;
1024  matrix[index][i][j] = value;
1025  }
1026 
1027  line = filestr.readLine();
1028  s = QString(line);
1029 
1030  }
1031 
1032 
1033  matrix_changed[index]=true;
1034  setMatrix(index);
1035 
1036  while(!line.isEmpty() && line.at(0) == '#' && !filestr.atEnd()){
1037  line = filestr.readLine();
1038  continue;
1039  }
1040 
1041  s = QString(line);
1042 
1043  if(filestr.atEnd()){
1044  filestr.close();
1045 
1046  something_changed=true;
1047  matrix_changed[index]=true;
1048  setMatrix(index);
1049  printf ("Calibration Matrix loaded! - No Fullscale found\n");
1050  appendLogMsg("Calibration Matrix loaded! - No Fullscale found!");
1051  loading(false);
1052  mutex.unlock();
1053  return;
1054 
1055  }
1056 
1057 
1058  QTextStream t(&s);
1059 
1060  float val[6];//1,val2,val3,val4,val5,val6;
1061  t >> val[0] >> val[1] >> val[2] >> val[3] >> val[4] >> val[5];
1062 
1063  bool saturated;
1064 
1065  for (i=0;i<CHANNEL_COUNT; i++){
1066  FSC value = fsc::convert(val[i],saturated);
1067  full_scale_calib[index][i] = value;
1068 // core->getDownloader()->strain_set_full_scale(bus,id,i,value, regset, &msg);
1069 // appendLogMsg(msg.c_str());
1070 
1071  }
1072 
1073  fullScaleChanged = true;
1074  filestr.close();
1075 
1076  something_changed=true;
1077 
1078  setFullScale();
1079  printf ("Calibration file loaded!\n");
1080  appendLogMsg("Calibration file loaded!");
1081 
1082 
1083  /***********************************/
1084 
1085 // int ri=0;
1086 // int ci=0;
1087 
1088 // drv_sleep (1000);
1089 // for (ri=0;ri<CHANNEL_COUNT;ri++){
1090 // for (ci=0;ci<CHANNEL_COUNT;ci++){
1091 // core->getDownloader()->strain_get_matrix_rc(bus,id,ri,ci,matrix[index][ri][ci], regset, &msg);
1092 // appendLogMsg(msg.c_str());
1093 // }
1094 // }
1095 // setMatrix(index);
1096 // resetMatrices(index);
1097 
1098 // int count_ok=0;
1099 // for (i=0;i<36; i++){
1100 // ri=i/6;
1101 // ci=i%6;
1102 // if (calib_matrix[index][ri][ci]==matrix[index][ri][ci]) {
1103 // count_ok++;
1104 // } else {
1105 // printf ("Found 1 error on element %d,%d !!\n",ri, ci);
1106 // appendLogMsg("Found 1 error on element %d,%d !!");
1107 // }
1108 // }
1109 
1110 // if (count_ok==36){
1111 // printf ("Calibration file %s applied with no errors\n", buff);
1112 // appendLogMsg(QString("Calibration file %1 applied with no errors").arg(buff));
1113 // matrix_changed[0]=false;
1114 // } else {
1115 // printf ("Found %d errors applying the calibration file!!\n",36-count_ok);
1116 // appendLogMsg(QString("Found %1 errors applying the calibration file!!").arg(36-count_ok));
1117 // }
1118 
1119 
1120 
1121 
1122 
1123 
1124  loading(false);
1125  mutex.unlock();
1126 }
1127 
1128 void CalibrationWindow::onImportCalibrationFile(bool click)
1129 {
1130  QString fileName = QFileDialog::getOpenFileName(this,"Choose File",QDir::home().absolutePath());
1131 
1132  if(fileName.isEmpty()){
1133  return;
1134  }
1135 
1136  QtConcurrent::run(this,&CalibrationWindow::importCalibrationFile,fileName);
1137 }
1138 
1139 
1140 void CalibrationWindow::onSetCalibration(bool click)
1141 {
1142  QtConcurrent::run(this,&CalibrationWindow::setCalibration);
1143 }
1144 
1145 void CalibrationWindow::onSaveToEeprom(bool click)
1146 {
1147  QtConcurrent::run(this,&CalibrationWindow::saveToEeprom);
1148 }
1149 
1150 void CalibrationWindow::onClear_Statistics(bool click)
1151 {
1152  QtConcurrent::run(this,&CalibrationWindow::Clear_Statistics);
1153 }
1154 
1155 void CalibrationWindow::onClear_FullRegulation(bool click)
1156 {
1157  QtConcurrent::run(this,&CalibrationWindow::Clear_AllRegulations);
1158 }
1159 
1160 void CalibrationWindow::onClear_Regulation(bool click)
1161 {
1162  QtConcurrent::run(this,&CalibrationWindow::Clear_Regulation);
1163 }
1164 
1165 void CalibrationWindow::onSetCalibBias(bool click)
1166 {
1167  QtConcurrent::run(this,&CalibrationWindow::setCalibBias);
1168 }
1169 
1170 void CalibrationWindow::onResetCalibBias(bool click)
1171 {
1172  QtConcurrent::run(this,&CalibrationWindow::resetCalibBias);
1173 }
1174 
1175 void CalibrationWindow::onSetCurrBias(bool click)
1176 {
1177  QtConcurrent::run(this,&CalibrationWindow::setCurrBias);
1178 }
1179 
1180 void CalibrationWindow::onResetCurrBias(bool click)
1181 {
1182  QtConcurrent::run(this,&CalibrationWindow::resetCurrBias);
1183 }
1184 
1185 
1186 void CalibrationWindow::onSetSerial(bool)
1187 {
1188  QtConcurrent::run(this,&CalibrationWindow::setSerial);
1189 }
1190 
1191 void CalibrationWindow::onLoading(bool loading)
1192 {
1193  if(loading){
1194  ui->centralwidget->setEnabled(false);
1195  progress->setVisible(true);
1196  progress->setMaximum(0);
1197  }else{
1198  ui->centralwidget->setEnabled(true);
1199  progress->setVisible(false);
1200  progress->setMaximum(100);
1201  }
1202 }
1203 
1204 void CalibrationWindow::onUpdateTitle()
1205 {
1206  QString title = "Calibration";
1207  if(!eeprom_saved_status){
1208  title += " - ****** Not saved *****";
1209  }
1210  setWindowTitle(title);
1211 }
1212 
1214 {
1215  //timer->stop();
1216  if(!eeprom_saved_status){
1217  if(QMessageBox::warning(this, "The regulation set changed on the RAM of the board ", "Do you want to save the values to EEPROM?", QMessageBox::Yes,QMessageBox::No) == QMessageBox::Yes){
1218  onSaveToEeprom(true);
1219  e->ignore();
1220  return;
1221  }
1222  }
1223  keepRunning = false;
1224  QMainWindow::closeEvent(e);
1225 }
1226 
1227 void CalibrationWindow::onMatrixChanged(QTableWidgetItem *item)
1228 {
1229  Q_UNUSED(item);
1230  if(first_time){
1231  return;
1232  }
1233  if(item->text() == "-"){
1234  return;
1235  }
1236  QTableWidget *table = (QTableWidget*)sender();
1237  matrix_changed[matrices.indexOf(table)] = true;
1238  for(int i=0;i<CHANNEL_COUNT;i++){
1239  for(int j=0;j<CHANNEL_COUNT;j++){
1240  table->item(i,j)->setTextColor("red");
1241  }
1242  }
1243 }
1244 
1245 
1246 void CalibrationWindow::onSerialChanged(QString text)
1247 {
1248  if(first_time){
1249  return;
1250  }
1251  serial_number_changed = true;
1252 }
1253 
1254 void CalibrationWindow::onSetSerialChanged(bool changed)
1255 {
1256  if(changed){
1257  ui->edit_serial->setStyleSheet("background-color: rgb(255,0,0)");
1258  }else{
1259  ui->edit_serial->setStyleSheet("");
1260  }
1261 }
1262 
1263 void CalibrationWindow::onClearLog()
1264 {
1265  ui->logText->clear();
1266 }
1267 
1268 void CalibrationWindow::onAppendLogMsg(QString msg)
1269 {
1270  if(!msg.isEmpty()){
1271  ui->logText->appendPlainText(msg);
1272  }
1273 }
1274 
1275 void CalibrationWindow::onResetCalibMatrix(bool click)
1276 {
1277  QtConcurrent::run(this,&CalibrationWindow::resetCalibration);
1278 
1279 }
1280 
1282 {
1283  mutex.lock();
1284  int index = 0;//ui->tabWidget->currentIndex();
1285  //QLineEdit *editGain = matrixGain.at(index);
1286 
1287  for (int ri=0; ri<6; ri++){
1288  for (int ci=0; ci<6; ci++){
1289  if (ri==ci){
1290  matrix[index][ri][ci] = 32767;
1291  calib_matrix[index][ri][ci] = 32767;
1292  } else {
1293  matrix[index][ri][ci] = 0;
1294  calib_matrix[index][ri][ci] = 0;
1295  }
1296  }
1297  }
1298  calib_const[index]=1;
1299  //setText(editGain,QString("%1").arg(calib_const[index]));
1300  setMatrix(index);
1301  matrix_changed[index] = true;
1302  mutex.unlock();
1303 }
1304 
1305 
1306 //void CalibrationWindow::onUseMatrixChanged(int value)
1307 //{
1308 // if(value != 0){
1312 // ui->tableUseMatrix->showColumn(COL_NEWTONMEASURE);
1313 // ui->actionImport_Calib_Matrix->setEnabled(true);
1314 // ui->actionLoad_Calibration_File->setEnabled(true);
1315 // ui->actionSave_Calibration_File->setEnabled(true);
1316 // }else{
1320 // ui->tableUseMatrix->hideColumn(COL_NEWTONMEASURE);
1321 // ui->actionImport_Calib_Matrix->setEnabled(false);
1322 // ui->actionLoad_Calibration_File->setEnabled(false);
1323 // ui->actionSave_Calibration_File->setEnabled(false);
1324 // }
1325 
1326 
1327 // QtConcurrent::run(this,&CalibrationWindow::useMatrix,value);
1328 
1329 //}
1330 
1331 void CalibrationWindow::useMatrix(int index, bool boot)
1332 {
1333  mutex.lock();
1334  loading();
1335  string msg;
1336  if(index >= 0){
1337  // marco.accame: use the new method strain_set_regulationset w/ strain_regset_one / strain_regset_two / strain_regset_three
1338  // index = 0 means no calibration used. index = 1 means first set, etc. hence
1339  int regsetInUseTMP = index + 1;
1340  if(!boot){
1341  core->getDownloader()->strain_set_regulationset(bus, id, regsetInUseTMP, cDownloader::strain_regsetmode_temporary, &msg);
1342  } else {
1343  core->getDownloader()->strain_set_regulationset(bus, id, regsetInUseTMP, cDownloader::strain_regsetmode_permanent, &msg);
1344  }
1345  appendLogMsg(msg.c_str());
1346  }
1347  //currentMatrixIndex = index;
1348  loading(false);
1349  mutex.unlock();
1350 }
1351 
1352 
1353 
1354 
1355 void CalibrationWindow::setOffset(int chan, int value)
1356 {
1357  // marco.accame: the regulation set to be sent to the board is the one in use in its inside
1358 
1359  mutex.lock();
1360  loading();
1361  offset[chan] = value;
1362  string msg;
1363  core->getDownloader()->strain_set_offset(bus,id, chan, offset[chan], cDownloader::strain_regset_inuse, &msg);
1364  appendLogMsg(msg.c_str());
1365  loading(false);
1366  mutex.unlock();
1367 }
1368 
1369 void CalibrationWindow::onSetText(QLineEdit *edit,QString text)
1370 {
1371  edit->setText(text);
1372 }
1373 
1374 void CalibrationWindow::onSetText(QTableWidgetItem *item ,QString text)
1375 {
1376  item->setText(text);
1377 }
1378 
1379 void CalibrationWindow::onSetTableVisible(QTableWidget *item,bool visible)
1380 {
1381  item->setVisible(visible);
1382 }
1383 
1384 void CalibrationWindow::onApplyDone()
1385 {
1386  for(int i=0; i<CHANNEL_COUNT;i++){
1387  ((CustomComboBox*)ui->tableParamters->cellWidget(i,COL_GAIN))->clear();
1388  ((CustomSpinBox*)ui->tableParamters->cellWidget(i,COL_OFFSET))->clear();
1389  }
1390 }
1391 
1392 void CalibrationWindow::onOffsetSpinnerValue(CustomSpinBox *spinner, int value)
1393 {
1394  spinner->setCurrentValue(value);
1395 }
1396 
1397 void CalibrationWindow::onSetFullScale()
1398 {
1399  QTableWidget *table = fullScales.first();
1400  //disconnect(table,SIGNAL(itemChanged(QTableWidgetItem*)), this,SLOT( onMatrixChanged(QTableWidgetItem*)));
1401 
1402  char tempbuf [250];
1403  for(int ri=0;ri<CHANNEL_COUNT;ri++){
1404  double v = fsc::convert(full_scale_calib[0][ri]);
1405  //qDebug() << v;
1406  sprintf(tempbuf,"%f",v);
1407  QTableWidgetItem *item = table->item(ri,0);
1408  item->setText(tempbuf);
1409  }
1410 
1411 
1412 
1413 
1414  //connect(table,SIGNAL(itemChanged(QTableWidgetItem*)), this,SLOT( onMatrixChanged(QTableWidgetItem*)),Qt::UniqueConnection);
1415 }
1416 void CalibrationWindow::onSetMatrix(int index)
1417 {
1418  QTableWidget *table = matrices.at(index);
1419 
1420  //disconnect(table,SIGNAL(itemChanged(QTableWidgetItem*)), this,SLOT( onMatrixChanged(QTableWidgetItem*)));
1421  char tempbuf [250];
1422  for(int ri=0;ri<CHANNEL_COUNT;ri++){
1423  for(int ci=0;ci<CHANNEL_COUNT;ci++){
1424  double v = q15::convert(matrix[index][ri][ci]);
1425  //qDebug() << v;
1426  sprintf(tempbuf,"%f",v);
1427  QTableWidgetItem *item = table->item(ri,ci);
1428  item->setText(tempbuf);
1429  }
1430 
1431 
1432  }
1433 
1434  //connect(table,SIGNAL(itemChanged(QTableWidgetItem*)), this,SLOT( onMatrixChanged(QTableWidgetItem*)),Qt::UniqueConnection);
1435 }
1436 
1437 void CalibrationWindow::onTimeout()
1438 {
1439  // marco.accame: the regulation set for now is the one in use inside the strain2
1440 
1441 
1442  qDebug() << "STARTING....";
1443  keepRunning = true;
1444  while(keepRunning){
1445  mutex.lock();
1446 
1447  int bUseCalibration = ui->checkDigital->isChecked();
1448  string msg;
1449  bool skip_display_calib=false;
1450 
1451 #if 0
1452  // non va bene discriminare sulla base di busecalibration. lo si deve fare su strain1 / strain2
1453  if(bUseCalibration) {
1454  // marco.accame.todo: must use strain_get_regulationset(). attention the values returned will be 1, 2, 3
1455  // previously strain_get_matrix(currmatrix) returned currmatrix = 0 to mean the first one. hence it was used setCurrentIndex(currmatrix+1)
1457 
1458  int bootRegset = cDownloader::strain_regset_inuse;
1460  // must now transform usedregulationset.
1461  // for now, until we have gui support to the three regulation sets ..
1462  // it is forced to 0 to keep former behaviour of strain_get_matrix()
1463  //usedregulationset = 0;
1464 
1465 
1466  ui->comboRegSet->blockSignals(true);
1467  ui->comboRegSet->setCurrentIndex(regsetInUse - 1);
1468  ui->comboRegSet->blockSignals(false);
1469 
1470  ui->comboRegSetBoot->blockSignals(true);
1471  ui->comboRegSetBoot->setCurrentIndex(bootRegset - 1);
1472  ui->comboRegSetBoot->blockSignals(false);
1473  }else{
1474 // ui->comboUseMatrix->blockSignals(true);
1475 // ui->comboUseMatrix->setCurrentIndex(0);
1476 // ui->comboUseMatrix->blockSignals(false);
1477 // currentMatrixIndex = 0;
1478  }
1479 
1480 #else
1481 
1482  if((icubCanProto_boardType__strain2 == boardtype) || (icubCanProto_boardType__strain2c == boardtype))
1483  {
1484  int regsetInUseTMP = cDownloader::strain_regset_one;
1485 
1486  // marco.accame.todo: must use strain_get_regulationset(). attention the values returned will be 1, 2, 3
1487  // previously strain_get_matrix(currmatrix) returned currmatrix = 0 to mean the first one. hence it was used setCurrentIndex(currmatrix+1)
1488  core->getDownloader()->strain_get_regulationset(bus, id, regsetInUseTMP, cDownloader::strain_regsetmode_temporary, &msg);
1489 
1490  int bootRegsetTMP = cDownloader::strain_regset_one;
1492  // must now transform usedregulationset.
1493  // for now, until we have gui support to the three regulation sets ..
1494  // it is forced to 0 to keep former behaviour of strain_get_matrix()
1495  //usedregulationset = 0;
1496 
1497 
1498  ui->comboRegSet->blockSignals(true);
1499  ui->comboRegSet->setCurrentIndex(regsetInUseTMP - 1);
1500  ui->comboRegSet->blockSignals(false);
1501 
1502  ui->comboRegSetBoot->blockSignals(true);
1503  ui->comboRegSetBoot->setCurrentIndex(bootRegsetTMP - 1);
1504  ui->comboRegSetBoot->blockSignals(false);
1505  }
1506 
1507 #endif
1508 
1509 
1510  if(first_time) {
1511  loading();
1512  ((CustomTreeWidgetItem*)item->getParentNode())->retrieveCanBoards(false);
1513  for (int i=0;i<((CustomTreeWidgetItem*)item->getParentNode())->getCanBoards().count();i++ ) {
1514  sBoard b = ((CustomTreeWidgetItem*)item->getParentNode())->getCanBoards().at(i);
1515  if(b.bus == bus && b.pid == id){
1516  selected = i;
1517  break;
1518  }
1519  }
1520 
1521  }
1522 
1523  if(refresh_serialnumber)
1524  {
1525  refresh_serialnumber = false;
1526 
1528  core->getDownloader()->board_list[selected].pid, serial_no,&msg);
1529  appendLogMsg(msg.c_str());
1530  setText(ui->edit_serial,serial_no);
1531 
1532  }
1533 
1534  int ret=0;
1535  ret = core->getDownloader()->strain_get_eeprom_saved(core->getDownloader()->board_list[selected].bus,
1536  core->getDownloader()->board_list[selected].pid,
1537  &eeprom_saved_status,&msg);
1538  appendLogMsg(msg.c_str());
1539  if (ret!=0){
1540  qDebug() << "debug: message 'strain_get_eeprom_saved' lost";
1541  }
1542  updateTitle();
1543 
1544  for (int i=0;i<CHANNEL_COUNT;i++){
1545  if(i==0){
1546  ret = core->getDownloader()->strain_get_offset (core->getDownloader()->board_list[selected].bus, core->getDownloader()->board_list[selected].pid, i, offset[i], cDownloader::strain_regset_inuse, &msg);
1547  }else{
1548  ret |= core->getDownloader()->strain_get_offset (core->getDownloader()->board_list[selected].bus, core->getDownloader()->board_list[selected].pid, i, offset[i], cDownloader::strain_regset_inuse, &msg);
1549  }
1550  appendLogMsg(msg.c_str());
1551  }
1552  if (ret!=0){
1553  qDebug() <<"debug: message 'strain_get_offset' lost.";
1554  }
1555 
1556 
1557  for (int i=0;i<CHANNEL_COUNT;i++){
1558  if(i==0){
1559  ret = core->getDownloader()->strain_get_adc (core->getDownloader()->board_list[selected].bus, core->getDownloader()->board_list[selected].pid, i, adc[i], bUseCalibration,&msg);
1560  }else{
1561  ret |= core->getDownloader()->strain_get_adc (core->getDownloader()->board_list[selected].bus, core->getDownloader()->board_list[selected].pid, i, adc[i], bUseCalibration,&msg);
1562  }
1563  appendLogMsg(msg.c_str());
1564  }
1565 
1566  if (ret!=0){
1567  qDebug() <<"debug: message 'strain_get_adc' lost.";
1568  }
1569 
1570  int ri,ci=0;
1571  char tempbuf [250];
1572 
1573 
1574 
1575 
1576  setSerialChanged(serial_number_changed);
1577 
1578  // marco.accame: maybe it is better to retrieve only one matrix: the selected one, not all three of them
1579 
1580  for(int mi=0;mi<MATRIX_COUNT;mi++){
1581  if (matrix_changed[mi] == false){
1582  for (ri=0;ri<CHANNEL_COUNT;ri++){
1583  for (ci=0;ci<CHANNEL_COUNT;ci++){
1584  core->getDownloader()->strain_get_matrix_rc(core->getDownloader()->board_list[selected].bus,
1585  core->getDownloader()->board_list[selected].pid,
1586  ri, ci, matrix[mi][ri][ci], cDownloader::strain_regset_inuse, &msg);
1587  appendLogMsg(msg.c_str());
1588  }
1589  }
1590  setMatrix(mi);
1591 // core->getDownloader()->strain_get_matrix_gain(core->getDownloader()->board_list[selected].bus,
1592 // core->getDownloader()->board_list[selected].pid,
1593 // calib_const[mi], regset, &msg);
1594 // appendLogMsg(msg.c_str());
1595 // sprintf(tempbuf,"%d",calib_const[mi]);
1596 // setText(matrixGain.at(mi),tempbuf);
1597 
1598 // for (ri=0;ri<CHANNEL_COUNT;ri++){
1599 // core->getDownloader()->strain_get_full_scale(core->getDownloader()->board_list[selected].bus, core->getDownloader()->board_list[selected].pid, ri, full_scale_const[ri],&msg);
1600 // appendLogMsg(msg.c_str());
1601 // sprintf(tempbuf,"%d",full_scale_const[ri]);
1602 // QTableWidgetItem *item2 = ui->tableParamters->item(ri,COL_FULLSCALE);
1603 // setText(item2,tempbuf);
1604 // }
1605 
1606  QTableWidget *table = matrices.at(mi);
1607  for(int i=0;i<CHANNEL_COUNT;i++){
1608  for(int j=0;j<CHANNEL_COUNT;j++){
1609  table->item(i,j)->setTextColor("");
1610  }
1611  }
1612  }else{
1613  QTableWidget *table = matrices.first();
1614  for(int i=0;i<CHANNEL_COUNT;i++){
1615  for(int j=0;j<CHANNEL_COUNT;j++){
1616  table->item(i,j)->setTextColor("red");
1617  }
1618  }
1619  }
1620  if(!fullScaleChanged){
1621  for (ri=0;ri<CHANNEL_COUNT;ri++){
1622  fullScales.at(mi)->item(ri,0)->setTextColor("");
1623  core->getDownloader()->strain_get_full_scale(bus,id, ri, full_scale_const[mi][ri], cDownloader::strain_regset_inuse, &msg);
1624  appendLogMsg(msg.c_str());
1625  sprintf(tempbuf,"%d",full_scale_const[mi][ri]);
1626  QTableWidgetItem *item2 = fullScales.at(mi)->item(ri,COL_FULLSCALE);
1627  setText(item2,tempbuf);
1628 
1629 
1630  }
1631  } else {
1632  for(int i=0;i<CHANNEL_COUNT;i++){
1633  fullScales.first()->item(i,0)->setTextColor("red");
1634  }
1635  }
1636 
1637  }
1638 
1639 
1640  if(clearStats)
1641  {
1642  clearStats = false;
1643  for(int i=0;i<CHANNEL_COUNT;i++)
1644  {
1645  maxadc[i] = -32768;
1646  minadc[i] = +32767;
1647  maxft[i] = -32768;
1648  minft[i] = +32767;
1649  }
1650  }
1651 
1652  for (int i=0;i<CHANNEL_COUNT;i++){
1653  if (!bUseCalibration){
1654  if(convert_to_signed32k(adc[i])>maxadc[i]){
1655  maxadc[i]=convert_to_signed32k(adc[i]);
1656  }
1657  if (convert_to_signed32k(adc[i])<minadc[i]){
1658  minadc[i]=convert_to_signed32k(adc[i]);
1659  }
1660  maxft[i]=-32768;
1661  minft[i]=+32767;
1662  } else {
1663  if(convert_to_signed32k(adc[i])>maxft[i]){
1664  maxft[i]=convert_to_signed32k(adc[i]);
1665  }
1666  if (convert_to_signed32k(adc[i])<minft[i]){
1667  minft[i]=convert_to_signed32k(adc[i]);
1668  }
1669 
1670  maxadc[i]=-32768;
1671  minadc[i]=+32767;
1672  }
1673  }
1674 
1675 
1676  if(bUseCalibration)
1677  {
1678  if(ui->tableCurr->horizontalHeaderItem(0)->text() != "ForceTorque"){
1679  setText(ui->tableCurr->horizontalHeaderItem(0),"ForceTorque");
1680 
1681  setText(ui->tableUseMatrix->horizontalHeaderItem(COL_MAXMEASURE),"Max FT");
1682  setText(ui->tableUseMatrix->horizontalHeaderItem(COL_MINMEASURE),"Min FT");
1683  setText(ui->tableUseMatrix->horizontalHeaderItem(COL_DIFFMEASURE),"Delta FT");
1684  setText(ui->tableUseMatrix->horizontalHeaderItem(COL_NEWTONMEASURE),"FT");
1685 
1686 
1687 
1688  for (int i=0;i<CHANNEL_COUNT;i++){
1689  setText(ui->tableUseMatrix->verticalHeaderItem(i),QString("%1").arg(i==0 ?"Fx"
1690  : i==1 ? "Fy"
1691  : i==2 ? "Fz"
1692  : i==3 ? "Mx"
1693  : i==4 ? "My"
1694  : "Mz" ));
1695  setText(ui->tableCurr->verticalHeaderItem(i),QString("%1").arg(i==0 ?"Fx"
1696  : i==1 ? "Fy"
1697  : i==2 ? "Fz"
1698  : i==3 ? "Mx"
1699  : i==4 ? "My"
1700  : "Mz" ));
1701  }
1702 
1703  setTableVisible(ui->tableCurr,false);
1704  setTableVisible(ui->tableCurr,true);
1705  setTableVisible(ui->tableUseMatrix,false);
1706  setTableVisible(ui->tableUseMatrix,true);
1707  }
1708  }
1709  else
1710  {
1711  if(ui->tableCurr->horizontalHeaderItem(0)->text() != "ADC"){
1712  setText(ui->tableCurr->horizontalHeaderItem(0),"ADC");
1713  setText(ui->tableUseMatrix->horizontalHeaderItem(COL_MAXMEASURE),"Max ADC");
1714  setText(ui->tableUseMatrix->horizontalHeaderItem(COL_MINMEASURE),"Min ADC");
1715  setText(ui->tableUseMatrix->horizontalHeaderItem(COL_DIFFMEASURE),"Delta ADC");
1716  setText(ui->tableUseMatrix->horizontalHeaderItem(COL_NEWTONMEASURE),"Empty");
1717 
1718  for (int i=0;i<CHANNEL_COUNT;i++){
1719  setText(ui->tableUseMatrix->verticalHeaderItem(i),QString("Ch:%1").arg(i));
1720  setText(ui->tableCurr->verticalHeaderItem(i),QString("Ch:%1").arg(i));
1721  }
1722 
1723  setTableVisible(ui->tableCurr,false);
1724  setTableVisible(ui->tableCurr,true);
1725  setTableVisible(ui->tableUseMatrix,false);
1726  setTableVisible(ui->tableUseMatrix,true);
1727  }
1728  }
1729 
1730 
1731  for (int i=0;i<CHANNEL_COUNT;i++){
1732 
1733  if((icubCanProto_boardType__strain2 == boardtype) || (icubCanProto_boardType__strain2c == boardtype))
1734  {
1736  core->getDownloader()->board_list[selected].pid, i,
1737  amp_registers[i], cDownloader::strain_regset_inuse, &msg);
1739  core->getDownloader()->board_list[selected].pid, i,
1740  amp_gains[i], amp_offsets[i], cDownloader::strain_regset_inuse, &msg);
1741 //#warning TEST di ricezione di un valore di gain inconsueto... dove viene cambiato il valore del combo sull base del valore ricevuto dall strain?
1742  appendLogMsg(msg.c_str());
1743 
1744 
1745  CustomComboBox *combo = (CustomComboBox *)ui->tableParamters->cellWidget(i,COL_GAIN);
1746  bool found = false;
1747  for(int k=0;k<combo->count();k++){
1748  if(combo->itemData(k).toInt() == amp_gains[i]){
1749 
1750  combo->setCurrIndex(k);
1751  found = true;
1752  break;
1753  }
1754  }
1755  if(!found){
1756  combo->addCustomValue(amp_gains[i]);
1757  }
1758 
1759  }
1760  else
1761  {
1762  amp_gains[i] = 1.0f;
1763  amp_offsets[i] = 0;
1764  }
1765 
1766 
1767  core->getDownloader()->strain_get_calib_bias(core->getDownloader()->board_list[selected].bus,
1768  core->getDownloader()->board_list[selected].pid, i,
1769  calib_bias[i], cDownloader::strain_regset_inuse, &msg);
1770  appendLogMsg(msg.c_str());
1771  //sprintf(tempbuf,"%d (%d)",showasQ15(calib_bias[i]), showBias(calib_bias[i]));
1772  sprintf(tempbuf,"%d", showasQ15(calib_bias[i]));
1773 
1774  QTableWidgetItem *item = ui->tableBias->item(i,COL_CALIBBIAS);
1775  setText(item,tempbuf);
1776 
1777 
1778 // core->getDownloader()->strain_get_curr_bias(core->getDownloader()->board_list[selected].bus, core->getDownloader()->board_list[selected].pid, i, curr_bias[i], &msg);
1779 // appendLogMsg(msg.c_str());
1780 // sprintf(tempbuf,"%d", showasQ15(curr_bias[i]));
1781 // QTableWidgetItem *item1 = ui->tableParamters->item(i,COL_CURRBIAS);
1782 // setText(item1,tempbuf);
1783 
1784 // sprintf (tempbuf,"%d",full_scale_const[i]);
1785 // QTableWidgetItem *item2 = ui->tableParamters->item(i,COL_FULLSCALE);
1786 // //item2->setText(tempbuf);
1787 // setText(item2,tempbuf);
1788 
1789  CustomSpinBox *slider = slider_offset.at(i);
1790  setOffsetSliderValue(slider,offset[i]);
1791 
1792  // marco.accame: we always show the received value in range [-32k, +32k).
1793  // in case of 0 == bUseCalibration: it is the adc value
1794  // in case of 1 == bUseCalibration: it is = M * (adc+calibtare) + currtare
1795  sprintf(tempbuf,"%d",convert_to_signed32k(adc[i]));
1796 
1797  QTableWidgetItem *item3 = NULL;
1798  if(bUseCalibration){
1799  item3 = ui->tableUseMatrix->item(i,COL_NEWTONMEASURE);
1800  }else{
1801  item3 = ui->tableCurr->item(i,COL_CURRMEASURE);
1802  }
1803  setText(item3,tempbuf);
1804 
1805 
1806 
1807 
1808  if(bUseCalibration){
1809  /****************************** Use digital ***************************/
1810  sprintf(tempbuf,"%d",maxft[i]);
1811  QTableWidgetItem *item = ui->tableUseMatrix->item(i,COL_MAXMEASURE);
1812  setText(item,tempbuf);
1813 
1814  sprintf(tempbuf,"%d",minft[i]);
1815  QTableWidgetItem *item1 = ui->tableUseMatrix->item(i,COL_MINMEASURE);
1816  setText(item1,tempbuf);
1817 
1818  sprintf(tempbuf,"%d",maxft[i]-minft[i]);
1819  QTableWidgetItem *item2 = ui->tableUseMatrix->item(i,COL_DIFFMEASURE);
1820  setText(item2,tempbuf);
1821 
1822  if (full_scale_const[currentMatrixIndex][i]==0){
1823  qDebug() << "Error getting the full scale "<< i << " from the sensor";
1824  skip_display_calib=true;
1825  }
1826 
1827 
1828 
1829  if (skip_display_calib==false){
1830  if(i<=2){
1831  sprintf(tempbuf,"%+.3f N",(convert_to_signed32k(adc[i]))/float(RANGE32K)*full_scale_const[currentMatrixIndex][i]);
1832  }else{
1833  sprintf(tempbuf,"%+.3f Nm",(convert_to_signed32k(adc[i]))/float(RANGE32K)*full_scale_const[currentMatrixIndex][i]);
1834  }
1835  //QTableWidgetItem *item3 = ui->tableUseMatrix->item(i,COL_NEWTONMEASURE);
1836  QTableWidgetItem *item3 = ui->tableCurr->item(i,COL_CURRMEASURE);
1837  setText(item3,tempbuf);
1838  }else{
1839  //QTableWidgetItem *item = ui->tableUseMatrix->item(i,COL_NEWTONMEASURE);
1840  QTableWidgetItem *item3 = ui->tableCurr->item(i,COL_CURRMEASURE);
1841  setText(item3,"ERROR");
1842  }
1843  } else {
1844  /****************************** Don't Use digital ***************************/
1845  sprintf(tempbuf,"%d",maxadc[i]);
1846  QTableWidgetItem *item = ui->tableUseMatrix->item(i,COL_MAXMEASURE);
1847  setText(item,tempbuf);
1848 
1849 
1850  sprintf(tempbuf,"%d",minadc[i]);
1851  QTableWidgetItem *item1 = ui->tableUseMatrix->item(i,COL_MINMEASURE);
1852  setText(item1,tempbuf);
1853 
1854 
1855  sprintf(tempbuf,"%d",maxadc[i]-minadc[i]);
1856  QTableWidgetItem *item2 = ui->tableUseMatrix->item(i,COL_DIFFMEASURE);
1857  setText(item2,tempbuf);
1858 
1859  QTableWidgetItem *item3 = ui->tableUseMatrix->item(i,COL_NEWTONMEASURE);
1860  setText(item3,"");
1861 
1862 // if(i<=2){
1863 // QTableWidgetItem *item = ui->tableCurr->item(i,COL_CURRMEASURE);
1864 // setText(item,"--- N");
1865 // }else{
1866 // QTableWidgetItem *item = ui->tableCurr->item(i,COL_CURRMEASURE);
1867 // setText(item,"--- Nm");
1868 // }
1869  }
1870  }
1871 
1872 
1873 
1874  if(first_time){
1875  first_time = false;
1876  loading(false);
1877 
1878  }
1879 
1880  mutex.unlock();
1881 
1882 
1883 
1884  QThread::msleep(500);
1885 
1886  }
1887 
1888 }
1889 
1890 bool CalibrationWindow::calibration_load_v3 (char* filename, int selected_bus, int selected_id, int index, int regset)
1891 {
1892  if (filename==NULL){
1893  yError("File not found!\n");
1894  appendLogMsg("File not found!");
1895  return false;
1896  }
1897  if (selected_id <1 || selected_id >= 15){
1898  yError("Invalid board address!\n");
1899  appendLogMsg("Invalid board address!");
1900  return false;
1901  }
1902 
1903  int file_version=0;
1904  fstream filestr;
1905  filestr.open (filename, fstream::in);
1906  if (!filestr.is_open()){
1907  yError("Error opening calibration file!\n");
1908  appendLogMsg("Error opening calibration file!");
1909  return false;
1910  }
1911 
1912  int i=0;
1913  char buffer[256];
1914 
1915  //file version
1916  filestr.getline (buffer,256);
1917  filestr.getline (buffer,256);
1918  sscanf (buffer,"%d",&file_version);
1919 
1920 
1921  if( ( (icubCanProto_boardType__strain2 == boardtype) || (icubCanProto_boardType__strain2c == boardtype) ) && (3 != file_version))
1922  {
1923  yError("Wrong file. Calibration version not supported for strain2: %d\n", file_version);
1924  appendLogMsg("Wrong file. Calibration version not supported for strain2");
1925  return false;
1926  }
1927  else if((icubCanProto_boardType__strain == boardtype) && (2 != file_version))
1928  {
1929  yError("Wrong file. Calibration version not supported: %d\n", file_version);
1930  appendLogMsg("Wrong file. Calibration version not supported");
1931  return false;
1932  }
1933 
1934  if(3 == file_version)
1935  {
1936  // Board type:
1937  filestr.getline (buffer,256);
1938  filestr.getline (buffer,256);
1939  if(0 != strcmp(buffer, "strain2"))
1940  {
1941  yError("Wrong file. Board type not supported: %s\n", buffer);
1942  appendLogMsg("Wrong file. Board type not supported");
1943  return false;
1944  }
1945 
1946  // Serial number:
1947  filestr.getline (buffer,256);
1948  filestr.getline (buffer,256);
1949  sprintf(serial_no,"%s", buffer);
1950  core->getDownloader()->strain_set_serial_number(bus,id, serial_no);
1951  //yDebug() << buffer;
1952 
1953  // Amplifier registers:
1954  filestr.getline (buffer,256);
1955  for (i=0;i<CHANNEL_COUNT; i++)
1956  {
1957  filestr.getline (buffer,256);
1958  yDebug() << buffer;
1959  unsigned int t08[6] = {0};
1960  sscanf (buffer,"0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", &t08[0], &t08[1], &t08[2], &t08[3], &t08[4], &t08[5]);
1961  for(int j=0; j<6; j++) amp_registers[i].data[j] = t08[j];
1962 
1963  core->getDownloader()->strain_set_amplifier_regs(core->getDownloader()->board_list[selected].bus, core->getDownloader()->board_list[selected].pid, i, amp_registers[i], regset);
1964 
1965  // downloader.strain_set_offset (downloader.board_list[selected].bus, downloader.board_list[selected].pid, i, offset[i]);
1966  //core->getDownloader()->strain_set_offset (bus,id, i, offset[i]);
1967  //printf("0X%02x, 0X%02x, 0X%02x, 0X%02x, 0X%02x,0X%02x", amp_registers[i].data[0], amp_registers[i].data[1], amp_registers[i].data[2], amp_registers[i].data[3], amp_registers[i].data[4], amp_registers[i].data[5]);
1968  //fflush(stdout);
1969  drv_sleep(10);
1970  }
1971 
1972  }
1973  else
1974  {
1975 
1976  //serial number
1977  filestr.getline (buffer,256);
1978  filestr.getline (buffer,256);
1979  sprintf(serial_no,"%s", buffer);
1980  core->getDownloader()->strain_set_serial_number(bus,id, serial_no);
1981 
1982  //offsets
1983  filestr.getline (buffer,256);
1984  for (i=0;i<CHANNEL_COUNT; i++)
1985  {
1986  filestr.getline (buffer,256);
1987  sscanf (buffer,"%d",&offset[i]);
1988  // downloader.strain_set_offset (downloader.board_list[selected].bus, downloader.board_list[selected].pid, i, offset[i]);
1989  core->getDownloader()->strain_set_offset (bus,id, i, offset[i], regset);
1990  drv_sleep(200);
1991  }
1992  }
1993 
1994  //calibration matrix
1995  filestr.getline (buffer,256);
1996  for (i=0;i<36; i++){
1997  int ri=i/6;
1998  int ci=i%6;
1999  filestr.getline (buffer,256);
2000  sscanf (buffer,"%x",&calib_matrix[index][ri][ci]);
2001  printf("%d %x\n", calib_matrix[index][ri][ci],calib_matrix[index][ri][ci]);
2002  core->getDownloader()->strain_set_matrix_rc(bus,id, ri, ci, calib_matrix[index][ri][ci], regset);
2003  }
2004 
2005 
2006 
2007  //matrix gain
2008  filestr.getline (buffer,256);
2009  filestr.getline (buffer,256);
2010  int cc=0;
2011  sscanf (buffer,"%d",&cc);
2012  core->getDownloader()->strain_set_matrix_gain(bus,id, cc, regset);
2013 
2014  //tare
2015  filestr.getline (buffer,256);
2016  for (i=0;i<CHANNEL_COUNT; i++){
2017  filestr.getline (buffer,256);
2018  sscanf (buffer,"%d",&calib_bias[i]);
2019  core->getDownloader()->strain_set_calib_bias(bus,id, i, calib_bias[i], regset);
2020  }
2021 
2022  //full scale values
2023  filestr.getline (buffer,256);
2024  for (i=0;i<CHANNEL_COUNT; i++){
2025  filestr.getline (buffer,256);
2026  sscanf (buffer,"%d",&full_scale_const[index][i]);
2027  core->getDownloader()->strain_set_full_scale(bus,id, i, full_scale_const[index][i], regset);
2028  }
2029 
2030 
2031 
2032  filestr.close();
2033  filestr.clear();
2034 
2035  matrix_changed[0]=true;
2036  matrix_changed[1]=true;
2037  matrix_changed[2]=true;
2038  something_changed=true;
2039  printf ("Calibration file loaded!\n");
2040  appendLogMsg("Calibration file loaded!");
2041 
2042  return true;
2043 }
2044 
2045 #if 0
2046 bool CalibrationWindow::calibration_load_v2 (char* filename, int selected_bus, int selected_id, int index)
2047 {
2048  const int regset = cDownloader::strain_regset_inuse;
2049 
2050  if (filename==NULL){
2051  yError("File not found!\n");
2052  appendLogMsg("File not found!");
2053  return false;
2054  }
2055  if (selected_id <1 || selected_id >= 15){
2056  yError("Invalid board address!\n");
2057  appendLogMsg("Invalid board address!");
2058  return false;
2059  }
2060 
2061  int file_version=0;
2062  fstream filestr;
2063  filestr.open (filename, fstream::in);
2064  if (!filestr.is_open()){
2065  yError("Error opening calibration file!\n");
2066  appendLogMsg("Error opening calibration file!");
2067  return false;
2068  }
2069 
2070  int i=0;
2071  char buffer[256];
2072 
2073  //file version
2074  filestr.getline (buffer,256);
2075  filestr.getline (buffer,256);
2076  sscanf (buffer,"%d",&file_version);
2077  if (file_version!=2){
2078  yError("Wrong file. Calibration version != 2\n");
2079  appendLogMsg("Wrong file. Calibration version != 2");
2080  return false;
2081  }
2082 
2083  //serial number
2084  filestr.getline (buffer,256);
2085  filestr.getline (buffer,256);
2086  sprintf(serial_no,"%s", buffer);
2087  core->getDownloader()->strain_set_serial_number(bus,id, serial_no);
2088 
2089  //offsets
2090  filestr.getline (buffer,256);
2091  for (i=0;i<CHANNEL_COUNT; i++)
2092  {
2093  filestr.getline (buffer,256);
2094  sscanf (buffer,"%d",&offset[i]);
2095  // downloader.strain_set_offset (downloader.board_list[selected].bus, downloader.board_list[selected].pid, i, offset[i]);
2096  core->getDownloader()->strain_set_offset (bus,id, i, offset[i], regset);
2097  drv_sleep(200);
2098  }
2099 
2100  //calibration matrix
2101  filestr.getline (buffer,256);
2102  for (i=0;i<36; i++){
2103  int ri=i/6;
2104  int ci=i%6;
2105  filestr.getline (buffer,256);
2106  sscanf (buffer,"%x",&calib_matrix[index][ri][ci]);
2107  printf("%d %x\n", calib_matrix[index][ri][ci],calib_matrix[index][ri][ci]);
2108  core->getDownloader()->strain_set_matrix_rc(bus,id, ri, ci, calib_matrix[index][ri][ci], regset);
2109  }
2110 
2111 
2112 
2113  //matrix gain
2114  filestr.getline (buffer,256);
2115  filestr.getline (buffer,256);
2116  int cc=0;
2117  sscanf (buffer,"%d",&cc);
2118  core->getDownloader()->strain_set_matrix_gain(bus,id, cc, regset);
2119 
2120  //tare
2121  filestr.getline (buffer,256);
2122  for (i=0;i<CHANNEL_COUNT; i++){
2123  filestr.getline (buffer,256);
2124  sscanf (buffer,"%d",&calib_bias[i]);
2125  core->getDownloader()->strain_set_calib_bias(bus,id, i, calib_bias[i], regset);
2126  }
2127 
2128  //full scale values
2129  filestr.getline (buffer,256);
2130  for (i=0;i<CHANNEL_COUNT; i++){
2131  filestr.getline (buffer,256);
2132  sscanf (buffer,"%d",&full_scale_const[index][i]);
2133  core->getDownloader()->strain_set_full_scale(bus,id, i, full_scale_const[index][i], regset);
2134  }
2135 
2136 
2137 
2138  filestr.close();
2139  filestr.clear();
2140 
2141  matrix_changed[0]=true;
2142  matrix_changed[1]=true;
2143  matrix_changed[2]=true;
2144  something_changed=true;
2145  printf ("Calibration file loaded!\n");
2146  appendLogMsg("Calibration file loaded!");
2147 
2148  return true;
2149 }
2150 #endif
2151 
2152 
2153 #if defined(MARCO_ACCAME_19SEP2018)
2155 {
2156  // marco.accame: the regulation set to be sent to the board is the one in use in its inside
2157  const int regset = cDownloader::strain_regset_inuse;
2158  const int index = 0;
2159 
2160  mutex.lock();
2161  loading();
2162  char* buff = fileName.toLatin1().data();
2163  string msg;
2164 
2165  if (buff==NULL){
2166  yError("File not found!\n");
2167  appendLogMsg("File not found!");
2168  loading(false);
2169  mutex.unlock();
2170  return;
2171  }
2172 
2173  fstream filestr;
2174  filestr.open (buff, fstream::in);
2175  if (!filestr.is_open()){
2176  yError("Error opening MATLAB matrix-fullscale file!\n");
2177  appendLogMsg("Error opening MATLAB matrix-fullscale file!");
2178  loading(false);
2179  mutex.unlock();
2180  return;
2181  }
2182 
2183  printf("Importing MATLAB matrix-fullscale file.\n");
2184 
2185  printf("matrix[6][6] = \n");
2186  unsigned int mat0[6][6] = {0};
2187  int i=0;
2188  char buffer[256];
2189  for (i=0;i<36; i++){
2190  int ri=i/6;
2191  int ci=i%6;
2192  filestr.getline (buffer,256);
2193  sscanf (buffer,"%x",&mat0[ri][ci]);
2194  printf("%f (0x%x)\n", strain::dsp::q15::convert(mat0[ri][ci]), mat0[ri][ci]);
2195  core->getDownloader()->strain_set_matrix_rc(bus,id,ri,ci,mat0[ri][ci], regset, &msg);
2196  appendLogMsg(msg.c_str());
2197  }
2198 
2199 
2200  filestr.getline (buffer,256);
2201  int cc=0;
2202  sscanf (buffer,"%d",&cc);
2203  core->getDownloader()->strain_set_matrix_gain(bus,id,cc, regset, &msg);
2204  appendLogMsg(msg.c_str());
2205 
2206  printf("gain = %d [BUT IT IS UNUSED]\n", cc);
2207 
2208  printf("fullscales[6] = \n");
2209  for (i=0;i<CHANNEL_COUNT; i++){
2210  filestr.getline (buffer,256);
2211  sscanf (buffer,"%d",&cc);
2212  printf("%d\n", cc);
2213  core->getDownloader()->strain_set_full_scale(bus,id,i,cc, regset, &msg);
2214  appendLogMsg(msg.c_str());
2215  }
2216 
2217  filestr.close();
2218 
2219 // something_changed=true;
2220  printf ("MATLAB matrix-fullscale file loaded!\n");
2221  appendLogMsg("MATLAB matrix-fullscale file loaded!");
2222 
2223  int ri=0;
2224  int ci=0;
2225 
2226  unsigned int mat1[6][6] = {0};
2227  drv_sleep (1000);
2228  for (ri=0;ri<CHANNEL_COUNT;ri++){
2229  for (ci=0;ci<CHANNEL_COUNT;ci++){
2230  core->getDownloader()->strain_get_matrix_rc(bus,id,ri,ci,mat1[ri][ci], regset, &msg);
2231  appendLogMsg(msg.c_str());
2232  }
2233  }
2234 // setMatrix(index);
2235 // resetMatrices(index);
2236 
2237  int count_ok=0;
2238  for (i=0;i<36; i++){
2239  ri=i/6;
2240  ci=i%6;
2241  if (mat0[ri][ci]==mat1[ri][ci]) {
2242  count_ok++;
2243  } else {
2244  printf ("Found 1 error on element %d,%d !!\n",ri, ci);
2245  appendLogMsg("Found 1 error on element %d,%d !!");
2246  }
2247  }
2248 
2249  if (count_ok==36){
2250  printf ("MATLAB matrix-fullscale file %s applied with no errors\n", buff);
2251  appendLogMsg(QString("MATLAB matrix-fullscale file %1 applied with no errors").arg(buff));
2252 // matrix_changed[0]=false;
2253  } else {
2254  printf ("Found %d errors applying the MATLAB matrix-fullscale file!!\n",36-count_ok);
2255  appendLogMsg(QString("Found %1 errors applying the MATLAB matrix-fullscale file!!").arg(36-count_ok));
2256  }
2257 
2258  matrix_changed[index] = false;
2259  fullScaleChanged = false;
2260  something_changed = false;
2261 
2262  loading(false);
2263  mutex.unlock();
2264 }
2265 #endif // (MARCO_ACCAME_19SEP2018)
2266 
2267 void CalibrationWindow::logger(void *caller, const std::string &msg)
2268 {
2269  if(NULL != caller)
2270  {
2271  CalibrationWindow *cw = reinterpret_cast<CalibrationWindow*>(caller);
2272  cw->appendLogMsg(QString::fromStdString(msg));
2273  }
2274 
2275 }
2276 
2277 bool CalibrationWindow::SetDefaultRegulationSet(int regset, bool alsoserialnumber)
2278 {
2279  int i=0;
2280 
2281  if(alsoserialnumber)
2282  {
2283  // serial number
2284  char my_serial_no[8] = "SN0000";
2285  core->getDownloader()->strain_set_serial_number(bus,id, my_serial_no);
2286  }
2287 
2288  if((icubCanProto_boardType__strain2 == boardtype) || (icubCanProto_boardType__strain2c == boardtype))
2289  {
2290  // amplifier registers:
2291  for (i=0;i<CHANNEL_COUNT; i++)
2292  {
2293  core->getDownloader()->strain_set_amplifier_gain_offset(core->getDownloader()->board_list[selected].bus, core->getDownloader()->board_list[selected].pid, i, core->getDownloader()->strain_amplifier_discretegain2float(defaultStrain2AmplGains[i]), defaultStrain2AmplOffsets[i], regset);
2294  drv_sleep(10);
2295  }
2296 
2297  }
2298  else
2299  {
2300  // offsets
2301  for (i=0;i<CHANNEL_COUNT; i++)
2302  {
2303  core->getDownloader()->strain_set_offset (bus,id, i, defaultStrain1DACoffsets[i], regset);
2304  drv_sleep(200);
2305  }
2306  }
2307 
2308  // calibration matrix
2309  for (i=0;i<36; i++)
2310  {
2311  int ri=i/6;
2312  int ci=i%6;
2313  unsigned int value = 0;
2314  if(ri == ci)
2315  {
2316  value = 32767;
2317  }
2318  core->getDownloader()->strain_set_matrix_rc(bus,id, ri, ci, value, regset);
2319  }
2320 
2321 
2322 
2323  // matrix gain
2324  core->getDownloader()->strain_set_matrix_gain(bus,id, 1, regset);
2325 
2326  // tare
2327  for (i=0;i<CHANNEL_COUNT; i++)
2328  {
2329  core->getDownloader()->strain_set_calib_bias(bus,id, i, 0, regset);
2330  }
2331 
2332  // full scale values
2333  for (i=0;i<CHANNEL_COUNT; i++)
2334  {
2335  unsigned int fs =
2336  core->getDownloader()->strain_set_full_scale(bus,id, i, 32767, regset);
2337  }
2338 
2339  return true;
2340 }
@ data
#define COL_CURRMEASURE
int convert_to_signed32k(unsigned int v)
#define COL_DIFFMEASURE
#define CHANNEL_COUNT
#define COL_CALIBBIAS
#define COL_NEWTONMEASURE
#define COL_TARGET
#define COL_OFFSET
int showBias(unsigned int v)
#define RANGE32K
#define COL_MINMEASURE
#define COL_FULLSCALE
unsigned int q15_from(int v)
#define COL_MAXMEASURE
#define COL_GAIN
int showasQ15(int v)
#define MATRIX_COUNT
bool SetDefaultRegulationSet(int regset, bool alsoserialnumber=false)
void setMatrix(int index)
void appendLogMsg(QString)
void setTableVisible(QTableWidget *, bool)
void resetMatrices(int index=-1)
bool calibration_load_v3(char *filename, int selected_bus, int selected_id, int index, int regset)
void setOffsetSliderValue(CustomSpinBox *, int value)
void setOffset(int chan, int value)
void closeEvent(QCloseEvent *e)
void importCalibrationFile(QString fileName)
void loading(bool=true)
void setText(QLineEdit *, QString text)
CalibrationWindow(FirmwareUpdaterCore *core, icubCanProto_boardType_t b, CustomTreeWidgetItem *item, QWidget *parent=0)
void setSerialChanged(bool)
void importCalibrationFileHEX(QString fileName)
void loadCalibrationFile(QString fileName)
void useMatrix(int, bool boot)
static void logger(void *caller, const std::string &msg)
void saveCalibrationFile(QString filePath)
void setCurrIndex(int v)
void addCustomValue(float val)
void setIndexFromAmpGain(int g)
void setCurrentValue(int v)
QTreeWidgetItem * getParentNode()
int strain_get_serial_number(int bus, int target_id, char *serial_number, string *errorstring=NULL)
Definition: downloader.cpp:672
int strain_set_matrix_gain(int bus, int target_id, unsigned int gain, int regset=strain_regset_inuse, string *errorstring=NULL)
Definition: downloader.cpp:891
int strain_get_offset(int bus, int target_id, char channel, unsigned int &offset, int regset=strain_regset_inuse, string *errorstring=NULL)
Definition: downloader.cpp:399
int strain_get_full_scale(int bus, int target_id, unsigned char channel, unsigned int &full_scale, int regset=strain_regset_inuse, string *errorstring=NULL)
int strain_get_calib_bias(int bus, int target_id, char channel, signed int &bias, int regset=strain_regset_inuse, string *errorstring=NULL)
Definition: downloader.cpp:444
int strain_reset_curr_bias(int bus, int target_id, string *errorstring=NULL)
Definition: downloader.cpp:622
int strain_set_offset(int bus, int target_id, char channel, unsigned int offset, int regset=strain_regset_inuse, string *errorstring=NULL)
int strain_set_serial_number(int bus, int target_id, const char *serial_number, string *errorstring=NULL)
Definition: downloader.cpp:644
int strain_get_regulationset(int bus, int target_id, int &regset, const int regsetmode=strain_regsetmode_temporary, string *errorstring=NULL)
Definition: downloader.cpp:837
int strain_save_to_eeprom(int bus, int target_id, string *errorstring=NULL)
Definition: downloader.cpp:214
@ strain_regsetmode_permanent
Definition: downloader.h:148
@ strain_regsetmode_temporary
Definition: downloader.h:148
int strain_get_adc(int bus, int target_id, char channel, unsigned int &adc, int type, string *errorstring=NULL)
Definition: downloader.cpp:348
int strain_get_eeprom_saved(int bus, int target_id, bool *status, string *errorstring=NULL)
Definition: downloader.cpp:713
int strain_reset_calib_bias(int bus, int target_id, string *errorstring=NULL)
Definition: downloader.cpp:524
int strain_get_matrix_rc(int bus, int target_id, char r, char c, unsigned int &elem, int regset=strain_regset_inuse, string *errorstring=NULL)
void set_external_logger(void *caller=NULL, void(*logger)(void *, const std::string &)=NULL)
Definition: downloader.cpp:103
int strain_set_full_scale(int bus, int target_id, unsigned char channel, unsigned int full_scale, int regset=strain_regset_inuse, string *errorstring=NULL)
sBoard * board_list
Definition: downloader.h:150
int strain_set_regulationset(int bus, int target_id, int regset=strain_regset_one, int regsetmode=strain_regsetmode_temporary, string *errorstring=NULL)
Definition: downloader.cpp:804
@ strain_regset_inuse
Definition: downloader.h:147
@ strain_regset_two
Definition: downloader.h:147
@ strain_regset_one
Definition: downloader.h:147
@ strain_regset_three
Definition: downloader.h:147
int strain_set_calib_bias(int bus, int target_id, string *errorstring=NULL)
Definition: downloader.cpp:476
int strain_get_amplifier_regs(int bus, int target_id, unsigned char channel, strain2_ampl_regs_t &ampregs, int regset=strain_regset_inuse, string *errorstring=NULL)
Definition: downloader.cpp:947
int strain_set_curr_bias(int bus, int target_id, string *errorstring=NULL)
Definition: downloader.cpp:575
int strain_get_amplifier_gain_offset(int bus, int target_id, unsigned char channel, float &gain, uint16_t &offset, int regset=strain_regset_inuse, string *errorstring=NULL)
int strain_set_matrix_rc(int bus, int target_id, char r, char c, unsigned int elem, int regset=strain_regset_inuse, string *errorstring=NULL)
int strain_set_amplifier_regs(int bus, int target_id, unsigned char channel, const strain2_ampl_regs_t &ampregs, int regset=strain_regset_inuse, string *errorstring=NULL)
Definition: downloader.cpp:913
int strain_set_amplifier_gain_offset(int bus, int target_id, unsigned char channel, float gain, uint16_t offset, int regset=strain_regset_inuse, string *errorstring=NULL)
float strain_amplifier_discretegain2float(strain2_ampl_discretegain_t c)
Definition: downloader.cpp:992
int strain_calibrate_offset2(int bus, int target_id, icubCanProto_boardType_t boardtype, const std::vector< strain2_ampl_discretegain_t > &gains, const std::vector< int16_t > &targets, string *errorstring=NULL)
#define GAINAMPROLE
Definition: customcombobox.h:8
void drv_sleep(double time)
Definition: downloader.cpp:26
strain2_ampl_discretegain_t
Definition: downloader.h:105
@ ampl_gain08
Definition: downloader.h:107
@ ampl_gain24
Definition: downloader.h:106
@ ampl_gain10
Definition: downloader.h:107
home
store as home position
Gain convert(const DiscreteGain dg)
Definition: strain.cpp:673
Q15 convert(const double v, bool &saturated)
Definition: strain.cpp:1135
std::uint16_t FSC
Definition: strain.h:40
std::int16_t Q15
Definition: strain.h:41
out
Definition: sine.m:8
degrees offset
Definition: sine.m:4
int bus
Definition: downloader.h:25
int pid
Definition: downloader.h:26