MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
elec.cc
Go to the documentation of this file.
1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/mbdyn/elec/elec.cc,v 1.60 2017/01/12 14:46:22 masarati Exp $ */
2 /*
3  * MBDyn (C) is a multibody analysis code.
4  * http://www.mbdyn.org
5  *
6  * Copyright (C) 1996-2017
7  *
8  * Pierangelo Masarati <masarati@aero.polimi.it>
9  * Paolo Mantegazza <mantegazza@aero.polimi.it>
10  *
11  * Dipartimento di Ingegneria Aerospaziale - Politecnico di Milano
12  * via La Masa, 34 - 20156 Milano, Italy
13  * http://www.aero.polimi.it
14  *
15  * Changing this copyright notice is forbidden.
16  *
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation (version 2 of the License).
20  *
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */
31 
32 /* Elementi elettrici */
33 
34 #include "mbconfig.h" /* This goes first in every *.c,*.cc file */
35 
36 #include "elec.h"
37 #include "elecnode.h"
38 #include "drive.h"
39 #include "strnode.h"
40 #include "accelerometer.h"
41 #include "displacement.h"
42 #include "motor.h"
43 #include "dataman.h"
44 #include "discctrl.h"
45 
46 /* Electric - begin */
47 
48 Electric::Electric(unsigned int uL,
49  const DofOwner* pDO, flag fOut)
50 : Elem(uL, fOut),
51 ElemWithDofs(uL, pDO, fOut)
52 {
53  NO_OP;
54 }
55 
57 {
58  NO_OP;
59 }
60 
61 /* Contributo al file di restart
62  * (Nota: e' incompleta, deve essere chiamata dalla funzione corrispndente
63  * relativa alla classe derivata */
64 std::ostream&
65 Electric::Restart(std::ostream& out) const
66 {
67  return out << " electric: " << GetLabel();
68 }
69 
70 
71 /* Tipo dell'elemento (usato solo per debug ecc.) */
74 {
75  return Elem::ELECTRIC;
76 }
77 
78 /* Electric - end */
79 
80 /* Legge un forgetting factor */
81 
83 ReadFF(MBDynParser& HP, integer iNumOutputs)
84 {
85  ForgettingFactor* pFF = 0;
86 
87  if (HP.IsKeyWord("forgetting" "factor")) {
88  if (HP.IsKeyWord("const")) {
89  doublereal d = HP.GetReal();
90 
93 
94  } else if (HP.IsKeyWord("dynamic")) {
95  integer n1 = HP.GetInt();
96  integer n2 = HP.GetInt();
97  doublereal dRho = HP.GetReal();
98  doublereal dFact = HP.GetReal();
99  doublereal dKRef = HP.GetReal();
100  doublereal dKLim = HP.GetReal();
101 
103  DynamicForgettingFactor2(n1, n2, iNumOutputs,
104  dRho, dFact, dKRef, dKLim));
105 
106  } else {
107  silent_cerr("Unknown forgetting factor type "
108  "at line " << HP.GetLineData() << std::endl);
110  }
111 
112  } else {
113  /* default */
116  }
117 
118  ASSERT(pFF != 0);
119  return pFF;
120 }
121 
122 /* Legge un eccitatore persistente */
123 
125 ReadPX(DataManager* pDM, MBDynParser& HP, integer iNumInputs)
126 {
127  PersistentExcitation* pPX = 0;
128 
129  if (HP.IsKeyWord("excitation")) {
130  if (iNumInputs == 1) {
131  DriveCaller* pDC = HP.GetDriveCaller();
133 
134  } else {
135  DriveCaller** ppDC = 0;
136  SAFENEWARR(ppDC, DriveCaller*, iNumInputs);
137 
138  for (integer i = iNumInputs; i-- > 0; ) {
139  ppDC[i] = HP.GetDriveCaller();
140  }
141  SAFENEWWITHCONSTRUCTOR(pPX, VectorPX, VectorPX(iNumInputs, ppDC));
142  }
143 
144  } else {
145  /* Null excitation */
146  SAFENEW(pPX, NullPX);
147  }
148 
149  ASSERT(pPX != 0);
150  return pPX;
151 }
152 
153 /* Legge un elemento elettrico */
154 
155 Elem *
157  MBDynParser& HP,
158  const DofOwner* pDO,
159  unsigned int uLabel)
160 {
161  DEBUGCOUTFNAME("ReadElectric()");
162 
163  const char* sKeyWords[] = {
164  "accelerometer",
165  "displacement",
166  "motor",
167  "discrete" "control",
168  "identification",
169  "control",
170  "adaptive" "control",
171  NULL
172  };
173 
174  // enum delle parole chiave
175  enum KeyWords {
176  UNKNOWN = -1,
177 
178  ACCELEROMETER = 0,
179  DISPLACEMENT,
180 
181  MOTOR,
182 
183  DISCRETECONTROL,
184  IDENTIFICATION,
185  CONTROL,
186  ADAPTIVECONTROL,
187 
189  };
190 
191  // tabella delle parole chiave
192  KeyTable K(HP, sKeyWords);
193 
194  // lettura del tipo di elemento elettrico
195  KeyWords CurrKeyWord = KeyWords(HP.GetWord());
196 
197  Elem* pEl = 0;
198 
199  switch (CurrKeyWord) {
200  case ACCELEROMETER: {
201  int f = 0;
202  if (HP.IsKeyWord("translational")) {
203  f = 1;
204  } else if(HP.IsKeyWord("rotational")) {
205  f = 2;
206  }
207 
208  if (f) {
209  // TODO: check if downgradable to ScalarNode
210 
211  // nodo strutturale collegato
212  const StructNode* pStrNode
213  = pDM->ReadNode<const StructNode, Node::STRUCTURAL>(HP);
214 
215  // nodo astratto collegato
216  const ScalarDifferentialNode* pAbsNode
218 
219  // Direzione
220  Vec3 Dir;
221  try {
222  Dir = HP.GetUnitVecRel(ReferenceFrame(pStrNode));
223  } catch (ErrNullNorm) {
224  silent_cerr("Accelerometer(" << uLabel << "): "
225  "null direction "
226  "at line " << HP.GetLineData()
227  << std::endl);
229  }
230  DEBUGCOUT("Direction: " << std::endl << Dir << std::endl);
231 
232  // offset
233  Vec3 Tmpf(Zero3);
234  if (HP.IsKeyWord("position") || HP.IsKeyWord("offset") || f == 1) {
235  Tmpf = HP.GetPosRel(ReferenceFrame(pStrNode));
236  }
237  flag fOut = pDM->fReadOutput(HP, Elem::ELECTRIC);
238 
239  switch (f) {
240  case 1:
242  TranslAccel(uLabel, pDO,
243  pStrNode, pAbsNode,
244  Dir, Tmpf, fOut));
245  break;
246 
247  case 2:
249  RotAccel(uLabel, pDO,
250  pStrNode, pAbsNode,
251  Dir, fOut));
252  break;
253 
254  default:
255  silent_cerr("you shouldn't be here!" << std::endl);
257  }
258 
259  } else {
260 
261  // nodo strutturale collegato
262  const StructNode* pStrNode
263  = pDM->ReadNode<const StructNode, Node::STRUCTURAL>(HP);
264 
265  // nodo astratto collegato
266  const ScalarDifferentialNode* pAbsNode
268 
269  // Direzione
270  Vec3 Dir;
271  try {
272  Dir = HP.GetUnitVecRel(ReferenceFrame(pStrNode));
273  } catch (ErrNullNorm) {
274  silent_cerr("Accelerometer(" << uLabel << "): "
275  "null direction "
276  "at line " << HP.GetLineData()
277  << std::endl);
279  }
280  DEBUGCOUT("Direction: " << std::endl << Dir << std::endl);
281 
282  // Parametri
283  doublereal dOmega = HP.GetReal();
284  if (dOmega <= 0.) {
285  silent_cerr("Accelerometer(" << uLabel << "): "
286  "illegal Omega "
287  "at line " << HP.GetLineData()
288  << std::endl);
290  }
291 
292  doublereal dTau = HP.GetReal();
293  if (dTau <= 0.) {
294  silent_cerr("Accelerometer(" << uLabel << "): "
295  "illegal Tau "
296  "at line " << HP.GetLineData()
297  << std::endl);
299  }
300 
301  doublereal dCsi = HP.GetReal();
302  if (dCsi <= 0. || dCsi > 1.) {
303  silent_cerr("Accelerometer(" << uLabel << "): "
304  "illegal Csi "
305  "at line " << HP.GetLineData()
306  << std::endl);
308  }
309 
310  doublereal dKappa = HP.GetReal();
311  if (dKappa == 0.) {
312  silent_cerr("Accelerometer(" << uLabel << "): "
313  "illegal Kappa "
314  "at line " << HP.GetLineData()
315  << std::endl);
317  }
318 
319  DEBUGCOUT("Omega: " << dOmega
320  << ", Tau: " << dTau
321  << ", Csi: " << dCsi
322  << ", Kappa: " << dKappa
323  << std::endl);
324 
325  flag fOut = pDM->fReadOutput(HP, Elem::ELECTRIC);
326 
328  Accelerometer(uLabel, pDO, pStrNode, pAbsNode,
329  Dir, dOmega, dTau, dCsi, dKappa,
330  fOut));
331  }
332 
333  } break;
334 
335  case DISPLACEMENT: {
336  // nodo strutturale collegato 1
337  const StructNode* pStrNode1
338  = pDM->ReadNode<const StructNode, Node::STRUCTURAL>(HP);
339 
340  // offset 1
341  Vec3 Tmpf1(Zero3);
342  if (HP.IsKeyWord("position")) {
343  NO_OP;
344  }
345  Tmpf1 = HP.GetPosRel(ReferenceFrame(pStrNode1));
346 
347  // nodo strutturale collegato 2
348  const StructNode* pStrNode2
349  = pDM->ReadNode<const StructNode, Node::STRUCTURAL>(HP);
350 
351  // offset 2
352  Vec3 Tmpf2(Zero3);
353  if (HP.IsKeyWord("position")) {
354  NO_OP;
355  }
356  Tmpf2 = HP.GetPosRel(ReferenceFrame(pStrNode2));
357 
358  // nodo astratto collegato
359  const ScalarDifferentialNode* pAbsNode
361 
362  flag fOut = pDM->fReadOutput(HP, Elem::ELECTRIC);
363 
365  DispMeasure(uLabel, pDO,
366  pStrNode1, pStrNode2, pAbsNode,
367  Tmpf1, Tmpf2, fOut));
368  } break;
369 
370  case MOTOR: {
371  // nodo strutturale collegato 1
372  const StructNode* pStrNode1
373  = pDM->ReadNode<const StructNode, Node::STRUCTURAL>(HP);
374 
375  // nodo strutturale collegato 2
376  const StructNode* pStrNode2
377  = pDM->ReadNode<const StructNode, Node::STRUCTURAL>(HP);
378 
379  // direzione
380  Mat3x3 Rn(Zero3x3);
381  bool bHaveOrientation = false;
382 
383  if (HP.IsKeyWord("orientation")) {
384  Rn = HP.GetRotRel(ReferenceFrame(pStrNode1));
385  bHaveOrientation = true;
386  } else { // FIXME
387  try {
388  // FIXME: The current implemention of the motor requires a rotation matrix instead of an axis.
389  // FIXME: In order to maintain backward compatibility a rotation matrix has to be synthesised here.
390  const Vec3 e3 = HP.GetUnitVecRel(ReferenceFrame(pStrNode1));
391  Vec3 e1(Zero3);
392 
393  doublereal e1n = -1;
394 
395  for (integer i = 1; i <= 3; ++i) {
396  const Vec3 e1t = Eye3.GetCol(i).Cross(e3);
397  const doublereal e1tn = e1t.Norm();
398 
399  if (e1tn > e1n) {
400  e1 = e1t;
401  e1n = e1tn;
402  }
403  }
404 
405  if (e1n <= 0) {
407  }
408 
409  e1 /= e1n;
410  Vec3 e2 = e3.Cross(e1);
411  e2 /= e2.Norm();
412 
413  Rn = Mat3x3(e1, e2, e3);
414  } catch (ErrNullNorm) {
415  silent_cerr("Motor(" << uLabel << "): "
416  "illegal motor direction "
417  "at line " << HP.GetLineData()
418  << std::endl);
420  }
421  }
422 
423  ASSERT(Eye3.IsSame(Rn.MulTM(Rn), sqrt(std::numeric_limits<doublereal>::epsilon())));
424 
425  // nodo elettrico1 collegato
426  ElectricNode* pVoltage1
427  = dynamic_cast<ElectricNode *>(pDM->ReadNode(HP, Node::ELECTRIC));
428 
429  // nodo elettrico2 collegato
430  ElectricNode* pVoltage2
431  = dynamic_cast<ElectricNode *>(pDM->ReadNode(HP, Node::ELECTRIC));
432 
433  doublereal dG = HP.GetReal();
434  doublereal dL = HP.GetReal();
435  DriveCaller* dR = HP.GetDriveCaller();
436  doublereal i0 = 0;
437 
438  if (HP.IsKeyWord("initial" "current")) {
439  i0 = HP.GetReal();
440  }
441 
442  bool bHaveM0orM1 = false;
443 
444  DriveCaller* pM0 = 0;
445 
446  if (HP.IsKeyWord("M0")) {
447  bHaveM0orM1 = true;
448  pM0 = HP.GetDriveCaller();
449  } else {
450  pM0 = new NullDriveCaller;
451  }
452 
453  DriveCaller* pM1 = 0;
454 
455  if (HP.IsKeyWord("M1")) {
456  bHaveM0orM1 = true;
457  pM1 = HP.GetDriveCaller();
458  } else {
459  pM1 = new NullDriveCaller;
460  }
461 
462  integer p = 0;
463 
464  if (bHaveM0orM1) {
465  if (!bHaveOrientation) {
466  silent_cerr("motor(" << uLabel
467  << "): \"M0\" and \"M1\" require rotation matrix instead of axis at line " << HP.GetLineData() << std::endl);
469  }
470 
471  if (!HP.IsKeyWord("terminal" "pairs")) {
472  silent_cerr("motor(" << uLabel << "): keyword \"terminal pairs\" expected at line "
473  << HP.GetLineData() << std::endl);
475  }
476 
477  p = HP.GetInt();
478 
479  if (p < 1) {
480  silent_cerr("motor(" << uLabel
481  << "): number of terminal pairs must be greater than zero at line "
482  << HP.GetLineData() << std::endl);
484  }
485  }
486 
487  flag fOut = pDM->fReadOutput(HP, Elem::ELECTRIC);
488 
490  Motor(uLabel, pDO,
491  pStrNode1, pStrNode2, pVoltage1, pVoltage2,
492  Rn, dG, dL, dR, i0, p, pM0, pM1, fOut));
493  } break;
494 
495  case DISCRETECONTROL: {
496  // Dati generali del controllore
497  integer iNumOutputs = HP.GetInt();
498  integer iNumInputs = HP.GetInt();
499  integer iOrderA = HP.GetInt();
500  integer iOrderB = iOrderA;
501  if (HP.IsKeyWord("fir")) {
502  iOrderB = HP.GetInt();
503  }
504 
505  integer iNumIter = HP.GetInt();
506 
507  DEBUGCOUT("Discrete controller of order " << iOrderA);
508  if (iOrderB != iOrderA) {
509  DEBUGCOUT(" (fir order " << iOrderB << ')' << std::endl);
510  }
511  DEBUGCOUT(": " << iNumOutputs << " output(s) and "
512  << iNumInputs << " input(s)" << std::endl
513  << "Update every " << iNumIter << " iterations" << std::endl);
514 
515  // Tipo di controllo
516  DiscreteControlProcess* pDCP = 0;
517  switch (HP.GetWord()) {
518  case CONTROL: {
519  // Add the file with control data
520  const char* s = HP.GetFileName();
521  std::string infile = s;
522 
523  DEBUGCOUT("Getting control matrices "
524  "from file \"" << infile << "\""
525  << std::endl);
526 
527  /* Construction of controller */
531  iNumInputs,
532  iOrderA,
533  iOrderB,
534  infile));
535  } break;
536 
537  case IDENTIFICATION: {
539  if (HP.IsKeyWord("arx")) {
541 
542  } else if (HP.IsKeyWord("armax")) {
544 
545  } else {
546  silent_cerr("DiscreteControl(" << uLabel << "): "
547  "unknown identification type "
548  "at line " << HP.GetLineData() << std::endl);
550  }
551 
552  // Forgetting factor
553  ForgettingFactor* pFF = ReadFF(HP, iNumOutputs);
554 
555  // Persistent excitation
556  PersistentExcitation* pPX = ReadPX(pDM, HP, iNumInputs);
557 
558  std::string outfile;
559  if (HP.IsKeyWord("file")) {
560  const char *s = HP.GetFileName();
561  outfile = s;
562  }
563 
564  /* Construction of controller */
567  DiscreteIdentProcess_Debug(iNumOutputs,
568  iNumInputs,
569  iOrderA,
570  iOrderB,
571  pFF, pPX,
572  f_proc, outfile));
573  } break;
574 
575  case ADAPTIVECONTROL: {
576 #ifdef USE_DBC
577  unsigned f_proc = DiscreteControlProcess::DISCPROC_ARX;
578  doublereal dPeriodicFactor(0.);
579 
580  if (HP.IsKeyWord("arx")) {
581  DEBUGCOUT("ARX adaptive control" << std::endl);
583 
584  } else if (HP.IsKeyWord("armax")) {
585  DEBUGCOUT("ARMAX adaptive control" << std::endl);
587  }
588 
589  if (HP.IsKeyWord("periodic")) {
590  dPeriodicFactor = HP.GetReal();
591  }
592 
593  GPCDesigner* pCD = 0;
594  if (HP.IsKeyWord("gpc")) {
595  DEBUGCOUT("GPC adaptive control" << std::endl);
596 
597  integer iPredS = HP.GetInt();
598  integer iContrS = HP.GetInt();
599  integer iPredH = HP.GetInt();
600  integer iContrH = 0;
601 
602  DEBUGCOUT("prediction advancing horizon: " << iPredS << std::endl
603  << "prediction receding horizon: " << iPredH << std::endl
604  << "control advancing horizon: " << iContrS << std::endl
605  << "control receding horizon: " << iContrH << std::endl);
606 
607  if (iPredS < 0) {
608  silent_cerr("DiscreteControl(" << uLabel << "): "
609  "prediction advancing horizon "
610  "must be positive "
611  "at line " << HP.GetLineData()
612  << std::endl);
614  }
615 
616  if (iPredH < 0) {
617  silent_cerr("DiscreteControl(" << uLabel << "): "
618  "prediction receding horizon "
619  "must be positive "
620  "at line " << HP.GetLineData()
621  << std::endl);
623  }
624 
625  if (iPredH >= iPredS) {
626  silent_cerr("DiscreteControl(" << uLabel << "): "
627  "prediction receding horizon "
628  "must be less than "
629  "prediction advancing horizon "
630  "at line " << HP.GetLineData()
631  << std::endl);
633  }
634 
635  if (iContrS < 0) {
636  silent_cerr("DiscreteControl(" << uLabel << "): "
637  "control advancing horizon "
638  "must be positive "
639  "at line " << HP.GetLineData()
640  << std::endl);
642  }
643 
644  doublereal* pW = 0;
645  doublereal* pR = 0;
646  SAFENEWARR(pW, doublereal, iPredS - iPredH);
647  SAFENEWARR(pR, doublereal, iContrS - iContrH);
648 
649  if (HP.IsKeyWord("prediction" "weights")) {
650  DEBUGCOUT("prediction weights:" << std::endl);
651  for (integer i = iPredS - iPredH; i-- > 0; ) {
652  pW[i] = HP.GetReal();
653  DEBUGCOUT("W[" << i + 1 << "] = " << pW[i] << std::endl);
654  }
655 
656  } else {
657  for (integer i = 0; i < iPredS - iPredH; i++) {
658  pW[i] = 1.;
659  }
660  }
661 
662  if (HP.IsKeyWord("control" "weights")) {
663  DEBUGCOUT("control weights:" << std::endl);
664  for (integer i = iContrS - iContrH; i-- > 0; ) {
665  pR[i] = HP.GetReal();
666  DEBUGCOUT("R[" << i + 1 << "] = " << pR[i] << std::endl);
667  }
668  } else {
669  for (integer i = 0; i < iContrS-iContrH; i++) {
670  pR[i] = 1.;
671  }
672  }
673 
674  DEBUGCOUT("Weight Drive:" << std::endl);
675  DriveCaller* pLambda = HP.GetDriveCaller();
676 
678  GPC(iNumOutputs, iNumInputs,
679  iOrderA, iOrderB,
680  iPredS, iContrS,
681  iPredH, iContrH,
682  pW, pR, pLambda,
683  dPeriodicFactor, f_proc));
684 
685  } else if (HP.IsKeyWord("deadbeat")) {
686  DEBUGCOUT("DeadBeat adaptive control" << std::endl);
687 
688  int iPredS = HP.GetInt();
689  int iContrS = HP.GetInt();
690  SAFENEWWITHCONSTRUCTOR(pCD, DeadBeat,
691  DeadBeat(iNumOutputs, iNumInputs,
692  iOrderA, iOrderB,
693  iPredS, iContrS,
694  dPeriodicFactor, f_proc));
695 
696  } else {
697  silent_cerr("DiscreteControl(" << uLabel << "): "
698  "unknown adaptive control type at line " << HP.GetLineData() << std::endl);
700  }
701 
702  // Forgetting factor
703  DEBUGCOUT("Forgetting Factor:" << std::endl);
704  ForgettingFactor* pFF = ReadFF(HP, iNumOutputs);
705 
706  // Persistent excitation
707  DEBUGCOUT("Persistent Excitation:" << std::endl);
708  PersistentExcitation* pPX = ReadPX(pDM, HP, iNumInputs);
709 
710  DriveCaller* pTrig = 0;
711  if (HP.IsKeyWord("trigger")) {
712  DEBUGCOUT("Trigger:" << std::endl);
713  pTrig = HP.GetDriveCaller();
714  } else {
715  SAFENEW(pTrig, OneDriveCaller);
716  }
717 
718  // desired output
719  std::vector<DriveCaller*> vDesiredOut;
720  if (HP.IsKeyWord("desired" "output")) {
721  DEBUGCOUT("Desired output:" << std::endl);
722  vDesiredOut.resize(iNumOutputs);
723 
724  for (integer i = 0; i < iNumOutputs; i++) {
725  DEBUGCOUT("output[" << i + 1 << "]:" << std::endl);
726  vDesiredOut[i] = HP.GetDriveCaller();
727  }
728  }
729 
730  std::string outfile;
731  if (HP.IsKeyWord("file") || HP.IsKeyWord("output" "file")) {
732  const char *s = HP.GetFileName();
733  outfile = s;
734  DEBUGCOUT("Identified matrices will be output in file \"" << s << "\"" << std::endl);
735  }
736 
737  /* Construction of controller */
741  DAC_Process_Debug(iNumOutputs, iNumInputs,
742  iOrderA, iOrderB,
743  pFF, pCD, pPX, pTrig, vDesiredOut,
744  outfile, f_proc));
745 #else /* !USE_DBC */
746  silent_cerr("DiscreteControl(" << uLabel << "): "
747  "GPC/deadbeat control is not available "
748  "at line " << HP.GetLineData() << std::endl);
750 #endif /* !USE_DBC */
751  } break;
752 
753  default:
754  silent_cerr("Sorry, not implemented yed" << std::endl);
756  }
757 
758 
759 
760  if (!HP.IsKeyWord("outputs")) {
761  silent_cerr("DiscreteControl(" << uLabel << "): "
762  "\"outputs\" expected "
763  "at line " << HP.GetLineData()
764  << std::endl);
765 
767  }
768 
769  std::vector<ScalarValue *> vOutputs(iNumOutputs);
770  std::vector<DriveCaller *> vOutScaleFact(iNumOutputs);
771 
772  // Allocazione nodi e connessioni
773  for (int i = 0; i < iNumOutputs; i++) {
774  vOutputs[i] = ReadScalarValue(pDM, HP);
775  if (HP.IsKeyWord("scale")) {
776  vOutScaleFact[i] = HP.GetDriveCaller();
777 
778  } else {
779  vOutScaleFact[i] = 0;
780  SAFENEW(vOutScaleFact[i], OneDriveCaller);
781  }
782  }
783 
784  if (!HP.IsKeyWord("inputs")) {
785  silent_cerr("DiscreteControl(" << uLabel << "): "
786  "\"inputs\" expected "
787  "at line " << HP.GetLineData()
788  << std::endl);
790  }
791 
792  // Same thing for input nodes
793  ScalarDof* pInputs = 0;
794  SAFENEWARRNOFILL(pInputs, ScalarDof, iNumInputs);
795 
796  // Allocazione nodi e connessioni
797  for (int i = 0; i < iNumInputs; i++) {
798  pInputs[i] = ReadScalarDof(pDM, HP, false, true);
799  }
800 
801  flag fOut = pDM->fReadOutput(HP, Elem::ELECTRIC);
802 
804  DiscreteControlElem(uLabel, pDO,
805  iNumOutputs, vOutputs, vOutScaleFact,
806  iNumInputs, pInputs,
807  pDCP, iNumIter, fOut));
808  } break;
809 
810  // Aggiungere altri elementi elettrici
811 
812  default:
813  silent_cerr("Electric(" << uLabel << "): "
814  "unknown type "
815  "at line " << HP.GetLineData()
816  << std::endl);
818  }
819 
820  // Se non c'e' il punto e virgola finale
821  if (HP.IsArg()) {
822  silent_cerr("semicolon expected at line " << HP.GetLineData() << std::endl);
824  }
825 
826  return pEl;
827 } /* ReadElectric() */
828 
flag fReadOutput(MBDynParser &HP, const T &t) const
Definition: dataman.h:1064
Mat3x3 GetRotRel(const ReferenceFrame &rf)
Definition: mbpar.cc:1795
const Vec3 Zero3(0., 0., 0.)
Vec3 Cross(const Vec3 &v) const
Definition: matvec3.h:218
long int flag
Definition: mbdyn.h:43
#define MBDYN_EXCEPT_ARGS
Definition: except.h:63
Definition: matvec3.h:98
ForgettingFactor * ReadFF(MBDynParser &HP, integer iNumOutputs)
Definition: elec.cc:83
#define DEBUGCOUTFNAME(fname)
Definition: myassert.h:256
virtual integer GetInt(integer iDefval=0)
Definition: parser.cc:1050
doublereal Norm(void) const
Definition: matvec3.h:263
Definition: px.h:57
const Mat3x3 Eye3(1., 0., 0., 0., 1., 0., 0., 0., 1.)
virtual const char * GetFileName(enum Delims Del=DEFAULTDELIM)
Definition: parsinc.cc:673
Vec3 GetCol(unsigned short int i) const
Definition: matvec3.h:903
Electric(unsigned int uL, const DofOwner *pDO, flag fOut)
Definition: elec.cc:48
virtual Elem::Type GetElemType(void) const
Definition: elec.cc:73
#define NO_OP
Definition: myassert.h:74
const Mat3x3 Zero3x3(0., 0., 0., 0., 0., 0., 0., 0., 0.)
virtual ~Electric(void)
Definition: elec.cc:56
#define SAFENEW(pnt, item)
Definition: mynewmem.h:695
Vec3 GetPosRel(const ReferenceFrame &rf)
Definition: mbpar.cc:1331
virtual bool IsKeyWord(const char *sKeyWord)
Definition: parser.cc:910
ScalarValue * ReadScalarValue(DataManager *pDM, MBDynParser &HP)
Definition: scalarvalue.cc:80
static int outfile
#define DEBUGCOUT(msg)
Definition: myassert.h:232
PersistentExcitation * ReadPX(DataManager *pDM, MBDynParser &HP, integer iNumInputs)
Definition: elec.cc:125
#define ASSERT(expression)
Definition: colamd.c:977
Definition: px.h:68
GradientExpression< UnaryExpr< FuncSqrt, Expr > > sqrt(const GradientExpression< Expr > &u)
Definition: gradient.h:2974
KeyWords
Definition: dataman4.cc:94
Definition: motor.h:64
#define SAFENEWWITHCONSTRUCTOR(pnt, item, constructor)
Definition: mynewmem.h:698
Elem * ReadElectric(DataManager *pDM, MBDynParser &HP, const DofOwner *pDO, unsigned int uLabel)
Definition: elec.cc:156
virtual bool IsArg(void)
Definition: parser.cc:807
Definition: elem.h:75
Type
Definition: elem.h:91
#define SAFENEWARRNOFILL(pnt, item, sz)
Definition: mynewmem.h:704
virtual int GetWord(void)
Definition: parser.cc:1083
virtual std::ostream & Restart(std::ostream &out) const
Definition: elec.cc:65
#define SAFENEWARR(pnt, item, sz)
Definition: mynewmem.h:701
DriveCaller * GetDriveCaller(bool bDeferred=false)
Definition: mbpar.cc:2033
Definition: gpc.h:272
Definition: px.h:49
Vec3 GetUnitVecRel(const ReferenceFrame &rf)
Definition: mbpar.cc:1695
double doublereal
Definition: colamd.c:52
long int integer
Definition: colamd.c:51
virtual HighParser::ErrOut GetLineData(void) const
Definition: parsinc.cc:697
unsigned int GetLabel(void) const
Definition: withlab.cc:62
Node * ReadNode(MBDynParser &HP, Node::Type type) const
Definition: dataman3.cc:2309
ScalarDof ReadScalarDof(const DataManager *pDM, MBDynParser &HP, bool bDof, bool bOrder)
Definition: dataman3.cc:2423
bool IsSame(const Mat3x3 &m, const doublereal &dTol) const
Definition: matvec3.h:1249
virtual doublereal GetReal(const doublereal &dDefval=0.0)
Definition: parser.cc:1056