YARP
Yet Another Robot Platform
ControlBoardHelper.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * All rights reserved.
4  *
5  * This software may be modified and distributed under the terms of the
6  * BSD-3-Clause license. See the accompanying LICENSE file for details.
7  */
8 
10 #include <yarp/dev/PidEnums.h>
11 #include <cstdio> // for printf
12 #include <cmath> //fabs
13 #include <yarp/os/Log.h>
14 #include <yarp/os/LogStream.h>
15 #include <map>
16 
17 using namespace yarp::dev;
18 
19 struct PidUnits
20 {
24  fbk_units = PidFeedbackUnitsEnum::RAW_MACHINE_UNITS;
25  out_units = PidOutputUnitsEnum::RAW_MACHINE_UNITS;
26  }
27 };
28 
30 {
31 public:
32  int nj;
33  int *axisMap;
34  int *invAxisMap;
35  bool verbose;
36 
37  double *position_zeros;
38  double *helper_ones;
39  double *angleToEncoders;
41  double *ampereToSensors;
42  double *voltToSensors;
43  double *dutycycleToPWMs;
44  double *bemfToRaws;
45  double *ktauToRaws;
46 
51  std::map<PidControlTypeEnum, PidUnits*> pid_units;
52 
53  explicit PrivateUnitsHandler(int size) :
54  axisMap(nullptr),
55  invAxisMap(nullptr),
56  verbose(true),
57  position_zeros(nullptr),
58  helper_ones(nullptr),
59  angleToEncoders(nullptr),
60  newtonsToSensors(nullptr),
61  ampereToSensors(nullptr),
62  voltToSensors(nullptr),
63  dutycycleToPWMs(nullptr),
64  bemfToRaws(nullptr),
65  ktauToRaws(nullptr),
66  PosPid_units(nullptr),
67  VelPid_units(nullptr),
68  CurPid_units(nullptr),
69  TrqPid_units(nullptr)
70  {
71  alloc(size);
72  std::fill_n(helper_ones, size, 1.0);
73  std::fill_n(position_zeros, size, 0.0);
74  std::fill_n(angleToEncoders, size, 1.0);
75  std::fill_n(newtonsToSensors, size, 1.0);
76  std::fill_n(ampereToSensors, size, 1.0);
77  std::fill_n(voltToSensors, size, 1.0);
78  std::fill_n(dutycycleToPWMs, size, 1.0);
79  std::fill_n(bemfToRaws, size, 1.0);
80  std::fill_n(ktauToRaws, size, 1.0);
81  }
82 
84  {
89  checkAndDestroy<double>(position_zeros);
90  checkAndDestroy<double>(helper_ones);
91  checkAndDestroy<int>(axisMap);
92  checkAndDestroy<int>(invAxisMap);
93  checkAndDestroy<double>(angleToEncoders);
94  checkAndDestroy<double>(newtonsToSensors);
95  checkAndDestroy<double>(ampereToSensors);
96  checkAndDestroy<double>(voltToSensors);
97  checkAndDestroy<double>(dutycycleToPWMs);
98  checkAndDestroy<double>(bemfToRaws);
99  checkAndDestroy<double>(ktauToRaws);
100  }
101 
102  void alloc(int n)
103  {
104  nj = n;
105  position_zeros = new double[nj];
106  helper_ones = new double[nj];
107  axisMap = new int[nj];
108  invAxisMap = new int[nj];
109  angleToEncoders = new double[nj];
110  newtonsToSensors = new double[nj];
111  ampereToSensors = new double[nj];
112  voltToSensors = new double[nj];
113  dutycycleToPWMs = new double[nj];
114  PosPid_units = new PidUnits[nj];
115  VelPid_units = new PidUnits[nj];
116  TrqPid_units = new PidUnits[nj];
117  CurPid_units = new PidUnits[nj];
118  bemfToRaws = new double[nj];
119  ktauToRaws = new double[nj];
120 
121  yAssert(position_zeros != nullptr);
122  yAssert(helper_ones != nullptr);
123  yAssert(axisMap != nullptr);
124  yAssert(invAxisMap != nullptr);
125  yAssert(angleToEncoders != nullptr);
126  yAssert(newtonsToSensors != nullptr);
127  yAssert(ampereToSensors != nullptr);
128  yAssert(voltToSensors != nullptr);
129  yAssert(dutycycleToPWMs != nullptr);
130  yAssert(PosPid_units != nullptr);
131  yAssert(VelPid_units != nullptr);
132  yAssert(TrqPid_units != nullptr);
133  yAssert(CurPid_units != nullptr);
134  yAssert(bemfToRaws != nullptr);
135  yAssert(ktauToRaws != nullptr);
136 
141  }
142 
144  {
145  alloc(other.nj);
146  memcpy(this->position_zeros, other.position_zeros, sizeof(*other.position_zeros)*nj);
147  memcpy(this->helper_ones, other.helper_ones, sizeof(*other.helper_ones)*nj);
148  memcpy(this->axisMap, other.axisMap, sizeof(*other.axisMap)*nj);
149  memcpy(this->invAxisMap, other.invAxisMap, sizeof(*other.invAxisMap)*nj);
150  memcpy(this->angleToEncoders, other.angleToEncoders, sizeof(*other.angleToEncoders)*nj);
151  memcpy(this->newtonsToSensors, other.newtonsToSensors, sizeof(*other.newtonsToSensors)*nj);
152  memcpy(this->ampereToSensors, other.ampereToSensors, sizeof(*other.ampereToSensors)*nj);
153  memcpy(this->voltToSensors, other.voltToSensors, sizeof(*other.voltToSensors)*nj);
154  memcpy(this->dutycycleToPWMs, other.dutycycleToPWMs, sizeof(*other.dutycycleToPWMs)*nj);
155  memcpy(this->PosPid_units, other.PosPid_units, sizeof(*other.PosPid_units)*nj);
156  memcpy(this->VelPid_units, other.VelPid_units, sizeof(*other.VelPid_units)*nj);
157  memcpy(this->TrqPid_units, other.TrqPid_units, sizeof(*other.TrqPid_units)*nj);
158  memcpy(this->CurPid_units, other.CurPid_units, sizeof(*other.CurPid_units)*nj);
159  memcpy(this->bemfToRaws, other.bemfToRaws, sizeof(*other.bemfToRaws)*nj);
160  memcpy(this->ktauToRaws, other.ktauToRaws, sizeof(*other.ktauToRaws)*nj);
161  }
162 };
163 
164 ControlBoardHelper::ControlBoardHelper(int n, const int *aMap, const double *angToEncs, const double *zs, const double *newtons, const double *amps, const double *volts, const double *dutycycles, const double *kbemf, const double *ktau)
165 {
166  yAssert(n>=0); // if number of joints is negative complain!
167  yAssert(aMap!=nullptr); // at least the axisMap is required
168  mPriv = new PrivateUnitsHandler(n);
169 
170  memcpy(mPriv->axisMap, aMap, sizeof(int)*n);
171 
172  if (zs!=nullptr) memcpy(mPriv->position_zeros, zs, sizeof(double)*n);
173  if (angToEncs!=nullptr) memcpy(mPriv->angleToEncoders, angToEncs, sizeof(double)*n);
174  if (newtons!=nullptr) memcpy(mPriv->newtonsToSensors, newtons, sizeof(double)*n);
175  if (amps!=nullptr) memcpy(mPriv->ampereToSensors, amps, sizeof(double)*n);
176  if (volts!=nullptr) memcpy(mPriv->voltToSensors, volts, sizeof(double)*n);
177  if (dutycycles != nullptr) memcpy(mPriv->dutycycleToPWMs, dutycycles, sizeof(double)*n);
178  if (kbemf != nullptr) memcpy(mPriv->bemfToRaws, kbemf, sizeof(double)*n);
179  if (ktau != nullptr) memcpy(mPriv->ktauToRaws, ktau, sizeof(double)*n);
180 
181  // invert the axis map
182  memset (mPriv->invAxisMap, 0, sizeof(int) * n);
183  int i;
184  for (i = 0; i < n; i++)
185  {
186  int j;
187  for (j = 0; j < n; j++)
188  {
189  if (mPriv->axisMap[j] == i)
190  {
191  mPriv->invAxisMap[i] = j;
192  break;
193  }
194  }
195  }
196 }
197 
199 {
200  if (mPriv) { delete mPriv; mPriv = nullptr; }
201 }
202 
204 {
205  mPriv = new PrivateUnitsHandler(*other.mPriv);
206 }
207 
209 {
210  mPriv = new PrivateUnitsHandler(*other.mPriv);
211  return *this;
212 }
213 
215 {
216  if( (id >= mPriv->nj) || (id< 0))
217  {
218  return false;
219  }
220  return true;
221 }
222 
223 
224 bool ControlBoardHelper::checkAxesIds(const int n_axes, const int* axesList)
225 {
226  if(n_axes > mPriv->nj)
227  {
228  if(mPriv->verbose)
229  yError("checkAxesIds: num of axes is too big");
230  return false;
231  }
232  for(int idx = 0; idx<n_axes; idx++)
233  {
234  if( (axesList[idx]<0) || (axesList[idx]>= mPriv->nj) )
235  {
236  if(mPriv->verbose)
237  yError("checkAxesIds: joint id out of bound");
238 
239  return false;
240  }
241  }
242  return true;
243 }
244 
246 { return mPriv->axisMap[axis]; }
247 
249 { return mPriv->invAxisMap[axis]; }
250 
251 //map a vector, no conversion
252  void ControlBoardHelper::toUser(const double *hwData, double *user)
253 {
254  for (int k=0;k<mPriv->nj;k++)
255  user[toUser(k)]=hwData[k];
256 }
257 
258 //map a vector, no conversion
259 void ControlBoardHelper::ControlBoardHelper::toUser(const int *hwData, int *user)
260 {
261  for (int k=0;k<mPriv->nj;k++)
262  user[toUser(k)]=hwData[k];
263 }
264 
265 //map a vector, no conversion
266  void ControlBoardHelper::toHw(const double *usr, double *hwData)
267 {
268  for (int k=0;k<mPriv->nj;k++)
269  hwData[toHw(k)]=usr[k];
270 }
271 
272 //map a vector, no conversion
273 void ControlBoardHelper::toHw(const int *usr, int *hwData)
274 {
275  for (int k=0;k<mPriv->nj;k++)
276  hwData[toHw(k)]=usr[k];
277 }
278 
279 void ControlBoardHelper::posA2E(double ang, int j, double &enc, int &k)
280 {
281  enc=(ang+ mPriv->position_zeros[j])*mPriv->angleToEncoders[j];
282  k=toHw(j);
283 }
284 
285 double ControlBoardHelper::posA2E(double ang, int j)
286 {
287  return (ang+ mPriv->position_zeros[j])*mPriv->angleToEncoders[j];
288 }
289 
290 void ControlBoardHelper::posE2A(double enc, int j, double &ang, int &k)
291 {
292  k=toUser(j);
293 
294  ang=(enc/ mPriv->angleToEncoders[k])- mPriv->position_zeros[k];
295 }
296 
297 double ControlBoardHelper::posE2A(double enc, int j)
298 {
299  int k=toUser(j);
300 
301  return (enc/ mPriv->angleToEncoders[k])- mPriv->position_zeros[k];
302 }
303 
304 void ControlBoardHelper::impN2S(double newtons, int j, double &sens, int &k)
305 {
306  sens=newtons* mPriv->newtonsToSensors[j]/ mPriv->angleToEncoders[j];
307  k=toHw(j);
308 }
309 
310 double ControlBoardHelper::impN2S(double newtons, int j)
311 {
312  return newtons* mPriv->newtonsToSensors[j]/ mPriv->angleToEncoders[j];
313 }
314 
315 void ControlBoardHelper::impN2S(const double *newtons, double *sens)
316 {
317  double tmp;
318  int index;
319  for(int j=0;j<mPriv->nj;j++)
320  {
321  impN2S(newtons[j], j, tmp, index);
322  sens[index]=tmp;
323  }
324 }
325 
326 void ControlBoardHelper::trqN2S(double newtons, int j, double &sens, int &k)
327 {
328  sens=newtons* mPriv->newtonsToSensors[j];
329  k=toHw(j);
330 }
331 
332 double ControlBoardHelper::trqN2S(double newtons, int j)
333 {
334  return newtons* mPriv->newtonsToSensors[j];
335 }
336 
337 //map a vector, convert from newtons to sensors
338 void ControlBoardHelper::trqN2S(const double *newtons, double *sens)
339 {
340  double tmp;
341  int index;
342  for(int j=0;j<mPriv->nj;j++)
343  {
344  trqN2S(newtons[j], j, tmp, index);
345  sens[index]=tmp;
346  }
347 }
348 
349 //map a vector, convert from sensor to newtons
350 void ControlBoardHelper::trqS2N(const double *sens, double *newtons)
351 {
352  double tmp;
353  int index;
354  for(int j=0;j<mPriv->nj;j++)
355  {
356  trqS2N(sens[j], j, tmp, index);
357  newtons[index]=tmp;
358  }
359 }
360 
361 void ControlBoardHelper::trqS2N(double sens, int j, double &newton, int &k)
362 {
363  k=toUser(j);
364  newton=(sens/ mPriv->newtonsToSensors[k]);
365 }
366 
367 double ControlBoardHelper::trqS2N(double sens, int j)
368 {
369  int k=toUser(j);
370  return (sens/ mPriv->newtonsToSensors[k]);
371 }
372 
373 void ControlBoardHelper::impS2N(const double *sens, double *newtons)
374 {
375  double tmp;
376  int index;
377  for(int j=0;j<mPriv->nj;j++)
378  {
379  impS2N(sens[j], j, tmp, index);
380  newtons[index]=tmp;
381  }
382 }
383 
384 void ControlBoardHelper::impS2N(double sens, int j, double &newton, int &k)
385 {
386  k=toUser(j);
387  newton=(sens/ mPriv->newtonsToSensors[k]* mPriv->angleToEncoders[k]);
388 }
389 
390 double ControlBoardHelper::impS2N(double sens, int j)
391 {
392  int k=toUser(j);
393 
394  return (sens/ mPriv->newtonsToSensors[k]* mPriv->angleToEncoders[k]);
395 }
396 
397 void ControlBoardHelper::velA2E(double ang, int j, double &enc, int &k)
398 {
399  k=toHw(j);
400  enc=ang* mPriv->angleToEncoders[j];
401 }
402 
403 double ControlBoardHelper::velA2E(double ang, int j)
404 {
405  return ang* mPriv->angleToEncoders[j];
406 }
407 
408 void ControlBoardHelper::velA2E_abs(double ang, int j, double &enc, int &k)
409 {
410  k=toHw(j);
411  enc=ang*fabs(mPriv->angleToEncoders[j]);
412 }
413 
414 void ControlBoardHelper::velE2A(double enc, int j, double &ang, int &k)
415 {
416  k=toUser(j);
417  ang=enc/ mPriv->angleToEncoders[k];
418 }
419 
420 void ControlBoardHelper::velE2A_abs(double enc, int j, double &ang, int &k)
421 {
422  k=toUser(j);
423  ang=enc/fabs(mPriv->angleToEncoders[k]);
424 }
425 
426 void ControlBoardHelper::accA2E(double ang, int j, double &enc, int &k)
427 {
428  velA2E(ang, j, enc, k);
429 }
430 
431 void ControlBoardHelper::accA2E_abs(double ang, int j, double &enc, int &k)
432 {
433  velA2E_abs(ang, j, enc, k);
434 }
435 
436 void ControlBoardHelper::accE2A(double enc, int j, double &ang, int &k)
437 {
438  velE2A(enc, j, ang, k);
439 }
440 
441 void ControlBoardHelper::accE2A_abs(double enc, int j, double &ang, int &k)
442 {
443  velE2A_abs(enc, j, ang, k);
444 }
445 
446 double ControlBoardHelper::velE2A(double enc, int j)
447 {
448  int k=toUser(j);
449  return enc/ mPriv->angleToEncoders[k];
450 }
451 
452 double ControlBoardHelper::velE2A_abs(double enc, int j)
453 {
454  int k=toUser(j);
455  return enc/fabs(mPriv->angleToEncoders[k]);
456 }
457 
458 
459 double ControlBoardHelper::accE2A(double enc, int j)
460 {
461  return velE2A(enc, j);
462 }
463 
464 double ControlBoardHelper::accE2A_abs(double enc, int j)
465 {
466  return velE2A_abs(enc, j);
467 }
468 
469 //map a vector, convert from angles to encoders
470 void ControlBoardHelper::posA2E(const double *ang, double *enc)
471 {
472  double tmp;
473  int index;
474  for(int j=0;j<mPriv->nj;j++)
475  {
476  posA2E(ang[j], j, tmp, index);
477  enc[index]=tmp;
478  }
479 }
480 
481 //map a vector, convert from encoders to angles
482 void ControlBoardHelper::posE2A(const double *enc, double *ang)
483 {
484  double tmp;
485  int index;
486  for(int j=0;j<mPriv->nj;j++)
487  {
488  posE2A(enc[j], j, tmp, index);
489  ang[index]=tmp;
490  }
491 }
492 
493 void ControlBoardHelper::velA2E(const double *ang, double *enc)
494 {
495  double tmp;
496  int index;
497  for(int j=0;j<mPriv->nj;j++)
498  {
499  velA2E(ang[j], j, tmp, index);
500  enc[index]=tmp;
501  }
502 }
503 
504 void ControlBoardHelper::velA2E_abs(const double *ang, double *enc)
505 {
506  double tmp;
507  int index;
508  for(int j=0;j<mPriv->nj;j++)
509  {
510  velA2E_abs(ang[j], j, tmp, index);
511  enc[index]=tmp;
512  }
513 }
514 
515 void ControlBoardHelper::velE2A(const double *enc, double *ang)
516 {
517  double tmp;
518  int index;
519  for(int j=0;j<mPriv->nj;j++)
520  {
521  velE2A(enc[j], j, tmp, index);
522  ang[index]=tmp;
523  }
524 }
525 
526 void ControlBoardHelper::velE2A_abs(const double *enc, double *ang)
527 {
528  double tmp;
529  int index;
530  for(int j=0;j<mPriv->nj;j++)
531  {
532  velE2A_abs(enc[j], j, tmp, index);
533  ang[index]=tmp;
534  }
535 }
536 
537 void ControlBoardHelper::accA2E(const double *ang, double *enc)
538 {
539  double tmp;
540  int index;
541  for(int j=0;j<mPriv->nj;j++)
542  {
543  accA2E(ang[j], j, tmp, index);
544  enc[index]=tmp;
545  }
546 }
547 
548 void ControlBoardHelper::accA2E_abs(const double *ang, double *enc)
549 {
550  double tmp;
551  int index;
552  for(int j=0;j<mPriv->nj;j++)
553  {
554  accA2E_abs(ang[j], j, tmp, index);
555  enc[index]=tmp;
556  }
557 }
558 
559 void ControlBoardHelper::accE2A(const double *enc, double *ang)
560 {
561  double tmp;
562  int index;
563  for(int j=0;j<mPriv->nj;j++)
564  {
565  accE2A(enc[j], j, tmp, index);
566  ang[index]=tmp;
567  }
568 }
569 
570 void ControlBoardHelper::accE2A_abs(const double *enc, double *ang)
571 {
572  double tmp;
573  int index;
574  for(int j=0;j<mPriv->nj;j++)
575  {
576  accE2A_abs(enc[j], j, tmp, index);
577  ang[index]=tmp;
578  }
579 }
580 
581 //***************** current ******************//
582 void ControlBoardHelper::ampereA2S(double ampere, int j, double &sens, int &k)
583 {
584  sens=ampere* mPriv->ampereToSensors[j];
585  k=toHw(j);
586 }
587 
588 double ControlBoardHelper::ampereA2S(double ampere, int j)
589 {
590  return ampere* mPriv->ampereToSensors[j];
591 }
592 
593 //map a vector, convert from ampere to sensors
594 void ControlBoardHelper::ampereA2S(const double *ampere, double *sens)
595 {
596  double tmp;
597  int index;
598  for(int j=0;j<mPriv->nj;j++)
599  {
600  ampereA2S(ampere[j], j, tmp, index);
601  sens[index]=tmp;
602  }
603 }
604 
605 //map a vector, convert from sensor to ampere
606 void ControlBoardHelper::ampereS2A(const double *sens, double *ampere)
607 {
608  double tmp;
609  int index;
610  for(int j=0;j<mPriv->nj;j++)
611  {
612  ampereS2A(sens[j], j, tmp, index);
613  ampere[index]=tmp;
614  }
615 }
616 
617 void ControlBoardHelper::ampereS2A(double sens, int j, double &ampere, int &k)
618 {
619  k=toUser(j);
620  ampere=(sens/ mPriv->ampereToSensors[k]);
621 }
622 
623 double ControlBoardHelper::ampereS2A(double sens, int j)
624 {
625  int k=toUser(j);
626  return sens/ mPriv->ampereToSensors[k];
627 }
628 // *******************************************//
629 
630 //***************** voltage ******************//
631 void ControlBoardHelper::voltageV2S(double voltage, int j, double &sens, int &k)
632 {
633  sens=voltage* mPriv->voltToSensors[j];
634  k=toHw(j);
635 }
636 
637 double ControlBoardHelper::voltageV2S(double voltage, int j)
638 {
639  return voltage* mPriv->voltToSensors[j];
640 }
641 
642 //map a vector, convert from voltage to sensors
643 void ControlBoardHelper::voltageV2S(const double *voltage, double *sens)
644 {
645  double tmp;
646  int index;
647  for(int j=0;j<mPriv->nj;j++)
648  {
649  voltageV2S(voltage[j], j, tmp, index);
650  sens[index]=tmp;
651  }
652 }
653 
654 //map a vector, convert from sensor to newtons
655 void ControlBoardHelper::voltageS2V(const double *sens, double *voltage)
656 {
657  double tmp;
658  int index;
659  for(int j=0;j<mPriv->nj;j++)
660  {
661  voltageS2V(sens[j], j, tmp, index);
662  voltage[index]=tmp;
663  }
664 }
665 
666 void ControlBoardHelper::voltageS2V(double sens, int j, double &voltage, int &k)
667 {
668  k=toUser(j);
669  voltage=(sens/ mPriv->voltToSensors[k]);
670 }
671 
672 double ControlBoardHelper::voltageS2V(double sens, int j)
673 {
674  int k=toUser(j);
675  return (sens/ mPriv->voltToSensors[k]);
676 }
677 // *******************************************//
678 
679 //***************** dutycycle ******************//
680 void ControlBoardHelper::dutycycle2PWM(double dutycycle, int j, double &pwm, int &k)
681 {
682  pwm = dutycycle* mPriv->dutycycleToPWMs[j];
683  k = toHw(j);
684 }
685 
686 double ControlBoardHelper::dutycycle2PWM(double dutycycle, int j)
687 {
688  return dutycycle* mPriv->dutycycleToPWMs[j];
689 }
690 
691 void ControlBoardHelper::dutycycle2PWM(const double *dutycycle, double *sens)
692 {
693  double tmp;
694  int index;
695  for (int j = 0; j<mPriv->nj; j++)
696  {
697  dutycycle2PWM(dutycycle[j], j, tmp, index);
698  sens[index] = tmp;
699  }
700 }
701 
702 void ControlBoardHelper::PWM2dutycycle(const double *pwm, double *dutycycle)
703 {
704  double tmp;
705  int index;
706  for (int j = 0; j<mPriv->nj; j++)
707  {
708  PWM2dutycycle(pwm[j], j, tmp, index);
709  dutycycle[index] = tmp;
710  }
711 }
712 
713 void ControlBoardHelper::PWM2dutycycle(double pwm_raw, int k_raw, double &dutycycle, int &j)
714 {
715  j = toUser(k_raw);
716  dutycycle = (pwm_raw / mPriv->dutycycleToPWMs[j]);
717 }
718 
719 double ControlBoardHelper::PWM2dutycycle(double pwm_raw, int k_raw)
720 {
721  int j = toUser(k_raw);
722  return (pwm_raw / mPriv->dutycycleToPWMs[j]);
723 }
724 
725 // *******************************************//
726 void ControlBoardHelper::bemf_user2raw(double bemf_user, int j, double &bemf_raw, int &k)
727 {
728  bemf_raw = bemf_user * mPriv->bemfToRaws[j];
729  k = toHw(j);
730 }
731 
732 void ControlBoardHelper::ktau_user2raw(double ktau_user, int j, double &ktau_raw, int &k)
733 {
734  ktau_raw = ktau_user * mPriv->ktauToRaws[j];
735  k = toHw(j);
736 }
737 
738 void ControlBoardHelper::bemf_raw2user(double bemf_raw, int k_raw, double &bemf_user, int &j_user)
739 {
740  j_user = toUser(k_raw);
741  bemf_user = bemf_raw / mPriv->bemfToRaws[j_user];
742 }
743 
744 void ControlBoardHelper::ktau_raw2user(double ktau_raw, int k_raw, double &ktau_user, int &j_user)
745 {
746  j_user = toUser(k_raw);
747  ktau_user = ktau_raw / mPriv->ktauToRaws[j_user];
748 }
749 
750 double ControlBoardHelper::bemf_user2raw(double bemf_user, int j)
751 {
752  return bemf_user * mPriv->bemfToRaws[j];
753 }
754 
755 double ControlBoardHelper::ktau_user2raw(double ktau_user, int j)
756 {
757  return ktau_user * mPriv->ktauToRaws[j];
758 }
759 
760 // *******************************************//
761 
763 { return mPriv->nj; }
764 
765 // *******************************************//
766 
768 {
769  double output_conversion_factor;
770  switch (mPriv->pid_units[pidtype][j].out_units)
771  {
772  case PidOutputUnitsEnum::DUTYCYCLE_PWM_PERCENT: output_conversion_factor = mPriv->dutycycleToPWMs[j]; break;
773  case PidOutputUnitsEnum::CURRENT_METRIC: output_conversion_factor = mPriv->ampereToSensors[j]; break;
774  case PidOutputUnitsEnum::POSITION_METRIC: output_conversion_factor = mPriv->angleToEncoders[j]; break;
775  case PidOutputUnitsEnum::VELOCITY_METRIC: output_conversion_factor = mPriv->angleToEncoders[j]; break;
776  case PidOutputUnitsEnum::TORQUE_METRIC: output_conversion_factor = mPriv->newtonsToSensors[j]; break;
777  case PidOutputUnitsEnum::RAW_MACHINE_UNITS:
778  default: output_conversion_factor = mPriv->helper_ones[j]; break;
779  }
780  return output_conversion_factor;
781 }
782 
784 {
785  double feedback_conversion_factor = 0.0;
786  switch (mPriv->pid_units[pidtype][j].fbk_units)
787  {
789  switch (pidtype)
790  {
791  case yarp::dev::PidControlTypeEnum::VOCAB_PIDTYPE_POSITION: feedback_conversion_factor = mPriv->angleToEncoders[j]; break;
792  case yarp::dev::PidControlTypeEnum::VOCAB_PIDTYPE_VELOCITY: feedback_conversion_factor = mPriv->angleToEncoders[j]; break;
793  case yarp::dev::PidControlTypeEnum::VOCAB_PIDTYPE_TORQUE: feedback_conversion_factor = mPriv->newtonsToSensors[j]; break;
794  case yarp::dev::PidControlTypeEnum::VOCAB_PIDTYPE_CURRENT: feedback_conversion_factor = mPriv->ampereToSensors[j]; break;
795  }
796  break;
797  case PidFeedbackUnitsEnum::RAW_MACHINE_UNITS:
798  default: feedback_conversion_factor = mPriv->helper_ones[j]; break;
799  }
800  return (1.0 / feedback_conversion_factor);
801 }
802 void ControlBoardHelper::convert_pid_to_user(const yarp::dev::PidControlTypeEnum& pidtype, const Pid &in_raw, int j_raw, Pid &out_usr, int &k_usr)
803 {
804  ControlBoardHelper* cb_helper = this;
805  k_usr = cb_helper->toUser(j_raw);
806  out_usr = in_raw;
807 
808  //feedback is at the denominator, i.e. kp=[PWM/deg]
809  double feedback_conversion_units_user2raw = get_pidfeedback_conversion_factor_user2raw(pidtype, k_usr);
810  out_usr.kp = out_usr.kp / feedback_conversion_units_user2raw;
811  out_usr.ki = out_usr.ki / feedback_conversion_units_user2raw;
812  out_usr.kd = out_usr.kd / feedback_conversion_units_user2raw;
813 
814  //output is at the numerator, i.e. kp=[PWM/deg]
815  double output_conversion_units_user2raw = get_pidoutput_conversion_factor_user2raw(pidtype, k_usr);
816  out_usr.kp = out_usr.kp / output_conversion_units_user2raw;
817  out_usr.ki = out_usr.ki / output_conversion_units_user2raw;
818  out_usr.kd = out_usr.kd / output_conversion_units_user2raw;
819  out_usr.max_output = out_usr.max_output / output_conversion_units_user2raw;
820  out_usr.max_int = out_usr.max_int / output_conversion_units_user2raw;
821  out_usr.stiction_up_val = out_usr.stiction_up_val / output_conversion_units_user2raw;
822  out_usr.stiction_down_val = out_usr.stiction_down_val / output_conversion_units_user2raw;
823  out_usr.offset = out_usr.offset / output_conversion_units_user2raw;
824 }
825 
827 {
828  Pid tmp;
829  int tmp_k;
830  convert_pid_to_machine(pidtype, in_usr, j_usr, tmp, tmp_k);
831  return tmp;
832 }
833 
834 void ControlBoardHelper::convert_pid_to_machine(const yarp::dev::PidControlTypeEnum& pidtype, const Pid &in_usr, int j_usr, Pid &out_raw, int &k_raw)
835 {
836  ControlBoardHelper* cb_helper = this;
837  k_raw = cb_helper->toHw(j_usr);
838  out_raw = in_usr;
839 
840  //feedback is at the denominator, i.e. kp=[PWM/deg]
841  double feedback_conversion_units_user2raw = get_pidfeedback_conversion_factor_user2raw(pidtype, j_usr);
842  out_raw.kp = out_raw.kp * feedback_conversion_units_user2raw;
843  out_raw.ki = out_raw.ki * feedback_conversion_units_user2raw;
844  out_raw.kd = out_raw.kd * feedback_conversion_units_user2raw;
845 
846  //output is at the numerator, i.e. kp=[PWM/deg]
847  double output_conversion_units_user2raw = get_pidoutput_conversion_factor_user2raw(pidtype, j_usr);
848  out_raw.kp = out_raw.kp * output_conversion_units_user2raw;
849  out_raw.ki = out_raw.ki * output_conversion_units_user2raw;
850  out_raw.kd = out_raw.kd * output_conversion_units_user2raw;
851  out_raw.max_output = out_raw.max_output * output_conversion_units_user2raw;
852  out_raw.max_int = out_raw.max_int * output_conversion_units_user2raw;
853  out_raw.stiction_up_val = out_raw.stiction_up_val * output_conversion_units_user2raw;
854  out_raw.stiction_down_val = out_raw.stiction_down_val * output_conversion_units_user2raw;
855  out_raw.offset = out_raw.offset * output_conversion_units_user2raw;
856 }
857 
858 void ControlBoardHelper::convert_pidunits_to_machine(const yarp::dev::PidControlTypeEnum& pidtype, double userval, int j, double &machineval, int &k)
859 {
860  ControlBoardHelper* cb_helper = this;
861  switch (pidtype)
862  {
864  //Beware:posA2E employs zeros, not only angleToEncoders
865  //This is fine if convert_pidunits_to_machine() is called by methods that are aware of this feature, that is intentional.
866  cb_helper->posA2E(userval, j, machineval, k);
867  break;
869  cb_helper->velA2E(userval, j, machineval, k);
870  break;
872  cb_helper->trqN2S(userval, j, machineval, k);
873  break;
875  cb_helper->ampereA2S(userval, j, machineval, k);
876  break;
877  default:
878  yError() << "convert_units_to_machine: invalid pidtype";
879  break;
880  }
881 }
882 
883 void ControlBoardHelper::convert_pidunits_to_machine(const yarp::dev::PidControlTypeEnum& pidtype, const double* userval, double* machineval)
884 {
885  ControlBoardHelper* cb_helper = this;
886  switch (pidtype)
887  {
889  //Beware:posA2E employs zeros, not only angleToEncoders
890  //This is fine if convert_pidunits_to_machine() is called by methods that are aware of this feature, that is intentional.
891  cb_helper->posA2E(userval, machineval);
892  break;
894  cb_helper->velA2E(userval, machineval);
895  break;
897  cb_helper->trqN2S(userval, machineval);
898  break;
900  cb_helper->ampereA2S(userval, machineval);
901  break;
902  default:
903  yError() << "convert_units_to_machine: invalid pidtype";
904  break;
905  }
906 }
907 
908 void ControlBoardHelper::convert_pidunits_to_user(const yarp::dev::PidControlTypeEnum& pidtype, const double machineval, double* userval, int k)
909 {
910  ControlBoardHelper* cb_helper = this;
911  switch (pidtype)
912  {
914  //Beware:posE2A employs zeros, not only angleToEncoders.
915  //This is fine if convert_pidunits_to_user() is called by methods that are aware of this feature, that is intentional.
916  *userval = cb_helper->posE2A(machineval, k);
917  break;
919  *userval = cb_helper->velE2A(machineval, k);
920  break;
922  *userval = cb_helper->trqS2N(machineval, k);
923  break;
925  *userval = cb_helper->ampereS2A(machineval, k);
926  break;
927  default:
928  yError() << "convert_units_to_machine: invalid pidtype";
929  break;
930  }
931 }
932 
933 void ControlBoardHelper::convert_pidunits_to_user(const yarp::dev::PidControlTypeEnum& pidtype, const double* machineval, double* userval)
934 {
935  ControlBoardHelper* cb_helper = this;
936  switch (pidtype)
937  {
939  //Beware:posE2A employs zeros, not only angleToEncoders.
940  //This is fine if convert_pidunits_to_user() is called by methods that are aware of this feature, that is intentional.
941  cb_helper->posE2A(machineval, userval);
942  break;
944  cb_helper->velE2A(machineval, userval);
945  break;
947  cb_helper->trqS2N(machineval, userval);
948  break;
950  cb_helper->ampereS2A(machineval, userval);
951  break;
952  default:
953  yError() << "convert_units_to_machine: invalid pidtype";
954  break;
955  }
956 }
957 
958 void ControlBoardHelper::set_pid_conversion_units(const PidControlTypeEnum& pidtype, const PidFeedbackUnitsEnum fbk_conv_units, const PidOutputUnitsEnum out_conv_units)
959 {
960  ControlBoardHelper* cb_helper = this;
961  int nj = cb_helper->axes();
962  for (int i = 0; i < nj; i++)
963  {
964  mPriv->pid_units[pidtype][i].fbk_units = fbk_conv_units;
965  mPriv->pid_units[pidtype][i].out_units = out_conv_units;
966  }
967 }
yarp::dev::ControlBoardHelper::PrivateUnitsHandler::dutycycleToPWMs
double * dutycycleToPWMs
Definition: ControlBoardHelper.cpp:43
LogStream.h
yarp::dev::ControlBoardHelper::convert_pidunits_to_machine
void convert_pidunits_to_machine(const yarp::dev::PidControlTypeEnum &pidtype, double userval, int j, double &machineval, int &k)
Definition: ControlBoardHelper.cpp:858
yarp::dev::ControlBoardHelper::velE2A
void velE2A(double enc, int j, double &ang, int &k)
Definition: ControlBoardHelper.cpp:414
yarp::dev::ControlBoardHelper::toHw
int toHw(int axis)
Definition: ControlBoardHelper.cpp:245
yarp::dev::ControlBoardHelper::PrivateUnitsHandler
Definition: ControlBoardHelper.cpp:30
yarp::dev::ControlBoardHelper::PrivateUnitsHandler::newtonsToSensors
double * newtonsToSensors
Definition: ControlBoardHelper.cpp:40
yarp::dev::ControlBoardHelper::convert_pid_to_machine
void convert_pid_to_machine(const yarp::dev::PidControlTypeEnum &pidtype, const Pid &in_usr, int j_usr, Pid &out_raw, int &k_raw)
Definition: ControlBoardHelper.cpp:834
yarp::dev::ControlBoardHelper::PrivateUnitsHandler::ktauToRaws
double * ktauToRaws
Definition: ControlBoardHelper.cpp:45
yarp::dev::ControlBoardHelper::posE2A
void posE2A(double enc, int j, double &ang, int &k)
Definition: ControlBoardHelper.cpp:290
yarp::dev::ControlBoardHelper::bemf_user2raw
double bemf_user2raw(double bemf_user, int j)
Definition: ControlBoardHelper.cpp:750
yarp::dev::ControlBoardHelper::get_pidoutput_conversion_factor_user2raw
double get_pidoutput_conversion_factor_user2raw(const yarp::dev::PidControlTypeEnum &pidtype, int j)
Definition: ControlBoardHelper.cpp:767
yarp::dev::Pid::stiction_up_val
double stiction_up_val
up stiction offset added to the pid output
Definition: ControlBoardPid.h:38
yarp::dev::VOCAB_PIDTYPE_CURRENT
@ VOCAB_PIDTYPE_CURRENT
Definition: PidEnums.h:25
yarp::dev::ControlBoardHelper::toUser
int toUser(int axis)
Definition: ControlBoardHelper.cpp:248
yarp::dev::ControlBoardHelper::checkAxesIds
bool checkAxesIds(const int n_axes, const int *axesList)
Definition: ControlBoardHelper.cpp:224
yarp::dev::ControlBoardHelper::velA2E_abs
void velA2E_abs(double ang, int j, double &enc, int &k)
Definition: ControlBoardHelper.cpp:408
yarp::dev::ControlBoardHelper::PrivateUnitsHandler::CurPid_units
PidUnits * CurPid_units
Definition: ControlBoardHelper.cpp:49
yarp::dev::ControlBoardHelper::PrivateUnitsHandler::PrivateUnitsHandler
PrivateUnitsHandler(int size)
Definition: ControlBoardHelper.cpp:53
yarp::dev::PidOutputUnitsEnum::RAW_MACHINE_UNITS
@ RAW_MACHINE_UNITS
yarp::dev::Pid::max_output
double max_output
max output
Definition: ControlBoardPid.h:36
yarp::dev::VOCAB_PIDTYPE_POSITION
@ VOCAB_PIDTYPE_POSITION
Definition: PidEnums.h:22
yarp::dev::ControlBoardHelper::operator=
ControlBoardHelper & operator=(const ControlBoardHelper &other)
Definition: ControlBoardHelper.cpp:208
yarp::dev::ControlBoardHelper::dutycycle2PWM
void dutycycle2PWM(double dutycycle, int j, double &pwm, int &k)
Definition: ControlBoardHelper.cpp:680
yarp::dev::ControlBoardHelper::ampereS2A
void ampereS2A(const double *sens, double *ampere)
Definition: ControlBoardHelper.cpp:606
yarp::dev::PidOutputUnitsEnum
PidOutputUnitsEnum
Definition: PidEnums.h:37
yarp::dev::ControlBoardHelper::ampereA2S
void ampereA2S(double ampere, int j, double &sens, int &k)
Definition: ControlBoardHelper.cpp:582
yarp::dev::Pid::ki
double ki
integrative gain
Definition: ControlBoardPid.h:33
yarp::dev::ControlBoardHelper::PrivateUnitsHandler::nj
int nj
Definition: ControlBoardHelper.cpp:32
yarp::dev::ControlBoardHelper::PrivateUnitsHandler::verbose
bool verbose
Definition: ControlBoardHelper.cpp:35
PidUnits::PidUnits
PidUnits()
Definition: ControlBoardHelper.cpp:23
PidEnums.h
yError
#define yError(...)
Definition: Log.h:282
yarp::dev
An interface for the device drivers.
Definition: audioBufferSizeData.cpp:17
yarp::dev::ControlBoardHelper::PrivateUnitsHandler::PosPid_units
PidUnits * PosPid_units
Definition: ControlBoardHelper.cpp:47
yarp::dev::ControlBoardHelper::PrivateUnitsHandler::voltToSensors
double * voltToSensors
Definition: ControlBoardHelper.cpp:42
yarp::dev::ControlBoardHelper::PrivateUnitsHandler::helper_ones
double * helper_ones
Definition: ControlBoardHelper.cpp:38
Log.h
yarp::dev::ControlBoardHelper::PrivateUnitsHandler::alloc
void alloc(int n)
Definition: ControlBoardHelper.cpp:102
yarp::dev::VOCAB_PIDTYPE_TORQUE
@ VOCAB_PIDTYPE_TORQUE
Definition: PidEnums.h:24
yarp::dev::Pid::offset
double offset
pwm offset added to the pid output
Definition: ControlBoardPid.h:37
yarp::dev::Pid::max_int
double max_int
saturation threshold for the integrator
Definition: ControlBoardPid.h:34
yarp::dev::ControlBoardHelper::velE2A_abs
void velE2A_abs(double enc, int j, double &ang, int &k)
Definition: ControlBoardHelper.cpp:420
yarp::dev::ControlBoardHelper::checkAxisId
bool checkAxisId(int id)
Definition: ControlBoardHelper.cpp:214
yarp::dev::ControlBoardHelper::ControlBoardHelper
ControlBoardHelper(int n, const int *aMap, const double *angToEncs=nullptr, const double *zs=nullptr, const double *newtons=nullptr, const double *amps=nullptr, const double *volts=nullptr, const double *dutycycles=nullptr, const double *kbemf=nullptr, const double *ktau=nullptr)
Definition: ControlBoardHelper.cpp:164
yarp::dev::ControlBoardHelper::PrivateUnitsHandler::ampereToSensors
double * ampereToSensors
Definition: ControlBoardHelper.cpp:41
yarp::dev::ControlBoardHelper::posA2E
void posA2E(double ang, int j, double &enc, int &k)
Definition: ControlBoardHelper.cpp:279
yarp::dev::PidControlTypeEnum
PidControlTypeEnum
Definition: PidEnums.h:21
yarp::dev::ControlBoardHelper::voltageS2V
void voltageS2V(const double *sens, double *voltage)
Definition: ControlBoardHelper.cpp:655
yarp::dev::Pid::kd
double kd
derivative gain
Definition: ControlBoardPid.h:32
yarp::dev::Pid::kp
double kp
proportional gain
Definition: ControlBoardPid.h:31
yarp::dev::ControlBoardHelper::PrivateUnitsHandler::PrivateUnitsHandler
PrivateUnitsHandler(const PrivateUnitsHandler &other)
Definition: ControlBoardHelper.cpp:143
yarp::dev::ControlBoardHelper::impS2N
void impS2N(const double *sens, double *newtons)
Definition: ControlBoardHelper.cpp:373
yarp::dev::ControlBoardHelper::voltageV2S
void voltageV2S(double voltage, int j, double &sens, int &k)
Definition: ControlBoardHelper.cpp:631
yarp::dev::ControlBoardHelper::PrivateUnitsHandler::TrqPid_units
PidUnits * TrqPid_units
Definition: ControlBoardHelper.cpp:50
PidUnits::out_units
PidOutputUnitsEnum out_units
Definition: ControlBoardHelper.cpp:22
yarp::dev::ControlBoardHelper::ktau_user2raw
double ktau_user2raw(double ktau_user, int j)
Definition: ControlBoardHelper.cpp:755
yarp::dev::ControlBoardHelper::PrivateUnitsHandler::position_zeros
double * position_zeros
Definition: ControlBoardHelper.cpp:37
yarp::dev::ControlBoardHelper::PrivateUnitsHandler::axisMap
int * axisMap
Definition: ControlBoardHelper.cpp:33
yarp::dev::VOCAB_PIDTYPE_VELOCITY
@ VOCAB_PIDTYPE_VELOCITY
Definition: PidEnums.h:23
ControlBoardHelper.h
yarp::dev::ControlBoardHelper::impN2S
void impN2S(double newtons, int j, double &sens, int &k)
Definition: ControlBoardHelper.cpp:304
PidUnits
Definition: ControlBoardHelper.cpp:20
yarp::dev::ControlBoardHelper::PrivateUnitsHandler::~PrivateUnitsHandler
~PrivateUnitsHandler()
Definition: ControlBoardHelper.cpp:83
PidUnits::fbk_units
PidFeedbackUnitsEnum fbk_units
Definition: ControlBoardHelper.cpp:21
yarp::dev::ControlBoardHelper::PrivateUnitsHandler::bemfToRaws
double * bemfToRaws
Definition: ControlBoardHelper.cpp:44
yarp::dev::Pid::stiction_down_val
double stiction_down_val
down stiction offset added to the pid output
Definition: ControlBoardPid.h:39
yarp::dev::ControlBoardHelper::accA2E
void accA2E(double ang, int j, double &enc, int &k)
Definition: ControlBoardHelper.cpp:426
yarp::dev::ControlBoardHelper::trqN2S
void trqN2S(double newtons, int j, double &sens, int &k)
Definition: ControlBoardHelper.cpp:326
yarp::dev::ControlBoardHelper::velA2E
void velA2E(double ang, int j, double &enc, int &k)
Definition: ControlBoardHelper.cpp:397
checkAndDestroy
void checkAndDestroy(T *&p)
Definition: ControlBoardHelper.h:45
yarp::dev::ControlBoardHelper::accE2A_abs
void accE2A_abs(double enc, int j, double &ang, int &k)
Definition: ControlBoardHelper.cpp:441
yarp::dev::PidFeedbackUnitsEnum
PidFeedbackUnitsEnum
Definition: PidEnums.h:31
yarp::dev::ControlBoardHelper::accA2E_abs
void accA2E_abs(double ang, int j, double &enc, int &k)
Definition: ControlBoardHelper.cpp:431
yarp::dev::ControlBoardHelper::~ControlBoardHelper
~ControlBoardHelper()
Definition: ControlBoardHelper.cpp:198
yarp::dev::PidFeedbackUnitsEnum::RAW_MACHINE_UNITS
@ RAW_MACHINE_UNITS
yarp::dev::ControlBoardHelper
Definition: ControlBoardHelper.h:60
yarp::dev::ControlBoardHelper::PrivateUnitsHandler::invAxisMap
int * invAxisMap
Definition: ControlBoardHelper.cpp:34
yarp::dev::ControlBoardHelper::convert_pid_to_user
void convert_pid_to_user(const yarp::dev::PidControlTypeEnum &pidtype, const Pid &in_raw, int j_raw, Pid &out_usr, int &k_usr)
Definition: ControlBoardHelper.cpp:802
yarp::dev::ControlBoardHelper::get_pidfeedback_conversion_factor_user2raw
double get_pidfeedback_conversion_factor_user2raw(const yarp::dev::PidControlTypeEnum &pidtype, int j)
Definition: ControlBoardHelper.cpp:783
yarp::dev::ControlBoardHelper::accE2A
void accE2A(double enc, int j, double &ang, int &k)
Definition: ControlBoardHelper.cpp:436
yarp::dev::ControlBoardHelper::PrivateUnitsHandler::VelPid_units
PidUnits * VelPid_units
Definition: ControlBoardHelper.cpp:48
yarp::dev::ControlBoardHelper::trqS2N
void trqS2N(const double *sens, double *newtons)
Definition: ControlBoardHelper.cpp:350
yarp::dev::Pid
Contains the parameters for a PID.
Definition: ControlBoardPid.h:29
yarp::dev::ControlBoardHelper::axes
int axes()
Definition: ControlBoardHelper.cpp:762
yarp::dev::ControlBoardHelper::set_pid_conversion_units
void set_pid_conversion_units(const PidControlTypeEnum &pidtype, const PidFeedbackUnitsEnum fbk_conv_units, const PidOutputUnitsEnum out_conv_units)
Definition: ControlBoardHelper.cpp:958
yarp::dev::ControlBoardHelper::bemf_raw2user
void bemf_raw2user(double bemf_raw, int k_raw, double &bemf_user, int &j_user)
Definition: ControlBoardHelper.cpp:738
yAssert
#define yAssert(x)
Definition: Log.h:297
yarp::dev::ControlBoardHelper::ktau_raw2user
void ktau_raw2user(double ktau_raw, int k_raw, double &ktau_user, int &j_user)
Definition: ControlBoardHelper.cpp:744
yarp::dev::ControlBoardHelper::PWM2dutycycle
void PWM2dutycycle(const double *pwm, double *dutycycle)
Definition: ControlBoardHelper.cpp:702
yarp::dev::ControlBoardHelper::convert_pidunits_to_user
void convert_pidunits_to_user(const yarp::dev::PidControlTypeEnum &pidtype, const double machineval, double *userval, int k)
Definition: ControlBoardHelper.cpp:908
yarp::dev::ControlBoardHelper::PrivateUnitsHandler::pid_units
std::map< PidControlTypeEnum, PidUnits * > pid_units
Definition: ControlBoardHelper.cpp:51
yarp::dev::ControlBoardHelper::PrivateUnitsHandler::angleToEncoders
double * angleToEncoders
Definition: ControlBoardHelper.cpp:39