iCub-main
embObjMotionControl.cpp
Go to the documentation of this file.
1 // -*- Mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-
2 
3 /*
4 * Copyright (C) 2012 iCub Facility, Istituto Italiano di Tecnologia
5 * Authors: Alberto Cardellino
6 * CopyPolicy: Released under the terms of the LGPLv2.1 or later, see LGPL.TXT
7 *
8 */
9 
10 //#include <yarp/dev/CanBusInterface.h>
11 #include <yarp/os/Bottle.h>
12 #include <yarp/os/Time.h>
13 #include <string.h>
14 #include <iostream>
15 #include <cmath>
16 
17 #include "embObjMotionControl.h"
18 #include <ethManager.h>
19 #include <FeatureInterface.h>
20 #include <yarp/conf/environment.h>
21 
22 #include <yarp/os/LogStream.h>
23 
24 #include "EoCommon.h"
25 #include "EOarray.h"
26 #include "EoProtocol.h"
27 #include "EoProtocolMN.h"
28 #include "EoProtocolMC.h"
29 #include "EoProtocolAS.h"
31 
32 #include <yarp/os/NetType.h>
33 #include <yarp/dev/ControlBoardHelper.h>
34 
35 
36 #include "eomcUtils.h"
37 
38 using namespace yarp::dev;
39 using namespace yarp::os;
40 using namespace yarp::os::impl;
41 
42 
43 
44 using namespace yarp::dev::eomc;
45 
46 
47 // macros
48 #define ASK_REFERENCE_TO_FIRMWARE 1
49 
50 #define PARSER_MOTION_CONTROL_VERSION 6
51 
52 
53 
54 
55 
56 static inline bool NOT_YET_IMPLEMENTED(const char *txt)
57 {
58  yError() << txt << " is not yet implemented for embObjMotionControl";
59  return true;
60 }
61 
62 static inline bool DEPRECATED(const char *txt)
63 {
64  yError() << txt << " has been deprecated for embObjMotionControl";
65  return true;
66 }
67 
68 #define NV_NOT_FOUND return nv_not_found();
69 
70 static bool nv_not_found(void)
71 {
72  yError () << " nv_not_found!! This may mean that this variable is not handled by this EMS\n";
73  return false;
74 }
75 
76 static constexpr double const temperatureErrorValue_s = -5000;
77 
78 
79 
80 
81 std::string embObjMotionControl::getBoardInfo(void)
82 {
83  if(nullptr == res)
84  {
85  return " BOARD name_unknown (IP unknown) ";
86  }
87  else
88  {
89  return ("BOARD " + res->getProperties().boardnameString + " (IP " + res->getProperties().ipv4addrString + ") ");
90  }
91 }
92 
93 
94 bool embObjMotionControl::alloc(int nj)
95 {
96  _axisMap = allocAndCheck<int>(nj);
97 
98  _encodersStamp = allocAndCheck<double>(nj);
99  _gearbox_M2J = allocAndCheck<double>(nj);
100  _gearbox_E2J = allocAndCheck<double>(nj);
101  _deadzone = allocAndCheck<double>(nj);
102  _foc_based_info= allocAndCheck<eomc::focBasedSpecificInfo_t>(nj);
103  _trj_pids= new eomc::PidInfo[nj];
104  //_dir_pids= new eomc::PidInfo[nj];
105  _trq_pids= new eomc::TrqPidInfo [nj];
106  _cur_pids= new eomc::PidInfo[nj];
107  _spd_pids= new eomc::PidInfo[nj];
108  _impedance_limits=allocAndCheck<eomc::impedanceLimits_t>(nj);
109  checking_motiondone=allocAndCheck<bool>(nj);
110  _last_position_move_time=allocAndCheck<double>(nj);
111 
112  // Reserve space for data stored locally. values are initialize to 0
113  _ref_command_positions = allocAndCheck<double>(nj);
114  _ref_positions = allocAndCheck<double>(nj);
115  _ref_command_speeds = allocAndCheck<double>(nj);
116  _ref_speeds = allocAndCheck<double>(nj);
117  _ref_accs = allocAndCheck<double>(nj);
118 
119  _enabledAmp = allocAndCheck<bool>(nj);
120  _enabledPid = allocAndCheck<bool>(nj);
121  _calibrated = allocAndCheck<bool>(nj);
122  _cacheImpedance = allocAndCheck<eOmc_impedance_t>(nj);
123 
124  _rotorsLimits.resize(nj);
125  _jointsLimits.resize(nj);
126  _currentLimits.resize(nj);
127  _temperatureLimits.resize(nj);
128  _jsets.resize(nj);
129  _joint2set.resize(nj);
130  _timeouts.resize(nj);
131  _impedance_params.resize(nj);
132  _axesInfo.resize(nj);
133  _jointEncs.resize(nj);
134  _motorEncs.resize(nj);
135  _kalman_params.resize(nj);
136  _temperatureSensorsVector.resize(nj);
137  _temperatureExceededLimitWatchdog.resize(nj);
138  _temperatureSensorErrorWatchdog.resize(nj);
139 
140  return true;
141 }
142 
143 bool embObjMotionControl::dealloc()
144 {
145  checkAndDestroy(_axisMap);
146  checkAndDestroy(_encodersStamp);
147  checkAndDestroy(_gearbox_M2J);
148  checkAndDestroy(_gearbox_E2J);
149  checkAndDestroy(_deadzone);
150  checkAndDestroy(_impedance_limits);
151  checkAndDestroy(checking_motiondone);
152  checkAndDestroy(_ref_command_positions);
153  checkAndDestroy(_ref_positions);
154  checkAndDestroy(_ref_command_speeds);
155  checkAndDestroy(_ref_speeds);
156  checkAndDestroy(_ref_accs);
157 
158  checkAndDestroy(_enabledAmp);
159  checkAndDestroy(_enabledPid);
160  checkAndDestroy(_calibrated);
161  checkAndDestroy(_foc_based_info);
162 
163  if(_trj_pids)
164  delete [] _trj_pids;
165 
166  //if(_dir_pids)
167  // delete [] _dir_pids;
168 
169  if(_trq_pids)
170  delete [] _trq_pids;
171 
172  if(_cur_pids)
173  delete [] _cur_pids;
174 
175  if (_spd_pids)
176  delete[] _spd_pids;
177 
178 
179  return true;
180 }
181 
183  ImplementControlCalibration(this),
184  ImplementAmplifierControl(this),
185  ImplementPidControl(this),
186  ImplementEncodersTimed(this),
187  ImplementPositionControl(this),
188  ImplementVelocityControl(this),
189  ImplementControlMode(this),
190  ImplementImpedanceControl(this),
191  ImplementMotorEncoders(this),
192 #ifdef IMPLEMENT_DEBUG_INTERFACE
194 #endif
195  ImplementTorqueControl(this),
196  ImplementControlLimits(this),
197  ImplementPositionDirect(this),
198  ImplementInteractionMode(this),
199  ImplementMotor(this),
200  ImplementRemoteVariables(this),
201  ImplementAxisInfo(this),
202  ImplementPWMControl(this),
203  ImplementCurrentControl(this),
204  ImplementJointFault(this),
205  SAFETY_THRESHOLD(2.0),
206  _rotorsLimits(0),
207  _jointsLimits(0),
208  _currentLimits(0),
209  _temperatureLimits(0),
210  _jsets(0),
211  _joint2set(0),
212  _timeouts(0),
213  _impedance_params(0),
214  _axesInfo(0),
215  _jointEncs(0),
216  _motorEncs(0),
217  _kalman_params(0),
218  _temperatureSensorsVector(0),
219  _temperatureExceededLimitWatchdog(0),
220  _temperatureSensorErrorWatchdog(0)
221 {
222  _gearbox_M2J = 0;
223  _gearbox_E2J = 0;
224  _deadzone = 0;
225  opened = 0;
226  _trj_pids = NULL;
227  //_dir_pids = NULL;
228  _trq_pids = NULL;
229  _cur_pids = NULL;
230  _spd_pids = NULL;
231  res = NULL;
232  _njoints = 0;
233  _axisMap = NULL;
234  _encodersStamp = NULL;
235  _foc_based_info = NULL;
236  _cacheImpedance = NULL;
237  _impedance_limits = NULL;
238  _ref_accs = NULL;
239  _ref_command_speeds = NULL;
240  _ref_command_positions= NULL;
241  _ref_positions = NULL;
242  _ref_speeds = NULL;
243  _measureConverter = NULL;
244 
245  checking_motiondone = NULL;
246  // debug connection
247  //tot_packet_recv = 0;
248  //errors = 0;
249  //start = 0;
250  //end = 0;
251 
252  // Check status of joints
253  _enabledPid = NULL;
254  _enabledAmp = NULL;
255  _calibrated = NULL;
256  _last_position_move_time = NULL;
257 
258  behFlags.useRawEncoderData = false;
259  behFlags.pwmIsLimited = false;
260 
261  std::string tmp = yarp::conf::environment::get_string("ETH_VERBOSEWHENOK");
262  if (tmp != "")
263  {
264  behFlags.verbosewhenok = (bool)yarp::conf::numeric::from_string(tmp, 0U);
265  }
266  else
267  {
268  behFlags.verbosewhenok = false;
269  }
270  parser = NULL;
271  _mcparser = NULL;
272 
273 #ifdef NETWORK_PERFORMANCE_BENCHMARK
274  /* We would like to verify if the round trimp of request and answer from embedded board is about 3 milliseconds, with a tollerance 0f 0.250 milliseconds.
275  The m_responseTimingVerifier object, after 3 seconds, prints an istogram with values from 1 to 10 millisec with a step of 0.5 millisec
276  */
277  m_responseTimingVerifier.init(0.003, 0.00025, 0.001, 0.01, 0.0005, 30);
278 #endif
279 
280 }
281 
282 
284 {
285  yTrace() << "embObjMotionControl::~embObjMotionControl()";
286 
287  if(NULL != parser)
288  {
289  delete parser;
290  parser = NULL;
291  }
292 
293  if(NULL != _mcparser)
294  {
295  delete _mcparser;
296  _mcparser = NULL;
297  }
298 
299  dealloc();
300 }
301 
302 
304 {
305  return opened;
306 }
307 
308 bool embObjMotionControl::initializeInterfaces(measureConvFactors &f)
309 {
310 
311  ImplementControlCalibration::initialize(_njoints, _axisMap, f.angleToEncoder, NULL);
312  ImplementAmplifierControl::initialize(_njoints, _axisMap, f.angleToEncoder, NULL,f.ampsToSensor);
313  ImplementEncodersTimed::initialize(_njoints, _axisMap, f.angleToEncoder, NULL);
314  ImplementMotorEncoders::initialize(_njoints, _axisMap, f.angleToEncoder, NULL);
315  ImplementPositionControl::initialize(_njoints, _axisMap, f.angleToEncoder, NULL);
316  ImplementPidControl::initialize(_njoints, _axisMap, f.angleToEncoder, NULL, f.newtonsToSensor, f.ampsToSensor, f.dutycycleToPWM);
317  ImplementControlMode::initialize(_njoints, _axisMap);
318  ImplementVelocityControl::initialize(_njoints, _axisMap, f.angleToEncoder, NULL);
319  ImplementControlLimits::initialize(_njoints, _axisMap, f.angleToEncoder, NULL);
320  ImplementImpedanceControl::initialize(_njoints, _axisMap, f.angleToEncoder, NULL, f.newtonsToSensor);
321  ImplementTorqueControl::initialize(_njoints, _axisMap, f.angleToEncoder, NULL, f.newtonsToSensor, f.ampsToSensor, f.dutycycleToPWM, f.bemf2raw, f.ktau2raw);
322  ImplementPositionDirect::initialize(_njoints, _axisMap, f.angleToEncoder, NULL);
323  ImplementInteractionMode::initialize(_njoints, _axisMap, f.angleToEncoder, NULL);
324  ImplementMotor::initialize(_njoints, _axisMap);
325  ImplementRemoteVariables::initialize(_njoints, _axisMap);
326  ImplementAxisInfo::initialize(_njoints, _axisMap);
327  ImplementCurrentControl::initialize(_njoints, _axisMap, f.ampsToSensor);
328  ImplementPWMControl::initialize(_njoints, _axisMap, f.dutycycleToPWM);
329  ImplementJointFault::initialize(_njoints, _axisMap);
330 
331  return true;
332 
333 }
334 
335 bool embObjMotionControl::open(yarp::os::Searchable &config)
336 {
337  // - first thing to do is verify if the eth manager is available. then i parse info about the eth board.
338 
339  ethManager = eth::TheEthManager::instance();
340  if(NULL == ethManager)
341  {
342  yFatal() << "embObjMotionControl::open() fails to instantiate ethManager";
343  return false;
344  }
345 
346  eOipv4addr_t ipv4addr;
347  string boardIPstring;
348  string boardName;
349  if(false == ethManager->verifyEthBoardInfo(config, ipv4addr, boardIPstring, boardName))
350  {
351  yError() << "embObjMotionControl::open(): object TheEthManager fails in parsing ETH propertiex from xml file";
352  return false;
353  }
354  // add specific info about this device ...
355 
356 
357  if(NULL == parser)
358  {
359  parser = new ServiceParser;
360  }
361 
362 
363  // - now all other things
364 
365  // -- instantiate EthResource etc.
366 
367  res = ethManager->requestResource2(this, config);
368  if(NULL == res)
369  {
370  yError() << "embObjMotionControl::open() fails because could not instantiate the ethResource for " << getBoardInfo() << " ... unable to continue";
371  return false;
372  }
373  // READ CONFIGURATION
374  if(!fromConfig(config))
375  {
376  yError() << getBoardInfo() << "Missing motion control parameters in config file";
377  return false;
378  }
379 
380  if(!res->verifyEPprotocol(eoprot_endpoint_motioncontrol))
381  {
382  yError() << "embObjMotionControl: failed verifyEPprotocol. Cannot continue!";
383  cleanup();
384  return false;
385  }
386 
387 
388  const eOmn_serv_parameter_t* servparam = &serviceConfig.ethservice;
389  if(eomn_serv_MC_generic == serviceConfig.ethservice.configuration.type)
390  {
391  servparam = NULL;
392  }
393 
394  // in here ...we open ports where to print AMO data
395  mcdiagnostics.config.mode = serviceConfig.ethservice.configuration.diagnosticsmode;
396  mcdiagnostics.config.par16 = serviceConfig.ethservice.configuration.diagnosticsparam;
397  if(eomn_serv_diagn_mode_MC_AMOyarp == mcdiagnostics.config.mode)
398  {
399  // prepare the ports
400  mcdiagnostics.ports.resize(2);
401  for(size_t i=0; i<mcdiagnostics.ports.size(); i++)
402  {
403  mcdiagnostics.ports[i] = new BufferedPort<Bottle>;
404  mcdiagnostics.ports[i]->open("/amo/" + res->getProperties().boardnameString + "/j" + std::to_string(i));
405  }
406  }
407 
408  // Initialize the downsampler timer
409 
410  event_downsampler = new mced::mcEventDownsampler();
411  event_downsampler->config.period = 0.01;
412  event_downsampler->config.threshold = 5;
413  event_downsampler->config.subcomponent = "[mc.skipped-cmd-wrong-mode]";
414  event_downsampler->config.info = getBoardInfo();
415  event_downsampler->start();
416 
417  if(false == res->serviceVerifyActivate(eomn_serv_category_mc, servparam))
418  {
419  yError() << "embObjMotionControl::open() has an error in call of ethResources::serviceVerifyActivate() for" << getBoardInfo();
420  cleanup();
421  return false;
422  }
423 
424  yDebug() << "embObjMotionControl:serviceVerifyActivate OK!";
425 
426 
427  if(!init() )
428  {
429  yError() << "embObjMotionControl::open() has an error in call of embObjMotionControl::init() for" << getBoardInfo();
430  return false;
431  }
432  else
433  {
434  if(behFlags.verbosewhenok)
435  {
436  yDebug() << "embObjMotionControl::init() has succesfully initted" << getBoardInfo();
437  }
438  }
439 
440 
441  if(false == res->serviceStart(eomn_serv_category_mc))
442  {
443  yError() << "embObjMotionControl::open() fails to start mc service for" << getBoardInfo() << ": cannot continue";
444  cleanup();
445  return false;
446  }
447  else
448  {
449  if(behFlags.verbosewhenok)
450  {
451  yDebug() << "embObjMotionControl::open() correctly starts mc service of" << getBoardInfo();
452  }
453  }
454 
455 
456  opened = true;
457 
458 
459  if(eomn_serv_diagn_mode_MC_AMOyarp == mcdiagnostics.config.mode)
460  {
461  // marco.accame on 10 june 2011.
462  // in here we wait some time so that yarprobotinterface may receive amo streaming before any
463  // further module (e.g., the calibrator) sends an active control mode and starts moving the motor.
464  //
465  // how does it work?
466  //
467  // when the ETH board receives command from res->serviceStart() it enters the control loop and it
468  // waits for a non IDLE control mode etc. but it also starts streaming AMO data. It is the thread
469  // inside EthReceiver whuch process UDP pckets, so a wait inside this current thread will do the job.
470  //
471  // moreover, if mcdiagnostics.config.par16 is > 0, then we also have a mechanism such that the AMO
472  // are streamed in a conditio of the motor not initiaized yet. in such way we can observe what is
473  // the effect of the configuration of the motor on the AMO reading.
474  //
475  // how does it work?
476  //
477  // it is the function embObjMotionControl::init() which configures the motors by sending messages
478  // with tag eoprot_tag_mc_joint_config.
479  // the ETH board, if it sees eomn_serv_diagn_mode_MC_AMOyarp and par16 > 0, it applies the config of
480  // the motor with a delay of mcdiagnostics.config.par16 milliseconds. so, in here if we wait
481  // the same amount of time, we:
482  // - can read amo values with the motors off,
483  // - we are sure that no other module (e.g., the calibrator) will attempt to move a motor which is
484  // not yet configured.
485  // I KNOW: IT WOULD BE MUCH BETTER to wait in here until the ETH board tells us that it has configured
486  // the motor (rather then just applying a delay and hoping the ETH boards works fine). but that would
487  // require some effort which for now i prefer to postpone because "l'ottimo e' il nemico del bene"
488  // and we need a quick solution to test icub3.
489 
490  SystemClock::delaySystem(0.001*mcdiagnostics.config.par16);
491  }
492 
493  return true;
494 }
495 
496 
497 int embObjMotionControl::fromConfig_NumOfJoints(yarp::os::Searchable &config)
498 {
499  //
500  // Read Configuration params from file
501  //
502  int jn = config.findGroup("GENERAL").check("Joints", Value(1), "Number of degrees of freedom").asInt32();
503 
504  return(jn);
505 }
506 
507 
508 
509 void embObjMotionControl::debugUtil_printJointsetInfo(void)
510 {
511 
512  yError() << "****** DEBUG PRINTS **********";
513  yError() << "joint to set:";
514  for(int x=0; x< _njoints; x++)
515  yError() << " /t j " << x << ": set " <<_joint2set[x];
516  yError() << "jointmap:";
517 
518  yError() << " number of sets" << _jsets.size();
519  for(size_t x=0; x< _jsets.size(); x++)
520  {
521  yError() << "set " << x<< "has size " <<_jsets[x].getNumberofJoints();
522  for(int y=0; y<_jsets[x].getNumberofJoints(); y++)
523  yError() << "set " << x << ": " << _jsets[x].joints[y];
524  }
525  yError() << "********* END ****************";
526 
527 }
528 
529 
530 
531 
532 bool embObjMotionControl::verifyUserControlLawConsistencyInJointSet(eomc::PidInfo *pidInfo)
533 {
534 
535  for(size_t s=0; s<_jsets.size(); s++)
536  {
537  int numofjoints = _jsets[s].getNumberofJoints();
538 
539  if(numofjoints== 0 )
540  {
541  yError() << "embObjMC" << getBoardInfo() << "Jointsset " << s << "hasn't joints!!! I should be never stay here!!!";
542  return false;
543  }
544  int firstjoint = _jsets[s].joints[0];//get firts joint of set s
545 
546  for(int k=1; k<numofjoints; k++)
547  {
548  int otherjoint = _jsets[s].joints[k];
549 
550  if(pidInfo[firstjoint].usernamePidSelected != pidInfo[otherjoint].usernamePidSelected)
551  {
552  yError() << "embObjMC "<< getBoardInfo() << "Joints beloning to same set must be have same control law. Joint " << otherjoint << " differs from " << firstjoint << "Set num " << s ;
553  yError() << pidInfo[firstjoint].usernamePidSelected << "***" << pidInfo[otherjoint].usernamePidSelected;
554  return false;
555  }
556  }
557  }
558  return true;
559 }
560 
561 
562 
563 
564 
565 bool embObjMotionControl::verifyUserControlLawConsistencyInJointSet(eomc::TrqPidInfo *pidInfo)
566 {
567  for(size_t s=0; s<_jsets.size(); s++)
568  {
569  int numofjoints = _jsets[s].getNumberofJoints();
570 
571  if(numofjoints== 0 )
572  {
573  yError() << "embObjMC "<< getBoardInfo() << "Jointsset " << s << "hasn't joints!!! I should be never stay here!!!";
574  return false;
575  }
576  int firstjoint = _jsets[s].joints[0];//get firts joint of set s
577 
578  for(int k=1; k<numofjoints; k++)
579  {
580  int otherjoint = _jsets[s].joints[k];
581 
582  if(pidInfo[firstjoint].usernamePidSelected != pidInfo[otherjoint].usernamePidSelected)
583  {
584  yError() << "embObjMC"<< getBoardInfo() << "Joints beloning to same set must be have same control law. Joint " << otherjoint << " differs from " << firstjoint << "Set num " << s ;
585  yError() << pidInfo[firstjoint].usernamePidSelected << "***" << pidInfo[otherjoint].usernamePidSelected;
586  return false;
587  }
588  }
589  }
590  return true;
591 }
592 
593 
594 bool embObjMotionControl::updatedJointsetsCfgWithControlInfo()
595 {
596  //#error ALE
597 
598  for(size_t s=0; s<_jsets.size(); s++)
599  {
600  if(_jsets[s].getNumberofJoints() == 0)
601  {
602  yError() << "embObjMC"<< getBoardInfo() << "Jointsset " << s << "hasn't joints!!! I should be never stay here!!!";
603  return false;
604  }
605 
606  int joint = _jsets[s].joints[0];
607  //eOmc_pidoutputtype_t pid_out_type = pidOutputTypeConver_eomc2fw(_trj_pids[joint].controlLaw);
608  //if(eomc_pidoutputtype_unknown == pid_out_type)
609  //{
610  // yError() << "embObjMC"<< getBoardInfo() << "pid output type is unknown for joint " << joint;
611  // return false;
612  //}
613  //_jsets[s].setPidOutputType(pid_out_type);
614  //_jsets[s].setCanDoTorqueControl(isTorqueControlEnabled(joint));
615 
616  _jsets[s].cfg.pid_output_types.postrj_ctrl_out_type = _trj_pids[joint].out_type;
617  _jsets[s].cfg.pid_output_types.veltrj_ctrl_out_type = _trj_pids[joint].out_type;
618  _jsets[s].cfg.pid_output_types.mixtrj_ctrl_out_type = _trj_pids[joint].out_type;
619 
620  //_jsets[s].cfg.pid_output_types.posdir_ctrl_out_type = _dir_pids[joint].out_type;
621  //_jsets[s].cfg.pid_output_types.veldir_ctrl_out_type = _dir_pids[joint].out_type;
622  _jsets[s].cfg.pid_output_types.posdir_ctrl_out_type = _trj_pids[joint].out_type;
623  _jsets[s].cfg.pid_output_types.veldir_ctrl_out_type = _trj_pids[joint].out_type;
624 
625  _jsets[s].cfg.pid_output_types.torque_ctrl_out_type = _trq_pids[joint].out_type;
626 
627  _jsets[s].cfg.pid_output_types.pwm_ctrl_out_type = eomc_ctrl_out_type_pwm;
628 
629  if (_cur_pids[joint].enabled)
630  {
631  _jsets[s].cfg.pid_output_types.cur_ctrl_out_type = eomc_ctrl_out_type_cur;
632  }
633  else
634  {
635  _jsets[s].cfg.pid_output_types.cur_ctrl_out_type = eomc_ctrl_out_type_n_a;
636  }
637  }
638  return true;
639 }
640 
641 
642 
643 
644 bool embObjMotionControl::saveCouplingsData(void)
645 {
646  eOmc_4jomo_coupling_t *jc_dest;
647 
648  static eOmc_4jomo_coupling_t dummyjomocoupling = {};
649 
650  switch(serviceConfig.ethservice.configuration.type)
651  {
652  case eomn_serv_MC_foc:
653  {
654  jc_dest = &(serviceConfig.ethservice.configuration.data.mc.foc_based.jomocoupling);
655  } break;
656 
657  case eomn_serv_MC_mc4plus:
658  {
659  jc_dest = &(serviceConfig.ethservice.configuration.data.mc.mc4plus_based.jomocoupling);
660  } break;
661 
662  case eomn_serv_MC_mc4plusmais:
663  {
664  jc_dest = &(serviceConfig.ethservice.configuration.data.mc.mc4plusmais_based.jomocoupling);
665 
666  } break;
667 
668  case eomn_serv_MC_mc2pluspsc:
669  {
670  jc_dest = &(serviceConfig.ethservice.configuration.data.mc.mc2pluspsc.jomocoupling);
671 
672  } break;
673 
674  case eomn_serv_MC_mc4plusfaps:
675  {
676  jc_dest = &(serviceConfig.ethservice.configuration.data.mc.mc4plusfaps.jomocoupling);
677 
678  } break;
679 
680  case eomn_serv_MC_advfoc:
681  {
682  jc_dest = &dummyjomocoupling;
683  } break;
684 
685  case eomn_serv_MC_mc4:
686  {
687  return true;
688  } break;
689 
690  case eomn_serv_MC_generic:
691  {
692  return true;
693  } break;
694 
695  default:
696  {
697  return false;
698  }
699  }
700 
701 
702  memset(jc_dest, 0, sizeof(eOmc_4jomo_coupling_t));
703 
704  //I need to initialize all elements of joint2set with "eomc_jointSetNum_none": it is used by fw to get num of setBemfParamRaw
705  //4 is teh satic dimension of joint2set. see definition of type eOmc_4jomo_coupling_t
706  for(int i=0; i<4; i++)
707  {
708  jc_dest->joint2set[i] = eomc_jointSetNum_none;
709  }
710 
711  if(_joint2set.size() > 4 )
712  {
713  yError() << "embObjMC "<< getBoardInfo() << "Jointsset size is bigger than 4. I can't send jointset information to fw.";
714  return false;
715  }
716 
717  for(size_t i=0; i<_joint2set.size(); i++)
718  {
719  jc_dest->joint2set[i] = _joint2set[i];
720  }
721 
722  for(int i=0; i<4; i++)
723  {
724  for(int j=0; j<4; j++)
725  {
726  jc_dest->joint2motor[i][j] = eo_common_float_to_Q17_14((float)_couplingInfo.matrixJ2M[4*i+j]);
727  jc_dest->motor2joint[i][j] = eo_common_float_to_Q17_14((float)_couplingInfo.matrixM2J[4*i+j]);
728  }
729  }
730 
731 
732  for(int r=0; r<4; r++)
733  {
734  for(int c=0; c<6; c++)
735  {
736  jc_dest->encoder2joint[r][c] = eo_common_float_to_Q17_14((float)_couplingInfo.matrixE2J[6*r+c]);
737  }
738  }
739 
740  for(size_t s=0; s< _jsets.size(); s++)
741  {
742  eOmc_jointset_configuration_t* cfg_ptr = _jsets[s].getConfiguration();
743  memcpy(&(jc_dest->jsetcfg[s]), cfg_ptr, sizeof(eOmc_jointset_configuration_t));
744  }
745 
746 
747  if(eomn_serv_MC_advfoc == serviceConfig.ethservice.configuration.type)
748  {
749  // i will copy data from jc_dest to the effective destination
750  eOmc_adv4jomo_coupling_t *ajc = &serviceConfig.ethservice.configuration.data.mc.advfoc.adv4jomocoupling;
751  ajc->type = eommccoupling_traditional4x4;
752  // i copy some fields as they are
753  std::memmove(&ajc->data.coupling4x4.joint2set[0], &jc_dest->joint2set[0], 4*sizeof(uint8_t));
754  std::memmove(&ajc->data.coupling4x4.jsetcfg[0], &jc_dest->jsetcfg[0], 4*sizeof(eOmc_jointset_configuration_t));
755  std::memmove(&ajc->data.coupling4x4.joint2motor, &jc_dest->joint2motor, sizeof(eOmc_4x4_matrix_t));
756  std::memmove(&ajc->data.coupling4x4.motor2joint, &jc_dest->motor2joint, sizeof(eOmc_4x4_matrix_t));
757  // and i will copy only 4x4 from one field
758  for(uint8_t r=0; r<4; r++)
759  {
760  for(uint8_t c=0; c<4; c++)
761  {
762  ajc->data.coupling4x4.encoder2joint4x4[r][c] = jc_dest->encoder2joint[r][c];
763  }
764  }
765  }
766 
767  return true;
768 
769 }
770 
771 
772 bool embObjMotionControl::fromConfig_Step2(yarp::os::Searchable &config)
773 {
774  Bottle xtmp;
775  int i,j;
776 
777  measureConvFactors measConvFactors (_njoints);
778 
779  if(iNeedCouplingsInfo())
780  {
781 
783  if(!_mcparser->parseCouplingInfo(config, _couplingInfo))
784  return false;
785 
786 
788  if(!_mcparser->parseJointsetCfgGroup(config, _jsets, _joint2set))
789  return false;
790 
791  //debugUtil_printJointsetInfo();
792  }
793 
794 
796 
797 
798  {
799  if(!_mcparser->parseAxisInfo(config, _axisMap, _axesInfo))
800  return false;
801 
803  if(behFlags.useRawEncoderData)
804  {
805  for (i = 0; i < _njoints; i++)
806  {
807  measConvFactors.angleToEncoder[i] = 1;
808  }
809  }
810  else
811  {
812  if(!_mcparser->parseEncoderFactor(config, measConvFactors.angleToEncoder))
813  return false;
814  }
815 
816  if (!_mcparser->parsefullscalePWM(config, measConvFactors.dutycycleToPWM))
817  return false;
818 
819  if (!_mcparser->parseAmpsToSensor(config, measConvFactors.ampsToSensor))
820  return false;
821 
822  //VALE: i have to parse GeneralMecGroup after parsing jointsetcfg, because inside generalmec group there is useMotorSpeedFbk that needs jointset info.
823 
824  if(!_mcparser->parseGearboxValues(config, _gearbox_M2J, _gearbox_E2J))
825  return false;
826 
827  // useMotorSpeedFbk
828  if(eomn_serv_MC_mc4 != (eOmn_serv_type_t)serviceConfig.ethservice.configuration.type)
829  {
830  int* useMotorSpeedFbk = 0;
831  useMotorSpeedFbk = new int[_njoints];
832  if (!_mcparser->parseMechanicalsFlags(config, useMotorSpeedFbk))
833  {
834  delete[] useMotorSpeedFbk;
835  return false;
836  }
837  //Note: currently in eth protocol this parameter belongs to jointset configuration. So
838  // i need to check that every joint belong to same set has the same value
839  if (!verifyUseMotorSpeedFbkInJointSet(useMotorSpeedFbk))
840  {
841  delete[] useMotorSpeedFbk;
842  return false;
843  }
844  delete[] useMotorSpeedFbk;
845  }
846  bool deadzoneIsAvailable;
847  if(!_mcparser->parseDeadzoneValue(config, _deadzone, &deadzoneIsAvailable))
848  return false;
849  if(!deadzoneIsAvailable) // if parameter is not written in configuration files then use default values
850  {
851  updateDeadZoneWithDefaultValues();
852  }
853 
854  if(!_mcparser->parseKalmanFilterParams(config, _kalman_params))
855  {
856  return false;
857  }
858  }
859 
860 
862  {
863  bool lowLevPidisMandatory = false;
864 
865  if((serviceConfig.ethservice.configuration.type == eomn_serv_MC_foc) || (serviceConfig.ethservice.configuration.type == eomn_serv_MC_advfoc))
866  {
867  lowLevPidisMandatory = true;
868  }
869 
870  if(!_mcparser->parsePids(config, _trj_pids/*, _dir_pids*/, _trq_pids, _cur_pids, _spd_pids, lowLevPidisMandatory))
871  return false;
872 
873  // 1) verify joint belonging to same set has same control law
874  //if(!verifyUserControlLawConsistencyInJointSet(_ppids))
875  // return false;
876  //if(!verifyUserControlLawConsistencyInJointSet(_vpids))
877  // return false;
878  //if(!verifyUserControlLawConsistencyInJointSet(_tpids))
879  // return false;
880 
881  //yarp::dev::PidFeedbackUnitsEnum fbk_TrqPidUnits;
882  //yarp::dev::PidOutputUnitsEnum out_TrqPidUnits;
883  //if(!verifyTorquePidshasSameUnitTypes(fbk_TrqPidUnits, out_TrqPidUnits))
884  // return false;
885 
886  //2) since some joint sets configuration info is in control and ids group, get that info and save them in jointset data struct.
887  updatedJointsetsCfgWithControlInfo();
888  }
889 
890  for (i = 0; i < _njoints; i++)
891  {
892  measConvFactors.newtonsToSensor[i] = 1000000.0f; // conversion from Nm into microNm
893 
894  measConvFactors.bemf2raw[i] = measConvFactors.newtonsToSensor[i] / measConvFactors.angleToEncoder[i];
895  if (_trq_pids->out_PidUnits == yarp::dev::PidOutputUnitsEnum::DUTYCYCLE_PWM_PERCENT)
896  {
897  measConvFactors.ktau2raw[i] = measConvFactors.dutycycleToPWM[i] / measConvFactors.newtonsToSensor[i];
898  }
899  else if (_trq_pids->out_PidUnits == yarp::dev::PidOutputUnitsEnum::RAW_MACHINE_UNITS)
900  {
901  measConvFactors.ktau2raw[i] = 1.0 / measConvFactors.newtonsToSensor[i];
902  }
903  else
904  {
905  yError() << "Invalid ktau units"; return false;
906  }
907  }
908 
910  _measureConverter = new ControlBoardHelper(_njoints, _axisMap, measConvFactors.angleToEncoder, NULL, measConvFactors.newtonsToSensor, measConvFactors.ampsToSensor, nullptr, measConvFactors.dutycycleToPWM , measConvFactors.bemf2raw, measConvFactors.ktau2raw);
911  _measureConverter->set_pid_conversion_units(PidControlTypeEnum::VOCAB_PIDTYPE_POSITION, _trj_pids->fbk_PidUnits, _trj_pids->out_PidUnits);
912  //_measureConverter->set_pid_conversion_units(PidControlTypeEnum::VOCAB_PIDTYPE_DIRECT, _dir_pids->fbk_PidUnits, _dir_pids->out_PidUnits);
913  _measureConverter->set_pid_conversion_units(PidControlTypeEnum::VOCAB_PIDTYPE_TORQUE, _trq_pids->fbk_PidUnits, _trq_pids->out_PidUnits);
914  _measureConverter->set_pid_conversion_units(PidControlTypeEnum::VOCAB_PIDTYPE_CURRENT, _cur_pids->fbk_PidUnits, _cur_pids->out_PidUnits);
915  _measureConverter->set_pid_conversion_units(PidControlTypeEnum::VOCAB_PIDTYPE_VELOCITY, _spd_pids->fbk_PidUnits, _spd_pids->out_PidUnits);
916  /*
917  void ControlBoardHelper::set_pid_conversion_units(const PidControlTypeEnum& pidtype, const PidFeedbackUnitsEnum fbk_conv_units, const PidOutputUnitsEnum out_conv_units)
918  {
919  ControlBoardHelper* cb_helper = this;
920  int nj = cb_helper->axes();
921  for (int i = 0; i < nj; i++)
922  {
923  mPriv->pid_units[pidtype][i].fbk_units = fbk_conv_units;
924  mPriv->pid_units[pidtype][i].out_units = out_conv_units;
925  }
926  }
927  */
928  initializeInterfaces(measConvFactors);
929  ImplementPidControl::setConversionUnits(PidControlTypeEnum::VOCAB_PIDTYPE_POSITION, _trj_pids->fbk_PidUnits, _trj_pids->out_PidUnits);
930  //ImplementPidControl::setConversionUnits(PidControlTypeEnum::VOCAB_PIDTYPE_DIRECT, _dir_pids->fbk_PidUnits, _dir_pids->out_PidUnits);
931  ImplementPidControl::setConversionUnits(PidControlTypeEnum::VOCAB_PIDTYPE_TORQUE, _trq_pids->fbk_PidUnits, _trq_pids->out_PidUnits);
932  ImplementPidControl::setConversionUnits(PidControlTypeEnum::VOCAB_PIDTYPE_CURRENT, _cur_pids->fbk_PidUnits, _cur_pids->out_PidUnits);
933  ImplementPidControl::setConversionUnits(PidControlTypeEnum::VOCAB_PIDTYPE_VELOCITY, _spd_pids->fbk_PidUnits, _spd_pids->out_PidUnits);
934 
935 
936  //Now save in data in structures EmbObj protocol compatible
937  if(!saveCouplingsData())
938  return false;
939 
940 
942  if(! _mcparser->parseImpedanceGroup(config,_impedance_params))
943  {
944  yError() << "embObjMC " << getBoardInfo() << "IMPEDANCE section: error detected in parameters syntax";
945  return false;
946  }
947 
948 
950  for(j=0; j<_njoints; j++)
951  {
952  // got from canBusMotionControl, ask to Randazzo Marco
953  _impedance_limits[j].min_damp= 0.001;
954  _impedance_limits[j].max_damp= 9.888;
955  _impedance_limits[j].min_stiff= 0.002;
956  _impedance_limits[j].max_stiff= 9.889;
957  _impedance_limits[j].param_a= 0.011;
958  _impedance_limits[j].param_b= 0.012;
959  _impedance_limits[j].param_c= 0.013;
960  }
961 
962 
963 
965  {
966  if(!_mcparser->parseCurrentLimits(config, _currentLimits))
967  return false;
968 
969  if(!_mcparser->parseTemperatureLimits(config, _temperatureLimits))
970  return false;
971 
972  if(!_mcparser->parseJointsLimits(config, _jointsLimits))
973  return false;
974 
975  if(!_mcparser->parseRotorsLimits(config, _rotorsLimits))
976  return false;
977  }
978 
980  eOmn_serv_type_t servtype = static_cast<eOmn_serv_type_t>(serviceConfig.ethservice.configuration.type);
981 
982  if((eomn_serv_MC_foc == servtype) || (eomn_serv_MC_advfoc == servtype))
983  {
984  std::string groupName = {};
985 
986  if(eomn_serv_MC_foc == servtype)
987  {
988  // in here the name of the group depends on the configured board
989  eObrd_type_t brd = static_cast<eObrd_type_t>(serviceConfig.ethservice.configuration.data.mc.foc_based.type);
990  groupName = (eobrd_foc == brd) ? "2FOC" : "AMCBLDC";
991  }
992  else if(eomn_serv_MC_advfoc == servtype)
993  {
994  // but in here we may have multiple boards, so ... it is better to use a generic name
995  // ADVFOC with multiple columns, one for each motor
996  groupName = "ADVFOC";
997  }
998 
999  if(!_mcparser->parseFocGroup(config, _foc_based_info, groupName, _temperatureSensorsVector))
1000  return false;
1001 
1002  for (j = 0; j < _njoints; j++)
1003  {
1004  if (((_temperatureSensorsVector.at(j)->getType() != motor_temperature_sensor_none )) && ((_temperatureLimits[j].hardwareTemperatureLimit == 0) || (_temperatureLimits[j].warningTemperatureLimit == 0)))
1005  {
1006  yError() << "In" << getBoardInfo() << "joint" << j << ": inconsistent configuration, please update it. If Temperature limits are not set then TemperatureSensorType must be NONE or not set and/or HasTempSensor must be zero. Aborting...";
1007  return false;
1008  }
1009 
1010  if (_temperatureSensorsVector.at(j)->getType() == motor_temperature_sensor_none)
1011  {
1012  yInfo() << "embObjMC " << getBoardInfo() << "joint " << j << " has motor not provided with any available type of temperature sensor. If needed update the configurations file accordingly";
1013  }
1014  }
1015  }
1016  else
1017  {
1018  for (j = 0; j < _njoints; j++)
1019  {
1020  _temperatureSensorsVector.at(j) = std::make_unique<eomc::TemperatureSensorNONE>();
1021  }
1022  }
1023 
1024 
1025 
1027  if(! _mcparser->parseTimeoutsGroup(config, _timeouts, 1000 /*defaultVelocityTimeout*/))
1028  return false;
1029 
1030 
1031  return true;
1032 }
1033 
1034 
1035 
1036 bool embObjMotionControl::verifyUseMotorSpeedFbkInJointSet(int useMotorSpeedFbk [])
1037 {
1038  for(size_t s=0; s< _jsets.size(); s++)
1039  {
1040  int numofjointsinset = _jsets[s].getNumberofJoints();
1041  if(numofjointsinset == 0 )
1042  {
1043  yError() << "embObjMC " << getBoardInfo() << "Jointsset " << s << "hasn't joints!!! I should be never stay here!!!";
1044  return false;
1045  }
1046 
1047  int firstjointofset = _jsets[s].joints[0];
1048  for(int j=1; j<numofjointsinset; j++)
1049  {
1050  int joint = _jsets[s].joints[j];
1051  if(useMotorSpeedFbk[firstjointofset] != useMotorSpeedFbk[joint])
1052  {
1053  yError() << "embObjMC " << getBoardInfo() << ". Param useMotorSpeedFbk should have same value for joints belong same set. See joint " << firstjointofset << " and " << joint;
1054  return false;
1055  }
1056  }
1057 
1058  _jsets[s].setUseSpeedFeedbackFromMotors(useMotorSpeedFbk[firstjointofset]);
1059  }
1060 
1061  return true;
1062 
1063 }
1064 
1065 bool embObjMotionControl::verifyTorquePidshasSameUnitTypes(yarp::dev::PidFeedbackUnitsEnum &fbk_pidunits, yarp::dev::PidOutputUnitsEnum& out_pidunits)
1066 {
1067  fbk_pidunits = yarp::dev::PidFeedbackUnitsEnum::RAW_MACHINE_UNITS;
1068  out_pidunits = yarp::dev::PidOutputUnitsEnum::RAW_MACHINE_UNITS;
1069  //get first joint with enabled torque
1070  int firstjoint = -1;
1071  for(int i=0; i<_njoints; i++)
1072  {
1073  if(_trq_pids[i].enabled)
1074  firstjoint = i;
1075  }
1076 
1077  if(firstjoint==-1)
1078  {
1079  // no joint has torque enabed
1080  return true;
1081  }
1082 
1083  for(int i=firstjoint+1; i<_njoints; i++)
1084  {
1085  if(_trq_pids[i].enabled)
1086  {
1087  if(_trq_pids[firstjoint].fbk_PidUnits != _trq_pids[i].fbk_PidUnits ||
1088  _trq_pids[firstjoint].out_PidUnits != _trq_pids[i].out_PidUnits)
1089  {
1090  yError() << "embObjMC " << getBoardInfo() << "all joints with torque enabled should have same controlunits type. Joint " << firstjoint << " differs from joint " << i;
1091  return false;
1092  }
1093  }
1094  }
1095 
1096  fbk_pidunits = _trq_pids[firstjoint].fbk_PidUnits;
1097  out_pidunits = _trq_pids[firstjoint].out_PidUnits;
1098  return true;
1099 }
1100 
1101 bool embObjMotionControl::isTorqueControlEnabled(int joint)
1102 {
1103  return (_trq_pids[joint].enabled);
1104 }
1105 
1106 bool embObjMotionControl::isVelocityControlEnabled(int joint)
1107 {
1108  //return (_dir_pids[joint].enabled);
1109  return (_trj_pids[joint].enabled);
1110 }
1111 
1112 
1113 void embObjMotionControl::updateDeadZoneWithDefaultValues(void)
1114 {
1115  for(int i=0; i<_njoints; i++)
1116  {
1117  switch(_jointEncs[i].type)
1118  {
1119  case eomc_enc_aea:
1120  _deadzone[i] = eomc_defaultValue::DeadZone::jointWithAEA;// 0.0494;
1121  break;
1122  case eomc_enc_aea3:
1123  _deadzone[i] = eomc_defaultValue::DeadZone::jointWithAEA3;// TODO: temporary equal to 0.0
1124  break;
1125  case eomc_enc_aksim2:
1127  case eomc_enc_amo:
1128  _deadzone[i] = eomc_defaultValue::DeadZone::jointWithAMO;// 0.0055;
1129  break;
1130  case eomc_enc_roie:
1131  case eomc_enc_absanalog:
1132  case eomc_enc_mais:
1133  case eomc_enc_qenc:
1134  case eomc_enc_hallmotor:
1135  case eomc_enc_spichainof2:
1136  case eomc_enc_spichainof3:
1137  case eomc_enc_mrie:
1138  default:
1139  _deadzone[i] = 0.0;
1140 
1141  }
1142  }
1143 }
1144 
1145 // use this one for ... service configuration
1146 bool embObjMotionControl::fromConfig_readServiceCfg(yarp::os::Searchable &config)
1147 {
1148 
1149  if(false == parser->parseService(config, serviceConfig))
1150  {
1151  yError() << "embObjMC " << getBoardInfo() << "cannot parse service" ;
1152  return false;
1153  }
1154 
1155  if(eomn_serv_MC_generic == serviceConfig.ethservice.configuration.type)
1156  {
1157  yError() << "embObjMC " << getBoardInfo() << "it is no longer possible use eomn_serv_MC_generic, because firmware cannot configure itself!" ;
1158  return false;
1159  }
1160 
1161  //now parser read encoders' resolutions also.
1162  //so here I save in embObMotioncontrol memory encoders's resolution
1163  servMC_encoder_t * jointEncoder_ptr = NULL;
1164  servMC_encoder_t * motorEncoder_ptr = NULL;
1165  for(int i=0; i<_njoints; i++)
1166  {
1167  jointEncoder_ptr = parser->getEncoderAtJoint(i);
1168  motorEncoder_ptr = parser->getEncoderAtMotor(i);
1169 
1170  if(NULL == jointEncoder_ptr)
1171  {
1172  _jointEncs[i].resolution = 1;
1173  _jointEncs[i].type = eomc_enc_none;
1174  _jointEncs[i].tolerance = 0;
1175  }
1176  else
1177  {
1178  _jointEncs[i].resolution = jointEncoder_ptr->resolution;
1179  _jointEncs[i].type = (eOmc_encoder_t)jointEncoder_ptr->desc.type; //Here I'm sure that type belong to eOmc_encoder_t enum.It is filled by eomc_string2encoder function
1180  _jointEncs[i].tolerance = jointEncoder_ptr->tolerance;
1181  }
1182 
1183 
1184  if(NULL == motorEncoder_ptr)
1185  {
1186  _motorEncs[i].resolution = 1;
1187  _motorEncs[i].type = eomc_enc_none;
1188  _motorEncs[i].tolerance = 0;
1189  }
1190  else
1191  {
1192  _motorEncs[i].resolution = motorEncoder_ptr->resolution;
1193  _motorEncs[i].type = (eOmc_encoder_t)motorEncoder_ptr->desc.type; //Here I'm sure that type belong to eOmc_encoder_t enum.It is filled by eomc_string2encoder function
1194  _motorEncs[i].tolerance = motorEncoder_ptr->tolerance;
1195  }
1196 
1197 
1198  }
1199 
1200 
1201  return true;
1202 }
1203 
1204 
1205 
1206 bool embObjMotionControl::fromConfig(yarp::os::Searchable &config)
1207 {
1208 
1209  _njoints = fromConfig_NumOfJoints(config);
1210 
1211  if(0 == _njoints)
1212  {
1213  yError() << "embObjMC"<< getBoardInfo() << "fromConfig(): detected _njoints = " << _njoints;
1214  return false;
1215  }
1216 
1217  // we have number of joints inside _njoints. we allocate all required buffers
1218  if(!alloc(_njoints))
1219  {
1220  yError() << "embObjMC"<< getBoardInfo() << "fromConfig(): alloc() failed for _njoints = " << _njoints;
1221  return false;
1222  }
1223 
1224 
1225  _mcparser = new eomc::Parser(_njoints, string(res->getProperties().boardnameString));
1226 
1228  int currentMCversion =0;
1229  if(!_mcparser->parseMotioncontrolVersion(config, currentMCversion))
1230  return false;
1231 
1232  if (currentMCversion != PARSER_MOTION_CONTROL_VERSION)
1233  {
1234  yError() << "embObjMC" << getBoardInfo() << "------ ATTENTION!!!! Wrong value of <MotioncontrolVersion> parameter !!!! ---------------------------------------------------------------------------------------";
1235  yError() << "embObjMC" << getBoardInfo() << "------ This means that the configuration files of this device are not compatible with my parser, so I cannot start. ";
1236  yError() << "embObjMC" << getBoardInfo() << "------ I need version " << PARSER_MOTION_CONTROL_VERSION << ", but in configuration files have version " << currentMCversion << ".";
1237  yError() << "embObjMC" << getBoardInfo() << "------ Please update configuration files in robots-configuration repository. (see http://wiki.icub.org/wiki/Robot_configuration for more information). ";
1238  yError() << "embObjMC" << getBoardInfo() << "------ If the problem persists contact icub-support@iit.it DO NOT DO IT BY YOURSELF.";
1239  yError() << "embObjMC" << getBoardInfo() << "----------------------------------------------------------------------------------------------------------------------------------------------------------------";
1240  return false;
1241  }
1242 
1243  //print verbose info
1244  if(_mcparser->isVerboseEnabled(config))
1245  yTrace() << config.toString().c_str();
1246 
1247 
1248 
1249  // first step of configuration
1250  if(false == fromConfig_readServiceCfg(config))
1251  {
1252  return false;
1253  }
1254 
1255  if(!_mcparser->parseBehaviourFalgs(config, behFlags.useRawEncoderData, behFlags.pwmIsLimited ))//in general info group
1256  {
1257  return false;
1258  }
1259 
1260 
1261  // second step of configuration
1262  if(false == fromConfig_Step2(config))
1263  {
1264  return false;
1265  }
1266 
1267  // third step of configuration
1268 
1269 
1270  return true;
1271 }
1272 
1273 
1274 bool embObjMotionControl::init()
1275 {
1276  eOprotID32_t protid = 0;
1277 
1279  //SEND DISABLE TO ALL JOINTS
1281 
1282  for(int logico=0; logico< _njoints; logico++)
1283  {
1284  int fisico = _axisMap[logico];
1285  protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, fisico, eoprot_tag_mc_joint_cmmnds_controlmode);
1286  eOenum08_t controlMode = eomc_controlmode_cmd_idle;
1287 
1288  if(false == res->setRemoteValue(protid, &controlMode))
1289  {
1290  yError() << "embObjMotionControl::init() had an error while setting eomc_controlmode_cmd_idle in "<< getBoardInfo();
1291  // return(false); i dont return false. because even if a failure, that is not a severe error.
1292  // MOREOVER: to verify we must read the status of the joint and NOT the command ... THINK OF IT
1293  }
1294  }
1295 
1296  SystemClock::delaySystem(0.010);
1297 
1298 
1300  // configure the regular rops
1302 
1303  vector<eOprotID32_t> id32v(0);
1304  for(int n=0; n<_njoints; n++)
1305  {
1306  protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, n, eoprot_tag_mc_joint_status_core);
1307  id32v.push_back(protid);
1308  protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, n, eoprot_tag_mc_motor_status);
1309  id32v.push_back(protid);
1310  }
1311 
1312  if(eomn_serv_diagn_mode_MC_AMOyarp == mcdiagnostics.config.mode)
1313  {
1314  protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, 0, eoprot_tag_mc_joint_status_debug);
1315  id32v.push_back(protid);
1316  protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, 1, eoprot_tag_mc_joint_status_debug);
1317  id32v.push_back(protid);
1318  }
1319 
1320 
1321  if(false == res->serviceSetRegulars(eomn_serv_category_mc, id32v))
1322  {
1323  yError() << "embObjMotionControl::init() fails to add its variables to regulars in "<< getBoardInfo() << ": cannot proceed any further";
1324  return false;
1325  }
1326  else
1327  {
1328  if(behFlags.verbosewhenok)
1329  {
1330  yDebug() << "embObjMotionControl::init() added" << id32v.size() << "regular rops to "<< getBoardInfo();
1331  char nvinfo[128];
1332  for(unsigned int r=0; r<id32v.size(); r++)
1333  {
1334  uint32_t id32 = id32v.at(r);
1335  eoprot_ID2information(id32, nvinfo, sizeof(nvinfo));
1336  yDebug() << "\t it added regular rop for" << nvinfo;
1337  }
1338  }
1339  }
1340 
1341  SystemClock::delaySystem(0.005);
1342 
1343 
1344 
1346  // invia la configurazione dei GIUNTI //
1348  for(int logico=0; logico< _njoints; logico++)
1349  {
1350  int fisico = _axisMap[logico];
1351  protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, fisico, eoprot_tag_mc_joint_config);
1352 
1353  eOmc_joint_config_t jconfig = {0};
1354  memset(&jconfig, 0, sizeof(eOmc_joint_config_t));
1355  yarp::dev::Pid tmp;
1356  tmp = _measureConverter->convert_pid_to_machine(yarp::dev::VOCAB_PIDTYPE_POSITION,_trj_pids[logico].pid, fisico);
1357  copyPid_iCub2eo(&tmp, &jconfig.pidtrajectory);
1358  //tmp = _measureConverter->convert_pid_to_machine(yarp::dev::VOCAB_PIDTYPE_DIRECT, _dir_pids[logico].pid, fisico);
1359  //copyPid_iCub2eo(&tmp, &jconfig.piddirect);
1360  tmp = _measureConverter->convert_pid_to_machine(yarp::dev::VOCAB_PIDTYPE_TORQUE, _trq_pids[logico].pid, fisico);
1361  copyPid_iCub2eo(&tmp, &jconfig.pidtorque);
1362 
1363  //stiffness and damping read in xml file are in Nm/deg and Nm/(Deg/sec), so we need to convert before send to fw.
1364  jconfig.impedance.damping = (eOmeas_damping_t) _measureConverter->impN2S(_impedance_params[logico].damping, fisico);
1365  jconfig.impedance.stiffness = (eOmeas_stiffness_t) _measureConverter->impN2S(_impedance_params[logico].stiffness, fisico);
1366  jconfig.impedance.offset = 0;
1367 
1368  _cacheImpedance[logico].stiffness = jconfig.impedance.stiffness;
1369  _cacheImpedance[logico].damping = jconfig.impedance.damping;
1370  _cacheImpedance[logico].offset = jconfig.impedance.offset;
1371 
1372  jconfig.userlimits.max = (eOmeas_position_t) S_32(_measureConverter->posA2E(_jointsLimits[logico].posMax, fisico));
1373  jconfig.userlimits.min = (eOmeas_position_t) S_32(_measureConverter->posA2E(_jointsLimits[logico].posMin, fisico));
1374 
1375  jconfig.hardwarelimits.max = (eOmeas_position_t) S_32(_measureConverter->posA2E(_jointsLimits[logico].posHwMax, fisico));
1376  jconfig.hardwarelimits.min = (eOmeas_position_t) S_32(_measureConverter->posA2E(_jointsLimits[logico].posHwMin, fisico));
1377 
1378 
1379  jconfig.maxvelocityofjoint = S_32(_measureConverter->posA2E(_jointsLimits[logico].velMax, fisico)); //icubdeg/s
1380  jconfig.velocitysetpointtimeout = (eOmeas_time_t) U_16(_timeouts[logico].velocity);
1381 
1382  jconfig.jntEncoderResolution = _jointEncs[logico].resolution;
1383  jconfig.jntEncoderType = _jointEncs[logico].type;
1384  jconfig.jntEncTolerance = _jointEncs[logico].tolerance;
1385 
1386  jconfig.motor_params.bemf_value = _measureConverter->bemf_user2raw(_trq_pids[logico].kbemf, fisico);
1387  jconfig.motor_params.bemf_scale = 0;
1388  jconfig.motor_params.ktau_value = _measureConverter->ktau_user2raw(_trq_pids[logico].ktau, fisico);
1389  jconfig.motor_params.ktau_scale = 0;
1390  jconfig.motor_params.friction.viscous_pos_val = _measureConverter->viscousPos_user2raw(_trq_pids[logico].viscousPos, fisico);
1391  jconfig.motor_params.friction.viscous_neg_val = _measureConverter->viscousNeg_user2raw(_trq_pids[logico].viscousNeg, fisico);
1392  jconfig.motor_params.friction.coulomb_pos_val = _measureConverter->coulombPos_user2raw(_trq_pids[logico].coulombPos, fisico);
1393  jconfig.motor_params.friction.coulomb_neg_val = _measureConverter->coulombNeg_user2raw(_trq_pids[logico].coulombNeg, fisico);
1394  jconfig.motor_params.friction.velocityThres_val = _measureConverter->velocityThres_user2raw(_trq_pids[logico].velocityThres, fisico);
1395 
1396  jconfig.gearbox_E2J = _gearbox_E2J[logico];
1397 
1398  jconfig.deadzone = _measureConverter->posA2E(_deadzone[logico], fisico);
1399 
1400  jconfig.tcfiltertype=_trq_pids[logico].filterType;
1401 
1402  jconfig.kalman_params.enabled = _kalman_params[logico].enabled;
1403  for(int i=0; i<_kalman_params[logico].x0.size(); i++) jconfig.kalman_params.x0[i] = _kalman_params[logico].x0.at(i);
1404  for(int i=0; i<_kalman_params[logico].Q.size(); i++) jconfig.kalman_params.Q[i] = _kalman_params[logico].Q.at(i);
1405  jconfig.kalman_params.R = _kalman_params[logico].R;
1406  jconfig.kalman_params.P0 = _kalman_params[logico].P0;
1407 
1408  if(false == res->setcheckRemoteValue(protid, &jconfig, 10, 0.010, 0.050))
1409  {
1410  yError() << "FATAL: embObjMotionControl::init() had an error while calling setcheckRemoteValue() for joint config fisico #" << fisico << "in "<< getBoardInfo();
1411  return false;
1412  }
1413  else
1414  {
1415  if(behFlags.verbosewhenok)
1416  {
1417  yDebug() << "embObjMotionControl::init() correctly configured joint config fisico #" << fisico << "in "<< getBoardInfo();
1418  }
1419  }
1420  }
1421 
1422 
1424  // invia la configurazione dei MOTORI //
1426 
1427 
1428  for(int logico=0; logico<_njoints; logico++)
1429  {
1430  int fisico = _axisMap[logico];
1431 
1432  protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, fisico, eoprot_tag_mc_motor_config);
1433  eOmc_motor_config_t motor_cfg = {0};
1434  motor_cfg.maxvelocityofmotor = 0;//_maxMotorVelocity[logico]; //unused yet!
1435  motor_cfg.currentLimits.nominalCurrent = _currentLimits[logico].nominalCurrent;
1436  motor_cfg.currentLimits.overloadCurrent = _currentLimits[logico].overloadCurrent;
1437  motor_cfg.currentLimits.peakCurrent = _currentLimits[logico].peakCurrent;
1438  motor_cfg.gearbox_M2J = _gearbox_M2J[logico];
1439  motor_cfg.rotorEncoderResolution = _motorEncs[logico].resolution;
1440  motor_cfg.rotEncTolerance = _motorEncs[logico].tolerance;
1441  motor_cfg.hasHallSensor = _foc_based_info[logico].hasHallSensor;
1442  motor_cfg.hasRotorEncoder = _foc_based_info[logico].hasRotorEncoder;
1443  motor_cfg.hasTempSensor = _foc_based_info[logico].hasTempSensor;
1444  motor_cfg.hasRotorEncoderIndex = _foc_based_info[logico].hasRotorEncoderIndex;
1445  motor_cfg.hasSpeedEncoder = _foc_based_info[logico].hasSpeedEncoder;
1446  motor_cfg.verbose = _foc_based_info[logico].verbose;
1447  motor_cfg.motorPoles = _foc_based_info[logico].motorPoles;
1448  motor_cfg.rotorIndexOffset = _foc_based_info[logico].rotorIndexOffset;
1449  motor_cfg.rotorEncoderType = _motorEncs[logico].type;
1450  motor_cfg.pwmLimit =_rotorsLimits[logico].pwmMax;
1451  motor_cfg.temperatureLimit = (eOmeas_temperature_t) S_16(_temperatureSensorsVector.at(logico)->convertTempCelsiusToRaw(_temperatureLimits.at(logico).hardwareTemperatureLimit)); //passing raw value not in degree
1452  motor_cfg.limitsofrotor.max = (eOmeas_position_t) S_32(_measureConverter->posA2E(_rotorsLimits[logico].posMax, fisico ));
1453  motor_cfg.limitsofrotor.min = (eOmeas_position_t) S_32(_measureConverter->posA2E(_rotorsLimits[logico].posMin, fisico ));
1454 
1455  yarp::dev::Pid tmp;
1456  tmp = _measureConverter->convert_pid_to_machine(yarp::dev::VOCAB_PIDTYPE_CURRENT, _cur_pids[logico].pid, fisico);
1457  copyPid_iCub2eo(&tmp, &motor_cfg.pidcurrent);
1458 
1459  tmp = _measureConverter->convert_pid_to_machine(yarp::dev::VOCAB_PIDTYPE_VELOCITY, _spd_pids[logico].pid, fisico);
1460  copyPid_iCub2eo(&tmp, &motor_cfg.pidspeed);
1461 
1462  if (false == res->setcheckRemoteValue(protid, &motor_cfg, 10, 0.010, 0.050))
1463  {
1464  yError() << "FATAL: embObjMotionControl::init() had an error while calling setcheckRemoteValue() for motor config fisico #" << fisico << "in "<< getBoardInfo();
1465  return false;
1466  }
1467  else
1468  {
1469  if (behFlags.verbosewhenok)
1470  {
1471  yDebug() << "embObjMotionControl::init() correctly configured motor config fisico #" << fisico << "in "<< getBoardInfo();
1472  }
1473  }
1474  }
1475 
1477  // invia la configurazione del controller //
1479 
1480  //to be done
1481 
1482  yTrace() << "embObjMotionControl::init(): correctly instantiated for " << getBoardInfo();
1483  return true;
1484 }
1485 
1486 
1487 
1489 {
1490  yTrace() << " embObjMotionControl::close()";
1491 
1492  ImplementControlMode::uninitialize();
1493  ImplementEncodersTimed::uninitialize();
1494  ImplementMotorEncoders::uninitialize();
1495  ImplementPositionControl::uninitialize();
1496  ImplementVelocityControl::uninitialize();
1497  ImplementPidControl::uninitialize();
1498  ImplementControlCalibration::uninitialize();
1499  ImplementAmplifierControl::uninitialize();
1500  ImplementImpedanceControl::uninitialize();
1501  ImplementControlLimits::uninitialize();
1502  ImplementTorqueControl::uninitialize();
1503  ImplementPositionDirect::uninitialize();
1504  ImplementInteractionMode::uninitialize();
1505  ImplementRemoteVariables::uninitialize();
1506  ImplementAxisInfo::uninitialize();
1507  ImplementCurrentControl::uninitialize();
1508  ImplementPWMControl::uninitialize();
1509  ImplementJointFault::uninitialize();
1510 
1511  if (_measureConverter) {delete _measureConverter; _measureConverter=0;}
1512 
1513 
1514  if(eomn_serv_diagn_mode_MC_AMOyarp == mcdiagnostics.config.mode)
1515  {
1516  // close the ports
1517  for(size_t i=0; i<mcdiagnostics.ports.size(); i++)
1518  {
1519  mcdiagnostics.ports[i]->close();
1520  delete mcdiagnostics.ports[i];
1521  }
1522  mcdiagnostics.ports.clear();
1523 
1524  mcdiagnostics.config.mode = eomn_serv_diagn_mode_NONE;
1525  mcdiagnostics.config.par16 = 0;
1526  }
1527 
1528  delete event_downsampler;
1529  // in cleanup, at date of 23feb2016 there is a call to ethManager->releaseResource() which ...
1530  // send to config all the boards and stops tx and rx treads.
1531  // thus, in here we cannot call serviceStop(mc) because there will be tx/rx activity only for the first call of ::close().
1532  // i termporarily put serviceStop(eomn_serv_category_all) inside releaseResource()
1533  // todo: later on: clear regulars of mc, stop(mc), inside releaseresource() DO NOT stop tx/rx activity and DO NOT stop all services
1534  // res->serviceStop(eomn_serv_category_mc);
1535  // #warning TODO: clear the regulars imposed by motion-control.
1536 
1537  cleanup();
1538 
1539  return true;
1540 }
1541 
1542 void embObjMotionControl::cleanup(void)
1543 {
1544  if(ethManager == NULL) return;
1545 
1546  int ret = ethManager->releaseResource2(res, this);
1547  res = NULL;
1548  if(ret == -1)
1549  ethManager->killYourself();
1550 }
1551 
1552 
1555 {
1557 }
1558 
1559 bool embObjMotionControl::update(eOprotID32_t id32, double timestamp, void *rxdata)
1560 {
1561  // use this function to update the values cached in the class using data received by the remote boards via the network callbacks
1562  // in embObjMotionControl it is updated only the timestamp of the encoders, thuus i dont used rxdata
1563  size_t joint = eoprot_ID2index(id32);
1564  eOprotEntity_t ent = eoprot_ID2entity(id32);
1565  eOprotTag_t tag = eoprot_ID2tag(id32);
1566 
1567  // rxdata = rxdata;
1568 
1569  // marco.accame: pay attention using rxdata. the rxdata depends on the id32.
1570  // now the function update() is called with rxdata of different types.
1571  // if the tag is eoprot_tag_mc_joint_status, then rxdata is of type eOmc_joint_status_t*
1572  // if the tag is eoprot_tag_mc_joint_status_basic, then rxdata is of type eOmc_joint_status_basic_t*
1573 
1574 
1575  // for the case of id32 which contains an encoder value .... we refresh the timestamp of that encoder
1576 
1577  if(true == initialised())
1578  { // do it only if we already have opened the device
1579  std::lock_guard<std::mutex> lck(_mutex);
1580  _encodersStamp[joint] = timestamp;
1581  }
1582 
1583 
1584  if(eomn_serv_diagn_mode_MC_AMOyarp == mcdiagnostics.config.mode)
1585  {
1586  char str[128] = "boh";
1587 
1588  eoprot_ID2information(id32, str, sizeof(str));
1589 
1590  if((eoprot_entity_mc_joint == ent) && (eoprot_tag_mc_joint_status_debug == tag) && (joint < mcdiagnostics.ports.size()))
1591  {
1592 
1593  eOprotID32_t id32sc = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, joint, eoprot_tag_mc_joint_status_core);
1594  eOmc_joint_status_core_t jcore = {};
1595 
1596  res->getLocalValue(id32sc, &jcore);
1597 
1598  int32_t *debug32 = reinterpret_cast<int32_t*>(rxdata);
1599  // write into relevant port
1600 
1601  Bottle& output = mcdiagnostics.ports[joint]->prepare();
1602  output.clear();
1603  //output.addString("[yt, amo, reg, pos]"); // but we must get the joint and the motor as well
1604  output.addString("[yt, amo, reg, pos]");
1605  output.addFloat64(timestamp);
1606  output.addInt32(debug32[0]);
1607  output.addInt32(debug32[1]);
1608  output.addInt32(jcore.measures.meas_position);
1609  mcdiagnostics.ports[joint]->write();
1610  }
1611  }
1612 
1613  if((eoprot_entity_mc_motor == ent) && (eoprot_tag_mc_motor_status == tag))
1614  {
1615  if(false == initialised())
1616  return true;
1617 
1618  uint8_t motor = eoprot_ID2index(id32);
1619  if((_temperatureSensorsVector.at(motor)->getType() == motor_temperature_sensor_none))
1620  return true;
1621 
1622  eOmc_motor_status_t *mc_motor_status = reinterpret_cast<eOmc_motor_status_t*>(rxdata);
1623 
1624  if((double)mc_motor_status->basic.mot_temperature != temperatureErrorValue_s) //I get a valid value
1625  {
1626  double tmp = _temperatureSensorsVector.at(motor)->convertRawToTempCelsius((double)mc_motor_status->basic.mot_temperature);
1627 
1628  if (tmp > _temperatureLimits[motor].warningTemperatureLimit)
1629  {
1630  if(! _temperatureExceededLimitWatchdog.at(motor).isStarted())
1631  {
1632  yWarning() << getBoardInfo() << "Motor" << motor << "The temperature (" << tmp << "[ ℃ ] ) exceeds the warning limit (" << _temperatureLimits[motor].warningTemperatureLimit << "[ ℃ ] ). Processes not stopped but it is strongly recommended decreasing motor usage or reducing currents and PWMs to not risk motor damaging";
1633  _temperatureExceededLimitWatchdog.at(motor).start();
1634  }
1635  else
1636  {
1637  if(_temperatureExceededLimitWatchdog.at(motor).isExpired())
1638  {
1639  yWarning() << getBoardInfo() << "Motor" << motor << "The temperature (" << tmp << "[ ℃ ] ) exceeds the warning limit (" << _temperatureLimits[motor].warningTemperatureLimit << "[ ℃ ] ) again!. Processes not stopped but it is strongly recommended decreasing motor usage or reducing currents and PWMs to not risk motor damaging";
1640  _temperatureExceededLimitWatchdog.at(motor).start();
1641  }
1642  _temperatureExceededLimitWatchdog.at(motor).increment();
1643  }
1644  }
1645  else
1646  {
1647  _temperatureExceededLimitWatchdog.at(motor).clear();
1648  }
1649  }
1650  else //I get a NOT valid value
1651  {
1652  if(! _temperatureSensorErrorWatchdog.at(motor).isStarted())
1653  {
1654  yError() << getBoardInfo() << "At timestamp" << yarp::os::Time::now() << "In motor" << motor << "cannot read Temperature from I2C. There might be cabling problems, TDB cable might be broken or sensor unreachable";
1655  _temperatureSensorErrorWatchdog.at(motor).start();
1656  }
1657  else
1658  {
1659  _temperatureSensorErrorWatchdog.at(motor).increment();
1660  if( _temperatureSensorErrorWatchdog.at(motor).isExpired())
1661  {
1662  yError()<< getBoardInfo() << "Motor" << motor << "failed to read temperature for" << yarp::os::Time::now() - _temperatureSensorErrorWatchdog.at(motor).getStartTime() << "seconds";
1663  _temperatureSensorErrorWatchdog.at(motor).start();
1664  }
1665  }
1666  }
1667  }
1668 
1669  return true;
1670 }
1671 
1672 
1673 bool embObjMotionControl::getEntityName(uint32_t entityId, std::string &entityName)
1674 {
1675  bool ret = getAxisNameRaw(entityId, entityName);
1676 
1677  //since getAxisNameRaw set "ERROR" in entityName when an error occurred,
1678  //while this function has to return an empty string, I reset the entityName string
1679  if(!ret)
1680  {
1681  entityName.clear();
1682  }
1683  return ret;
1684 
1685 }
1686 
1688 bool embObjMotionControl::setPidRaw(const PidControlTypeEnum& pidtype, int j, const Pid &pid)
1689 {
1690  switch (pidtype)
1691  {
1692  case VOCAB_PIDTYPE_POSITION:
1693  helper_setPosPidRaw(j,pid);
1694  break;
1695  case VOCAB_PIDTYPE_VELOCITY:
1696  //helper_setVelPidRaw(j,pid);
1697  helper_setSpdPidRaw(j, pid);
1698  break;
1699  case VOCAB_PIDTYPE_TORQUE:
1700  helper_setTrqPidRaw(j, pid);
1701  break;
1702  case VOCAB_PIDTYPE_CURRENT:
1703  helper_setCurPidRaw(j,pid);
1704  break;
1705  default:
1706  yError()<<"Invalid pidtype:"<<pidtype;
1707  break;
1708  }
1709  return true;
1710 }
1711 
1712 bool embObjMotionControl::getPidRaw (const PidControlTypeEnum& pidtype, int axis, Pid *pid)
1713 {
1714  switch (pidtype)
1715  {
1716  case VOCAB_PIDTYPE_POSITION:
1717  helper_getPosPidRaw(axis,pid);
1718  break;
1719  case VOCAB_PIDTYPE_VELOCITY:
1720  //helper_getVelPidRaw(axis,pid);
1721  helper_getSpdPidRaw(axis, pid);
1722  break;
1723  case VOCAB_PIDTYPE_TORQUE:
1724  helper_getTrqPidRaw(axis, pid);
1725  break;
1726  case VOCAB_PIDTYPE_CURRENT:
1727  helper_getCurPidRaw(axis,pid);
1728  break;
1729  default:
1730  yError()<<"Invalid pidtype:"<<pidtype;
1731  break;
1732  }
1733  return true;
1734 }
1735 
1736 bool embObjMotionControl::helper_setPosPidRaw(int j, const Pid &pid)
1737 {
1738  eOprotID32_t protoId = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_pidtrajectory);
1739  eOmc_PID_t outPid;
1740  Pid hwPid = pid;
1741 
1742  //printf("helper_setPosPid: kp=%f ki=%f kd=%f\n", hwPid.kp, hwPid.ki, hwPid.kd);
1743  copyPid_iCub2eo(&hwPid, &outPid);
1744 
1745  if(false == res->setRemoteValue(protoId, &outPid))
1746  {
1747  yError() << "while setting position PIDs for " << getBoardInfo() << " joint " << j;
1748  return false;
1749  }
1750 
1751  return true;
1752 }
1753 
1754 bool embObjMotionControl::setPidsRaw(const PidControlTypeEnum& pidtype, const Pid *pids)
1755 {
1756  bool ret = true;
1757  for(int j=0; j< _njoints; j++)
1758  {
1759  ret &= setPidRaw(pidtype, j, pids[j]);
1760  }
1761  return ret;
1762 }
1763 
1764 bool embObjMotionControl::setPidReferenceRaw(const PidControlTypeEnum& pidtype, int j, double ref)
1765 {
1766  return NOT_YET_IMPLEMENTED("setPidReferenceRaw");
1767 }
1768 
1769 bool embObjMotionControl::setPidReferencesRaw(const PidControlTypeEnum& pidtype, const double *refs)
1770 {
1771  bool ret = true;
1772  for(int j=0, index=0; j< _njoints; j++, index++)
1773  {
1774  ret &= setPidReferenceRaw(pidtype, j, refs[index]);
1775  }
1776  return ret;
1777 }
1778 
1779 bool embObjMotionControl::setPidErrorLimitRaw(const PidControlTypeEnum& pidtype, int j, double limit)
1780 {
1781  // print_debug(AC_trace_file, "embObjMotionControl::setErrorLimitRaw()");
1782  return NOT_YET_IMPLEMENTED("setErrorLimitRaw");
1783 }
1784 
1785 bool embObjMotionControl::setPidErrorLimitsRaw(const PidControlTypeEnum& pidtype, const double *limits)
1786 {
1787  // print_debug(AC_trace_file, "embObjMotionControl::setErrorLimitsRaw()");
1788  return NOT_YET_IMPLEMENTED("setErrorLimitsRaw");
1789 }
1790 
1791 bool embObjMotionControl::getPidErrorRaw(const PidControlTypeEnum& pidtype, int j, double *err)
1792 {
1793  uint16_t size = 0;
1794  eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_core);
1795  eOmc_joint_status_core_t jcore = {0};
1796  *err = 0;
1797  if(!res->getLocalValue(id32, &jcore))
1798  return false;
1799 
1800  switch(pidtype)
1801  {
1802  case VOCAB_PIDTYPE_POSITION:
1803  {
1804  if((eomc_controlmode_torque == jcore.modes.controlmodestatus) ||
1805  (eomc_controlmode_openloop == jcore.modes.controlmodestatus) ||
1806  (eomc_controlmode_current == jcore.modes.controlmodestatus))
1807  return true;
1808  else
1809  *err = (double) jcore.ofpid.generic.error1;
1810  }
1811  break;
1812  /*
1813  case VOCAB_PIDTYPE_DIRECT:
1814  {
1815  *err=0; //not yet implemented
1816  NOT_YET_IMPLEMENTED("getPidErrorRaw VOCAB_PIDTYPE_DIRECT");
1817  }
1818  break;
1819  */
1820  case VOCAB_PIDTYPE_TORQUE:
1821  {
1822  if ((eOmc_interactionmode_compliant == jcore.modes.interactionmodestatus) &&
1823  (eomc_controlmode_position == jcore.modes.controlmodestatus))
1824  {
1825  *err = (double) jcore.ofpid.complpos.errtrq;
1826  }
1827 
1828  if(eomc_controlmode_torque == jcore.modes.controlmodestatus)
1829  {
1830  *err = (double) jcore.ofpid.torque.errtrq;
1831  }
1832  }
1833  break;
1834  case VOCAB_PIDTYPE_VELOCITY:
1835  {
1836  *err = 0; //not yet implemented
1837  NOT_YET_IMPLEMENTED("getPidErrorRaw VOCAB_PIDTYPE_LLSPEED");
1838  }
1839  break;
1840  case VOCAB_PIDTYPE_CURRENT:
1841  {
1842  *err = 0; //not yet implemented
1843  NOT_YET_IMPLEMENTED("getPidErrorRaw VOCAB_PIDTYPE_CURRENT");
1844  }
1845  break;
1846  default:
1847  {
1848  yError()<<"Invalid pidtype:"<<pidtype;
1849  }
1850  break;
1851  }
1852  return true;
1853 }
1854 
1855 bool embObjMotionControl::getPidErrorsRaw(const PidControlTypeEnum& pidtype, double *errs)
1856 {
1857  bool ret = true;
1858  for(int j=0; j< _njoints; j++)
1859  {
1860  ret &= getPidErrorRaw(pidtype, j, &errs[j]);
1861  }
1862  return ret;
1863 }
1864 
1865 bool embObjMotionControl::helper_getPosPidRaw(int j, Pid *pid)
1866 {
1867  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_pidtrajectory);
1868 
1869  uint16_t size;
1870  eOmc_PID_t eoPID = {0};
1871 
1872 
1873 #ifdef NETWORK_PERFORMANCE_BENCHMARK
1874  double start = yarp::os::Time::now();
1875 #endif
1876 
1877  bool ret = askRemoteValue(protid, &eoPID, size);
1878 
1879 #ifdef NETWORK_PERFORMANCE_BENCHMARK
1880  double end = yarp::os::Time::now();
1881  m_responseTimingVerifier.tick(end-start, start);
1882 #endif
1883 
1884  if(!ret)
1885  return false;
1886 
1887  copyPid_eo2iCub(&eoPID, pid);
1888 
1889  //printf("helper_getPosPid: kp=%f ki=%f kd=%f\n", pid->kp, pid->ki, pid->kd);
1890 
1891  return true;
1892 }
1893 
1894 bool embObjMotionControl::helper_getPosPidsRaw(Pid *pid)
1895 {
1896  std::vector<eOmc_PID_t> eoPIDList(_njoints);
1897  bool ret = askRemoteValues(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, eoprot_tag_mc_joint_config_pidtrajectory, eoPIDList);
1898  if(!ret)
1899  {
1900  yError() << "failed helper_getPosPidsRaw for" << getBoardInfo();
1901  return false;
1902  }
1903 
1904  for(int j=0; j<_njoints; j++)
1905  {
1906  copyPid_eo2iCub(&eoPIDList[j], &pid[j]);
1907 
1908  //printf("helper_getPosPid: kp=%f ki=%f kd=%f\n", pid->kp, pid->ki, pid->kd);
1909  }
1910  return true;
1911 }
1912 
1913 
1914 bool embObjMotionControl::getPidsRaw(const PidControlTypeEnum& pidtype, Pid *pids)
1915 {
1916  switch (pidtype)
1917  {
1918  case VOCAB_PIDTYPE_POSITION:
1919  helper_getPosPidsRaw(pids);
1920  break;
1921  //case VOCAB_PIDTYPE_DIRECT:
1922  // helper_getVelPidsRaw(pids);
1923  // break;
1924  case VOCAB_PIDTYPE_TORQUE:
1925  helper_getTrqPidsRaw(pids);
1926  break;
1927  case VOCAB_PIDTYPE_CURRENT:
1928  helper_getCurPidsRaw(pids);
1929  break;
1930  case VOCAB_PIDTYPE_VELOCITY:
1931  helper_getSpdPidsRaw(pids);
1932  break;
1933  default:
1934  yError()<<"Invalid pidtype:"<<pidtype;
1935  break;
1936  }
1937  return true;
1938 }
1939 
1940 bool embObjMotionControl::getPidReferenceRaw(const PidControlTypeEnum& pidtype, int j, double *ref)
1941 {
1942  eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_core);
1943  eOmc_joint_status_core_t jcore = {0};
1944  *ref = 0;
1945  if(!res->getLocalValue(id32, &jcore))
1946  return false;
1947 
1948  switch (pidtype)
1949  {
1950  case VOCAB_PIDTYPE_POSITION:
1951  {
1952  if((eomc_controlmode_torque == jcore.modes.controlmodestatus) ||
1953  (eomc_controlmode_openloop == jcore.modes.controlmodestatus) ||
1954  (eomc_controlmode_current == jcore.modes.controlmodestatus))
1955  { *ref = 0; yError() << "Invalid getPidReferenceRaw() request for current control mode"; return true; }
1956  *ref = (double) jcore.ofpid.generic.reference1;
1957  }
1958  break;
1959  //case VOCAB_PIDTYPE_DIRECT:
1960  //{
1961  // *ref=0;
1962  // NOT_YET_IMPLEMENTED("getPidReferenceRaw VOCAB_PIDTYPE_DIRECT");
1963  //}
1964  //break;
1965  case VOCAB_PIDTYPE_TORQUE:
1966  {
1967  *ref = 0;
1968  NOT_YET_IMPLEMENTED("getPidReferenceRaw VOCAB_PIDTYPE_TORQUE");
1969  }
1970  break;
1971  case VOCAB_PIDTYPE_CURRENT:
1972  {
1973  *ref=0;
1974  NOT_YET_IMPLEMENTED("getPidReferenceRaw VOCAB_PIDTYPE_CURRENT");
1975  }
1976  break;
1977  case VOCAB_PIDTYPE_VELOCITY:
1978  {
1979  *ref = 0;
1980  NOT_YET_IMPLEMENTED("getPidReferenceRaw VOCAB_PIDTYPE_VELOCITY");
1981  }
1982  break;
1983  default:
1984  {
1985  *ref=0;
1986  yError()<<"Invalid pidtype:"<<pidtype;
1987  }
1988  break;
1989  }
1990  return true;
1991 }
1992 
1993 bool embObjMotionControl::getPidReferencesRaw(const PidControlTypeEnum& pidtype, double *refs)
1994 {
1995  bool ret = true;
1996 
1997  // just one joint at time, wait answer before getting to the next.
1998  // This is because otherwise too many msg will be placed into can queue
1999  for(int j=0; j< _njoints; j++)
2000  {
2001  ret &= getPidReferenceRaw(pidtype, j, &refs[j]);
2002  }
2003  return ret;
2004 }
2005 
2006 bool embObjMotionControl::getPidErrorLimitRaw(const PidControlTypeEnum& pidtype, int j, double *limit)
2007 {
2008  return NOT_YET_IMPLEMENTED("getErrorLimit");
2009 }
2010 
2011 bool embObjMotionControl::getPidErrorLimitsRaw(const PidControlTypeEnum& pidtype, double *limits)
2012 {
2013  return NOT_YET_IMPLEMENTED("getErrorLimit");
2014 }
2015 
2016 bool embObjMotionControl::resetPidRaw(const PidControlTypeEnum& pidtype, int j)
2017 {
2018  return NOT_YET_IMPLEMENTED("resetPid");
2019 }
2020 
2021 bool embObjMotionControl::disablePidRaw(const PidControlTypeEnum& pidtype, int j)
2022 {
2023  return DEPRECATED("disablePidRaw");
2024 }
2025 
2026 bool embObjMotionControl::enablePidRaw(const PidControlTypeEnum& pidtype, int j)
2027 {
2028  return DEPRECATED("enablePidRaw");
2029 }
2030 
2031 bool embObjMotionControl::setPidOffsetRaw(const PidControlTypeEnum& pidtype, int j, double v)
2032 {
2033  return NOT_YET_IMPLEMENTED("setOffset");
2034 }
2035 
2037 // Velocity control interface raw //
2039 
2041 {
2042  int mode=0;
2043  getControlModeRaw(j, &mode);
2044  if( (mode != VOCAB_CM_VELOCITY) &&
2045  (mode != VOCAB_CM_MIXED) &&
2046  (mode != VOCAB_CM_IMPEDANCE_VEL) &&
2047  (mode != VOCAB_CM_IDLE))
2048  {
2049  if(event_downsampler->canprint())
2050  {
2051  yError() << "velocityMoveRaw: skipping command because " << getBoardInfo() << " joint " << j << " is not in VOCAB_CM_VELOCITY mode";
2052  }
2053  return true;
2054  }
2055 
2056  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_setpoint);
2057 
2058  _ref_command_speeds[j] = sp ; // save internally the new value of speed.
2059 
2060  eOmc_setpoint_t setpoint;
2061  setpoint.type = eomc_setpoint_velocity;
2062  setpoint.to.velocity.value = (eOmeas_velocity_t) S_32(_ref_command_speeds[j]);
2063  setpoint.to.velocity.withacceleration = (eOmeas_acceleration_t) S_32(_ref_accs[j]);
2064 
2065 
2066  if(false == res->setRemoteValue(protid, &setpoint))
2067  {
2068  yError() << "while setting velocity mode";
2069  return false;
2070  }
2071  return true;
2072 }
2073 
2075 {
2076  bool ret = true;
2077  eOmc_setpoint_t setpoint;
2078 
2079  setpoint.type = eomc_setpoint_velocity;
2080 
2081  for(int j=0; j<_njoints; j++)
2082  {
2083  ret = velocityMoveRaw(j, sp[j]) && ret;
2084  }
2085 
2086  return ret;
2087 }
2088 
2089 
2091 // Calibration control interface //
2093 
2094 bool embObjMotionControl::setCalibrationParametersRaw(int j, const CalibrationParameters& params)
2095 {
2096  yTrace() << "setCalibrationParametersRaw for " << getBoardInfo() << "joint" << j;
2097 
2098  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_calibration);
2099  eOmc_calibrator_t calib;
2100  memset(&calib, 0x00, sizeof(calib));
2101  calib.type = params.type;
2102 
2103  switch (calib.type)
2104  {
2105  // muove -> amp+pid, poi calib
2106  case eomc_calibration_type0_hard_stops:
2107  calib.params.type0.pwmlimit = (int16_t)S_16(params.param1);
2108  calib.params.type0.velocity = (eOmeas_velocity_t)S_32(params.param2);
2109  calib.params.type0.calibrationZero = (int32_t)S_32(_measureConverter->posA2E(params.paramZero, j));
2110  break;
2111 
2112  // fermo
2113  case eomc_calibration_type1_abs_sens_analog:
2114  calib.params.type1.position = (int16_t)S_16(params.param1);
2115  calib.params.type1.velocity = (eOmeas_velocity_t)S_32(params.param2);
2116  calib.params.type1.calibrationZero = (int32_t)S_32(_measureConverter->posA2E(params.paramZero, j));
2117  break;
2118 
2119  // muove
2120  case eomc_calibration_type2_hard_stops_diff:
2121  calib.params.type2.pwmlimit = (int16_t)S_16(params.param1);
2122  calib.params.type2.velocity = (eOmeas_velocity_t)S_32(params.param2);
2123  calib.params.type2.calibrationZero = (int32_t)S_32(_measureConverter->posA2E(params.paramZero, j));
2124  break;
2125 
2126  // muove
2127  case eomc_calibration_type3_abs_sens_digital:
2128  calib.params.type3.position = (int16_t)S_16(params.param1);
2129  calib.params.type3.velocity = (eOmeas_velocity_t)S_32(params.param2);
2130  calib.params.type3.offset = (int32_t)S_32(params.param3);
2131  calib.params.type3.calibrationZero = (int32_t)S_32(_measureConverter->posA2E(params.paramZero, j));
2132  break;
2133 
2134  // muove
2135  case eomc_calibration_type4_abs_and_incremental:
2136  calib.params.type4.position = (int16_t)S_16(params.param1);
2137  calib.params.type4.velocity = (eOmeas_velocity_t)S_32(params.param2);
2138  calib.params.type4.maxencoder = (int32_t)S_32(params.param3);
2139  calib.params.type4.calibrationZero = (int32_t)S_32(_measureConverter->posA2E(params.paramZero, j));
2140  break;
2141 
2142  // muove
2143  case eomc_calibration_type5_hard_stops:
2144  calib.params.type5.pwmlimit = (int32_t) S_32(params.param1);
2145  calib.params.type5.final_pos = (int32_t) S_32(params.param2);
2146  calib.params.type5.calibrationZero = (int32_t)S_32(_measureConverter->posA2E(params.paramZero, j));
2147  break;
2148 
2149  // muove
2150  case eomc_calibration_type6_mais:
2151  calib.params.type6.position = (int32_t)S_32(params.param1);
2152  calib.params.type6.velocity = (int32_t)S_32(params.param2);
2153  calib.params.type6.current = (int32_t)S_32(params.param3);
2154  calib.params.type6.vmin = (int32_t)S_32(params.param4);
2155  calib.params.type6.vmax = (int32_t)S_32(params.param5);
2156  calib.params.type6.calibrationZero = (int32_t)S_32(_measureConverter->posA2E(params.paramZero, j));
2157  break;
2158 
2159  // muove
2160  case eomc_calibration_type7_hall_sensor:
2161  calib.params.type7.position = (int32_t)S_32(params.param1);
2162  calib.params.type7.velocity = (int32_t)S_32(params.param2);
2163  //param3 is not used
2164  calib.params.type7.vmin = (int32_t)S_32(params.param4);
2165  calib.params.type7.vmax = (int32_t)S_32(params.param5);
2166  calib.params.type7.calibrationZero = (int32_t)S_32(_measureConverter->posA2E(params.paramZero, j));
2167  break;
2168 
2169  //muove
2170  case eomc_calibration_type8_tripod_internal_hard_stop:
2171  calib.params.type8.pwmlimit = (int32_t) S_32(params.param1);
2172  calib.params.type8.max_delta = (int32_t) S_32(params.param2);
2173  calib.params.type8.calibrationZero = (int32_t)S_32(params.paramZero /* * _angleToEncoder[j] */);
2174  break;
2175 
2176  case eomc_calibration_type9_tripod_external_hard_stop:
2177  calib.params.type9.pwmlimit = (int32_t) S_32(params.param1);
2178  calib.params.type9.max_delta = (int32_t) S_32(params.param2);
2179  calib.params.type9.calibrationZero = (int32_t)S_32(params.paramZero /* * _angleToEncoder[j] */);
2180  break;
2181 
2182  case eomc_calibration_type10_abs_hard_stop:
2183  calib.params.type10.pwmlimit = (int32_t) S_32(params.param1);
2184  calib.params.type10.calibrationZero = (int32_t)S_32(_measureConverter->posA2E(params.paramZero, j));
2185  break;
2186 
2187  case eomc_calibration_type11_cer_hands:
2188  calib.params.type11.offset0 = (int32_t)S_32(params.param1);
2189  calib.params.type11.offset1 = (int32_t)S_32(params.param2);
2190  calib.params.type11.offset2 = (int32_t)S_32(params.param3);
2191  calib.params.type11.cable_range = (int32_t)S_32(params.param4);
2192  calib.params.type11.pwm = (int32_t)S_32(params.param5);
2193  //calib.params.type11.calibrationZero = 32767;//(int32_t)S_32(params.paramZero * _angleToEncoder[j]);
2194  break;
2195 
2196  case eomc_calibration_type12_absolute_sensor:
2197  calib.params.type12.rawValueAtZeroPos = (int32_t)S_32(params.param1);
2198  calib.params.type12.calibrationDelta = (int32_t)S_32(_measureConverter->posA2E(params.paramZero, j));
2199  break;
2200 
2201  case eomc_calibration_type13_cer_hands_2:
2202  calib.params.type13.rawValueAtZeroPos0 = (int32_t)S_32(params.param1);
2203  calib.params.type13.rawValueAtZeroPos1 = (int32_t)S_32(params.param2);
2204  calib.params.type13.rawValueAtZeroPos2 = (int32_t)S_32(params.param3);
2205  calib.params.type13.rawValueAtZeroPos3 = (int32_t)S_32(params.param4);
2206  break;
2207 
2208  case eomc_calibration_type14_qenc_hard_stop_and_fap:
2209  calib.params.type14.pwmlimit = (int32_t)S_32(params.param1);
2210  calib.params.type14.final_pos = (int32_t)S_32(params.param2);
2211  calib.params.type14.invertdirection = (uint8_t)U_32(params.param3);
2212  calib.params.type14.rotation = (int32_t)S_32(params.param4);
2213 
2214  if (calib.params.type14.invertdirection != 0 && calib.params.type14.invertdirection != 1)
2215  {
2216  yError() << "Error in param3 of calibartion type 14 for joint " << j << "Admitted values are: 0=FALSE and 1=TRUE";
2217  return false;
2218  }
2219 
2220 
2221  if(!checkCalib14RotationParam(calib.params.type14.rotation))
2222  {
2223  yError() << "Error in param4 of calibartion type 14 for joint " << j << "Admitted values are: 0, 32768, 16384, -16384 [0, 180, 90, -90] in iCubDegree";
2224  return false;
2225  }
2226  calib.params.type14.offset = (int32_t)S_32(params.param5);
2227  calib.params.type14.calibrationZero = (int32_t)S_32(_measureConverter->posA2E(params.paramZero, j));
2228 
2229  yDebug() << "***** calib.params.type14.pwmlimit = " <<calib.params.type14.pwmlimit;
2230  yDebug() << "***** calib.params.type14.final_pos = " <<calib.params.type14.final_pos;
2231  yDebug() << "***** calib.params.type14.invertdirection = " <<calib.params.type14.invertdirection;
2232  yDebug() << "***** calib.params.type14.rotation = " <<calib.params.type14.rotation;
2233  yDebug() << "***** calib.params.type14.offset = " <<calib.params.type14.offset;
2234  yDebug() << "***** calib.params.type14.calibrationZero = " <<calib.params.type14.calibrationZero;
2235  break;
2236 
2237  default:
2238  yError() << "Calibration type unknown!! (embObjMotionControl)\n";
2239  return false;
2240  break;
2241  }
2242 
2243  if (false == res->setRemoteValue(protid, &calib))
2244  {
2245  yError() << "while setting velocity mode";
2246  return false;
2247  }
2248 
2249  _calibrated[j] = true;
2250 
2251  return true;
2252 }
2253 
2254 bool embObjMotionControl::checkCalib14RotationParam(int32_t calib_param4)
2255 {
2256  eOmc_calib14_ROT_t urotation = eomc_int2calib14_ROT(calib_param4);
2257 
2258  if (urotation == eOmc_calib14_ROT_zero ||
2259  urotation == eOmc_calib14_ROT_plus180 ||
2260  urotation == eOmc_calib14_ROT_plus090 ||
2261  urotation == eOmc_calib14_ROT_minus090)
2262  {
2263  return true;
2264  }
2265 
2266  return false;
2267 }
2268 
2269 bool embObjMotionControl::calibrateAxisWithParamsRaw(int j, unsigned int type, double p1, double p2, double p3)
2270 {
2271  yTrace() << "calibrateRaw for" << getBoardInfo() << "joint" << j;
2272 
2273  // Tenere il check o forzare questi sottostati?
2274 // if(!_enabledAmp[j ] )
2275 // {
2276 // yWarning () << "Called calibrate for joint " << j << "with PWM(AMP) not enabled, forcing it!!";
2277 // // return false;
2278 // }
2279 
2280 // if(!_enabledPid[j ])
2281 // {
2282 // yWarning () << "Called calibrate for joint " << j << "with PID not enabled, forcing it!!";
2283 // // return false;
2284 // }
2285 
2286  // There is no explicit command "go to calibration mode" but it is implicit in the calibration command
2287 
2288 
2289  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_calibration);
2290  eOmc_calibrator_t calib;
2291  memset(&calib, 0x00, sizeof(calib));
2292  calib.type = type;
2293 
2294  switch(type)
2295  {
2296  // muove -> amp+pid, poi calib
2297  case eomc_calibration_type0_hard_stops:
2298  calib.params.type0.pwmlimit = (int16_t) S_16(p1);
2299  calib.params.type0.velocity = (eOmeas_velocity_t) S_32(p2);
2300  break;
2301 
2302  // fermo
2303  case eomc_calibration_type1_abs_sens_analog:
2304  calib.params.type1.position = (int16_t) S_16(p1);
2305  calib.params.type1.velocity = (eOmeas_velocity_t) S_32(p2);
2306  break;
2307 
2308  // muove
2309  case eomc_calibration_type2_hard_stops_diff:
2310  calib.params.type2.pwmlimit = (int16_t) S_16(p1);
2311  calib.params.type2.velocity = (eOmeas_velocity_t) S_32(p2);
2312  break;
2313 
2314  // muove
2315  case eomc_calibration_type3_abs_sens_digital:
2316  calib.params.type3.position = (int16_t) S_16(p1);
2317  calib.params.type3.velocity = (eOmeas_velocity_t) S_32(p2);
2318  calib.params.type3.offset = (int32_t) S_32(p3);
2319  break;
2320 
2321  // muove
2322  case eomc_calibration_type4_abs_and_incremental:
2323  calib.params.type4.position = (int16_t) S_16(p1);
2324  calib.params.type4.velocity = (eOmeas_velocity_t) S_32(p2);
2325  calib.params.type4.maxencoder = (int32_t) S_32(p3);
2326  break;
2327 
2328  default:
2329  yError () << "Calibration type unknown!! (embObjMotionControl)\n";
2330  return false;
2331  break;
2332  }
2333 
2334  if(false == res->setRemoteValue(protid, &calib))
2335  {
2336  yError() << "while setting velocity mode";
2337  return false;
2338  }
2339 
2340  _calibrated[j ] = true;
2341 
2342  return true;
2343 }
2344 
2345 
2347 {
2348  bool result = false;
2349  eOenum08_t temp = 0;
2350  uint16_t size = 0;
2351  eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, axis, eoprot_tag_mc_joint_status_core_modes_controlmodestatus);
2352  if(false == askRemoteValue(id32, &temp, size))
2353  {
2354  yError () << "Failure of askRemoteValue() inside embObjMotionControl::doneRaw(axis=" << axis << ") for " << getBoardInfo();
2355  return false;
2356  }
2357 
2358  eOmc_controlmode_t type = (eOmc_controlmode_t) temp;
2359 
2360 
2361  // if the control mode is no longer a calibration type, it means calibration ended
2362  if (eomc_controlmode_idle == type)
2363  {
2364  result = false;
2365  }
2366  else if (eomc_controlmode_calib == type)
2367  {
2368  result = false;
2369  }
2370  else if (eomc_controlmode_hwFault == type)
2371  {
2372  yError("unable to complete calibration: joint %d in 'hw_fault status' inside doneRaw() function", axis);
2373  result = false;
2374  }
2375  else if (eomc_controlmode_notConfigured == type)
2376  {
2377  yError("unable to complete calibration: joint %d in 'not_configured' status inside doneRaw() function", axis);
2378  result = false;
2379  }
2380  else if (eomc_controlmode_unknownError == type)
2381  {
2382  yError("unable to complete calibration: joint %d in 'unknownError' status inside doneRaw() function", axis);
2383  result = false;
2384  }
2385  else if (eomc_controlmode_configured == type)
2386  {
2387  yError("unable to complete calibration: joint %d in 'configured' status inside doneRaw() function", axis);
2388  result = false;
2389  }
2390  else
2391  {
2392  result = true;
2393  }
2394  return result;
2395 }
2396 
2398 // Position control interface //
2400 
2402 {
2403  *ax=_njoints;
2404 
2405  return true;
2406 }
2407 
2409 {
2410  if (yarp::os::Time::now()-_last_position_move_time[j]<MAX_POSITION_MOVE_INTERVAL)
2411  {
2412  yWarning() << "Performance warning: You are using positionMove commands at high rate (<"<< MAX_POSITION_MOVE_INTERVAL*1000.0 <<" ms). Probably position control mode is not the right control mode to use.";
2413  }
2414  _last_position_move_time[j] = yarp::os::Time::now();
2415 
2416  int mode = 0;
2417  getControlModeRaw(j, &mode);
2418  if( (mode != VOCAB_CM_POSITION) &&
2419  (mode != VOCAB_CM_MIXED) &&
2420  (mode != VOCAB_CM_IMPEDANCE_POS) &&
2421  (mode != VOCAB_CM_IDLE))
2422  {
2423  if (event_downsampler->canprint())
2424  {
2425  yError() << "positionMoveRaw: skipping command because " << getBoardInfo() << " joint " << j << " is not in VOCAB_CM_POSITION mode";
2426  }
2427  return true;
2428  }
2429 
2430  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_setpoint);
2431  _ref_command_positions[j] = ref; // save internally the new value of pos.
2432 
2433  eOmc_setpoint_t setpoint;
2434 
2435  setpoint.type = (eOenum08_t) eomc_setpoint_position;
2436  setpoint.to.position.value = (eOmeas_position_t) S_32(_ref_command_positions[j]);
2437  setpoint.to.position.withvelocity = (eOmeas_velocity_t) S_32(_ref_speeds[j]);
2438 
2439  return res->setRemoteValue(protid, &setpoint);
2440 }
2441 
2443 {
2444  bool ret = true;
2445 
2446  for(int j=0, index=0; j< _njoints; j++, index++)
2447  {
2448  ret &= positionMoveRaw(j, refs[index]);
2449  }
2450  return ret;
2451 }
2452 
2453 bool embObjMotionControl::relativeMoveRaw(int j, double delta)
2454 {
2455  return NOT_YET_IMPLEMENTED("positionRelative");
2456 }
2457 
2458 bool embObjMotionControl::relativeMoveRaw(const double *deltas)
2459 {
2460  return NOT_YET_IMPLEMENTED("positionRelative");
2461 }
2462 
2463 
2465 {
2466  eObool_t ismotiondone = eobool_false;
2467  uint16_t size = 0;
2468 
2469  eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_core_modes_ismotiondone);
2470  if(false == askRemoteValue(id32, &ismotiondone, size))
2471  {
2472  yError () << "Failure of askRemoteValue() inside embObjMotionControl::checkMotionDoneRaw(j=" << j << ") for " << getBoardInfo();
2473  return false;
2474  }
2475 
2476 
2477  *flag = ismotiondone; // eObool_t can have values only amongst: eobool_true (1) or eobool_false (0).
2478 
2479  return true;
2480 }
2481 
2483 {
2484  std::vector <eObool_t> ismotiondoneList(_njoints);
2485  bool ret = askRemoteValues(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, eoprot_tag_mc_joint_status_core_modes_ismotiondone, ismotiondoneList);
2486  if(false == ret)
2487  {
2488  yError () << "Failure of askRemoteValues() inside embObjMotionControl::checkMotionDoneRaw for all joints of" << getBoardInfo();
2489  return false;
2490  }
2491  *flag=true;
2492  for(int j=0; j<_njoints; j++)
2493  {
2494  *flag &= ismotiondoneList[j]; // eObool_t can have values only amongst: eobool_true (1) or eobool_false (0).
2495  }
2496  return true;
2497 }
2498 
2500 {
2501  // Velocity is expressed in iDegrees/s
2502  // save internally the new value of speed; it'll be used in the positionMove
2503  int index = j ;
2504  _ref_speeds[index] = sp;
2505  return true;
2506 }
2507 
2509 {
2510  // Velocity is expressed in iDegrees/s
2511  // save internally the new value of speed; it'll be used in the positionMove
2512  for(int j=0, index=0; j< _njoints; j++, index++)
2513  {
2514  _ref_speeds[index] = spds[index];
2515  }
2516  return true;
2517 }
2518 
2520 {
2521  // Acceleration is expressed in iDegrees/s^2
2522  // save internally the new value of the acceleration; it'll be used in the velocityMove command
2523 
2524  if (acc > 1e6)
2525  {
2526  _ref_accs[j ] = 1e6;
2527  }
2528  else if (acc < -1e6)
2529  {
2530  _ref_accs[j ] = -1e6;
2531  }
2532  else
2533  {
2534  _ref_accs[j ] = acc;
2535  }
2536 
2537  return true;
2538 }
2539 
2541 {
2542  // Acceleration is expressed in iDegrees/s^2
2543  // save internally the new value of the acceleration; it'll be used in the velocityMove command
2544  for(int j=0, index=0; j< _njoints; j++, index++)
2545  {
2546  if (accs[j] > 1e6)
2547  {
2548  _ref_accs[index] = 1e6;
2549  }
2550  else if (accs[j] < -1e6)
2551  {
2552  _ref_accs[index] = -1e6;
2553  }
2554  else
2555  {
2556  _ref_accs[index] = accs[j];
2557  }
2558  }
2559  return true;
2560 }
2561 
2562 bool embObjMotionControl::getRefSpeedRaw(int j, double *spd)
2563 {
2564  if (j<0 || j>_njoints) return false;
2565 #if ASK_REFERENCE_TO_FIRMWARE
2566  *spd = _ref_speeds[j];
2567  //return NOT_YET_IMPLEMENTED("getRefSpeedRaw");
2568 #else
2569  *spd = _ref_speeds[j];
2570 #endif
2571  return true;
2572 }
2573 
2575 {
2576  memcpy(spds, _ref_speeds, sizeof(double) * _njoints);
2577  return true;
2578 }
2579 
2581 {
2582  *acc = _ref_accs[j];
2583  return true;
2584 }
2585 
2587 {
2588  memcpy(accs, _ref_accs, sizeof(double) * _njoints);
2589  return true;
2590 }
2591 
2593 {
2594  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_stoptrajectory);
2595 
2596  eObool_t stop = eobool_true;
2597 
2598  return res->setRemoteValue(protid, &stop);
2599 }
2600 
2602 {
2603  bool ret = true;
2604  for(int j=0; j< _njoints; j++)
2605  {
2606  ret &= stopRaw(j);
2607  }
2608  return ret;
2609 }
2611 
2613 // Position control2 interface //
2615 
2616 bool embObjMotionControl::positionMoveRaw(const int n_joint, const int *joints, const double *refs)
2617 {
2618  bool ret = true;
2619  for(int j=0; j<n_joint; j++)
2620  {
2621  ret = ret &&positionMoveRaw(joints[j], refs[j]);
2622  }
2623  return ret;
2624 }
2625 
2626 bool embObjMotionControl::relativeMoveRaw(const int n_joint, const int *joints, const double *deltas)
2627 {
2628  bool ret = true;
2629  for(int j=0; j<n_joint; j++)
2630  {
2631  ret = ret &&relativeMoveRaw(joints[j], deltas[j]);
2632  }
2633  return ret;
2634 }
2635 
2636 bool embObjMotionControl::checkMotionDoneRaw(const int n_joint, const int *joints, bool *flag)
2637 {
2638 
2639  //1) first of all, check if all joints number are ok
2640  for(int j=0; j<n_joint; j++)
2641  {
2642  if(joints[j] >= _njoints)
2643  {
2644  yError() << getBoardInfo() << ":checkMotionDoneRaw required for not existing joint ( " << joints[j] << ")";
2645  return false;
2646  }
2647  }
2648 
2649  //2) ask check motion done for all my joints
2650  std::vector <eObool_t> ismotiondoneList(_njoints);
2651  bool ret = askRemoteValues(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, eoprot_tag_mc_joint_status_core_modes_ismotiondone, ismotiondoneList);
2652  if(false == ret)
2653  {
2654  yError () << getBoardInfo() << "Failure of askRemoteValues() inside embObjMotionControl::checkMotionDoneRaw for a group of joint"; getBoardInfo();
2655  return false;
2656  }
2657 
2658  //3) verify only the given joints
2659  bool tot_val = true;
2660  for(int j=0; j<n_joint; j++)
2661  {
2662  tot_val &= ismotiondoneList[joints[j]];
2663  }
2664 
2665  *flag = tot_val;
2666  return true;
2667 
2668 }
2669 
2670 bool embObjMotionControl::setRefSpeedsRaw(const int n_joint, const int *joints, const double *spds)
2671 {
2672  bool ret = true;
2673  for(int j=0; j<n_joint; j++)
2674  {
2675  ret = ret &&setRefSpeedRaw(joints[j], spds[j]);
2676  }
2677  return ret;
2678 }
2679 
2680 bool embObjMotionControl::setRefAccelerationsRaw(const int n_joint, const int *joints, const double *accs)
2681 {
2682  bool ret = true;
2683  for(int j=0; j<n_joint; j++)
2684  {
2685  ret = ret &&setRefAccelerationRaw(joints[j], accs[j]);
2686  }
2687  return ret;
2688 }
2689 
2690 bool embObjMotionControl::getRefSpeedsRaw(const int n_joint, const int *joints, double *spds)
2691 {
2692  bool ret = true;
2693  for(int j=0; j<n_joint; j++)
2694  {
2695  ret = ret && getRefSpeedRaw(joints[j], &spds[j]);
2696  }
2697  return ret;
2698 }
2699 
2700 bool embObjMotionControl::getRefAccelerationsRaw(const int n_joint, const int *joints, double *accs)
2701 {
2702  bool ret = true;
2703  for(int j=0; j<n_joint; j++)
2704  {
2705  ret = ret && getRefAccelerationRaw(joints[j], &accs[j]);
2706  }
2707  return ret;
2708 }
2709 
2710 bool embObjMotionControl::stopRaw(const int n_joint, const int *joints)
2711 {
2712  bool ret = true;
2713  for(int j=0; j<n_joint; j++)
2714  {
2715  ret = ret &&stopRaw(joints[j]);
2716  }
2717  return ret;
2718 }
2719 
2721 
2722 // ControlMode
2723 
2725 {
2726  eOmc_joint_status_core_t jcore = {0};
2727  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_core);
2728  if(! res->getLocalValue(protid, &jcore))
2729  return false;
2730 
2731  eOmc_controlmode_t type = (eOmc_controlmode_t) jcore.modes.controlmodestatus;
2732 
2734  return true;
2735 }
2736 
2737 // IControl Mode 2
2739 {
2740  bool ret = true;
2741  for(int j=0; j< _njoints; j++)
2742  {
2743  ret = ret && getControlModeRaw(j, &v[j]);
2744  }
2745  return ret;
2746 }
2747 
2748 bool embObjMotionControl::getControlModesRaw(const int n_joint, const int *joints, int *modes)
2749 {
2750  bool ret = true;
2751  for(int j=0; j< n_joint; j++)
2752  {
2753  ret = ret && getControlModeRaw(joints[j], &modes[j]);
2754  }
2755  return ret;
2756 }
2757 
2758 
2759 
2760 // marco.accame: con alberto cardellino abbiamo parlato della correttezza di effettuare la verifica di quanto imposto (in setControlModeRaw() ed affini)
2761 // andando a rileggere il valore nella scheda eth fino a che esso non sia quello atteso. si deve fare oppure no?
2762 // con il control mode il can ora lo fa ma e' giusto? era cosi' anche in passato?
2763 bool embObjMotionControl::setControlModeRaw(const int j, const int _mode)
2764 {
2765  bool ret = true;
2766  eOenum08_t controlmodecommand = 0;
2767 
2768  if((_mode == VOCAB_CM_TORQUE) && (_trq_pids[j].enabled == false))
2769  {
2770  yError()<<"Torque control is disabled. Check your configuration parameters";
2771  return false;
2772  }
2773 
2774  if(!controlModeCommandConvert_yarp2embObj(_mode, controlmodecommand) )
2775  {
2776  yError() << "SetControlMode: received unknown control mode for " << getBoardInfo() << " joint " << j << " mode " << Vocab32::decode(_mode);
2777  return false;
2778  }
2779 
2780  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_controlmode);
2781  if(false == res->setRemoteValue(protid, &controlmodecommand) )
2782  {
2783  yError() << "setControlModeRaw failed for " << getBoardInfo() << " joint " << j << " mode " << Vocab32::decode(_mode);
2784  return false;
2785  }
2786 
2787 
2788  ret = checkRemoteControlModeStatus(j, _mode);
2789 
2790  if(false == ret)
2791  {
2792  yError() << "In embObjMotionControl::setControlModeRaw(j=" << j << ", mode=" << yarp::os::Vocab32::decode(_mode).c_str() << ") for " << getBoardInfo() << " has failed checkRemoteControlModeStatus()";
2793  }
2794 
2795  return ret;
2796 }
2797 
2798 
2799 bool embObjMotionControl::setControlModesRaw(const int n_joint, const int *joints, int *modes)
2800 {
2801  bool ret = true;
2802  eOenum08_t controlmodecommand = 0;
2803 
2804 
2805  for(int i=0; i<n_joint; i++)
2806  {
2807  if ((modes[i] == VOCAB_CM_TORQUE) && (_trq_pids[i].enabled == false)) {yError()<<"Torque control is disabled. Check your configuration parameters"; continue;}
2808 
2809  if(!controlModeCommandConvert_yarp2embObj(modes[i], controlmodecommand) )
2810  {
2811  yError() << "SetControlModesRaw(): received unknown control mode for " << getBoardInfo() << " joint " << joints[i] << " mode " << Vocab32::decode(modes[i]);
2812 
2813  return false;
2814  }
2815 
2816  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, joints[i], eoprot_tag_mc_joint_cmmnds_controlmode);
2817  if(false == res->setRemoteValue(protid, &controlmodecommand) )
2818  {
2819  yError() << "setControlModesRaw() could not send set<cmmnds_controlmode> for " << getBoardInfo() << " joint " << joints[i] << " mode " << Vocab32::decode(modes[i]);
2820 
2821  return false;
2822  }
2823 
2824  bool tmpresult = checkRemoteControlModeStatus(joints[i], modes[i]);
2825  if(false == tmpresult)
2826  {
2827  yError() << "setControlModesRaw(const int n_joint, const int *joints, int *modes) could not check with checkRemoteControlModeStatus() for " << getBoardInfo() << " joint " << joints[i] << " mode " << Vocab32::decode(modes[i]);
2828  }
2829 
2830  ret = ret && tmpresult;
2831 
2832  }
2833 
2834  return ret;
2835 }
2836 
2838 {
2839  bool ret = true;
2840  eOenum08_t controlmodecommand = 0;
2841 
2842  for(int i=0; i<_njoints; i++)
2843  {
2844 
2845  if ((modes[i] == VOCAB_CM_TORQUE) && (_trq_pids[i].enabled == false))
2846  {
2847  yError()<<"Torque control is disabled. Check your configuration parameters";
2848  continue;
2849  }
2850 
2851  if(!controlModeCommandConvert_yarp2embObj(modes[i], controlmodecommand) )
2852  {
2853  yError() << "SetControlMode: received unknown control mode for" << getBoardInfo() << " joint " << i << " mode " << Vocab32::decode(modes[i]);
2854  return false;
2855  }
2856 
2857  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, i, eoprot_tag_mc_joint_cmmnds_controlmode);
2858  if(false == res->setRemoteValue(protid, &controlmodecommand) )
2859  {
2860  yError() << "setControlModesRaw failed for " << getBoardInfo() << " joint " << i << " mode " << Vocab32::decode(modes[i]);
2861  return false;
2862  }
2863 
2864  bool tmpresult = checkRemoteControlModeStatus(i, modes[i]);
2865  if(false == tmpresult)
2866  {
2867  yError() << "setControlModesRaw(int *modes) could not check with checkRemoteControlModeStatus() for" << getBoardInfo() << " joint " << i << " mode " << Vocab32::decode(modes[i]);
2868  }
2869 
2870  ret = ret && tmpresult;
2871 
2872  }
2873 
2874 
2875  return ret;
2876 }
2877 
2878 
2880 
2881 bool embObjMotionControl::setEncoderRaw(int j, double val)
2882 {
2883  return NOT_YET_IMPLEMENTED("setEncoder");
2884 }
2885 
2886 bool embObjMotionControl::setEncodersRaw(const double *vals)
2887 {
2888  return NOT_YET_IMPLEMENTED("setEncoders");
2889 }
2890 
2892 {
2893  return NOT_YET_IMPLEMENTED("resetEncoder");
2894 }
2895 
2897 {
2898  return NOT_YET_IMPLEMENTED("resetEncoders");
2899 }
2900 
2901 bool embObjMotionControl::getEncoderRaw(int j, double *value)
2902 {
2903  eOmc_joint_status_core_t core;
2904  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_core);
2905 
2906  bool ret = res->getLocalValue(protid, &core);
2907 
2908  if(ret)
2909  {
2910  *value = (double) core.measures.meas_position;
2911  }
2912  else
2913  {
2914  yError() << "embObjMotionControl while reading encoder";
2915  *value = 0;
2916  }
2917 
2918  return ret;
2919 }
2920 
2922 {
2923  bool ret = true;
2924  for(int j=0; j< _njoints; j++)
2925  {
2926  ret &= getEncoderRaw(j, &encs[j]);
2927 
2928  }
2929  return ret;
2930 }
2931 
2933 {
2934  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_core);
2935  eOmc_joint_status_core_t core;
2936  *sp = 0;
2937  if(!res->getLocalValue(protid, &core))
2938  {
2939  return false;
2940  }
2941  // extract requested data from status
2942  *sp = (double) core.measures.meas_velocity;
2943  return true;
2944 }
2945 
2947 {
2948  bool ret = true;
2949  for(int j=0; j< _njoints; j++)
2950  {
2951  ret &= getEncoderSpeedRaw(j, &spds[j]);
2952  }
2953  return ret;
2954 }
2955 
2957 {
2958  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_core);
2959  eOmc_joint_status_core_t core;
2960  *acc = 0;
2961  if(! res->getLocalValue(protid, &core))
2962  {
2963  return false;
2964  }
2965  *acc = (double) core.measures.meas_acceleration;
2966  return true;
2967 }
2968 
2970 {
2971  bool ret = true;
2972  for(int j=0; j< _njoints; j++)
2973  {
2974  ret &= getEncoderAccelerationRaw(j, &accs[j]);
2975  }
2976  return ret;
2977 }
2978 
2980 
2981 bool embObjMotionControl::getEncodersTimedRaw(double *encs, double *stamps)
2982 {
2983  bool ret = getEncodersRaw(encs);
2984  std::lock_guard<std::mutex> lck(_mutex);
2985  for(int i=0; i<_njoints; i++)
2986  stamps[i] = _encodersStamp[i];
2987  return ret;
2988 }
2989 
2990 bool embObjMotionControl::getEncoderTimedRaw(int j, double *encs, double *stamp)
2991 {
2992  bool ret = getEncoderRaw(j, encs);
2993  std::lock_guard<std::mutex> lck(_mutex);
2994  *stamp = _encodersStamp[j];
2995  return ret;
2996 }
2997 
2999 
3001 {
3002  *num=_njoints;
3003  return true;
3004 }
3005 
3006 bool embObjMotionControl::setMotorEncoderRaw(int m, const double val)
3007 {
3008  return NOT_YET_IMPLEMENTED("setMotorEncoder");
3009 }
3010 
3012 {
3013  return NOT_YET_IMPLEMENTED("setMotorEncoders");
3014 }
3015 
3017 {
3018  return NOT_YET_IMPLEMENTED("setMotorEncoderCountsPerRevolutionRaw");
3019 }
3020 
3022 {
3023  return NOT_YET_IMPLEMENTED("getMotorEncoderCountsPerRevolutionRaw");
3024 }
3025 
3027 {
3028  return NOT_YET_IMPLEMENTED("resetMotorEncoder");
3029 }
3030 
3032 {
3033  return NOT_YET_IMPLEMENTED("reseMotortEncoders");
3034 }
3035 
3037 {
3038  eOmc_motor_status_basic_t status;
3039  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, m, eoprot_tag_mc_motor_status_basic);
3040 
3041  bool ret = res->getLocalValue(protid, &status);
3042  if(ret)
3043  {
3044  *value = (double) status.mot_position;
3045  }
3046  else
3047  {
3048  yError() << "embObjMotionControl while reading motor encoder position";
3049  *value = 0;
3050  }
3051 
3052  return ret;
3053 }
3054 
3056 {
3057  bool ret = true;
3058  for(int j=0; j< _njoints; j++)
3059  {
3060  ret &= getMotorEncoderRaw(j, &encs[j]);
3061 
3062  }
3063  return ret;
3064 }
3065 
3067 {
3068  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, m, eoprot_tag_mc_motor_status_basic);
3069  eOmc_motor_status_basic_t tmpMotorStatus;
3070  bool ret = res->getLocalValue(protid, &tmpMotorStatus);
3071  if(ret)
3072  {
3073  *sp = (double) tmpMotorStatus.mot_velocity;
3074  }
3075  else
3076  {
3077  yError() << "embObjMotionControl while reading motor encoder speed";
3078  *sp = 0;
3079  }
3080  return true;
3081 }
3082 
3084 {
3085  bool ret = true;
3086  for(int j=0; j< _njoints; j++)
3087  {
3088  ret &= getMotorEncoderSpeedRaw(j, &spds[j]);
3089  }
3090  return ret;
3091 }
3092 
3094 {
3095  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, m, eoprot_tag_mc_motor_status_basic);
3096  eOmc_motor_status_basic_t tmpMotorStatus;
3097  bool ret = res->getLocalValue(protid, &tmpMotorStatus);
3098  if(ret)
3099  {
3100  *acc = (double) tmpMotorStatus.mot_acceleration;
3101  }
3102  else
3103  {
3104  yError() << "embObjMotionControl while reading motor encoder acceleration";
3105  *acc = 0;
3106  }
3107  return true;
3108 }
3109 
3111 {
3112  bool ret = true;
3113  for(int j=0; j< _njoints; j++)
3114  {
3115  ret &= getMotorEncoderAccelerationRaw(j, &accs[j]);
3116  }
3117  return ret;
3118 }
3119 
3121 {
3122  bool ret = getMotorEncodersRaw(encs);
3123  std::lock_guard<std::mutex> lck(_mutex);
3124  for(int i=0; i<_njoints; i++)
3125  stamps[i] = _encodersStamp[i];
3126  return ret;
3127 }
3128 
3129 bool embObjMotionControl::getMotorEncoderTimedRaw(int m, double *encs, double *stamp)
3130 {
3131  bool ret = getMotorEncoderRaw(m, encs);
3132  std::lock_guard<std::mutex> lck(_mutex);
3133  *stamp = _encodersStamp[m];
3134  return ret;
3135 }
3137 
3139 
3141 {
3142  return DEPRECATED("enableAmpRaw");
3143 }
3144 
3146 {
3147  return DEPRECATED("disableAmpRaw");
3148 }
3149 
3150 bool embObjMotionControl::getCurrentRaw(int j, double *value)
3151 {
3152  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_status_basic);
3153  eOmc_motor_status_basic_t tmpMotorStatus;
3154  bool ret = res->getLocalValue(protid, &tmpMotorStatus);
3155 
3156  *value = (double) tmpMotorStatus.mot_current;
3157  return true;
3158 }
3159 
3161 {
3162  bool ret = true;
3163  for(int j=0; j< _njoints; j++)
3164  {
3165  ret &= getCurrentRaw(j, &vals[j]);
3166  }
3167  return ret;
3168 }
3169 
3171 {
3172  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config_currentlimits);
3173  uint16_t size;
3174  eOmc_current_limits_params_t currentlimits = {0};
3175 
3176  if(!askRemoteValue(protid, &currentlimits, size))
3177  {
3178  yError() << "embObjMotionControl::setMaxCurrentRaw() could not read max current for " << getBoardInfo() << "joint " << j;
3179  return false;
3180  }
3181 
3182  //set current overload
3183  currentlimits.overloadCurrent = (eOmeas_current_t) S_16(val);
3184 
3185  //send new values
3186  return res->setRemoteValue(protid, &currentlimits);
3187 }
3188 
3190 {
3191  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config_currentlimits);
3192  uint16_t size;
3193  eOmc_current_limits_params_t currentlimits = {0};
3194  *val = 0;
3195 
3196  if(!askRemoteValue(protid, &currentlimits, size))
3197  {
3198  yError() << "embObjMotionControl::getMaxCurrentRaw() could not read max current for " << getBoardInfo() << "joint " << j;
3199  return false;
3200  }
3201 
3202  *val = (double) currentlimits.overloadCurrent;
3203 
3204  return true;
3205 }
3206 
3208 {
3209  //VALE: can i set this func like deprecated? none sets _enabledAmp!!
3210  (_enabledAmp[j ]) ? *st = 1 : *st = 0;
3211  return true;
3212 }
3213 
3215 {
3216  bool ret = true;
3217  for(int j=0; j<_njoints; j++)
3218  {
3219  sts[j] = _enabledAmp[j];
3220  }
3221 
3222  return ret;
3223 }
3224 
3225 #ifdef IMPLEMENT_DEBUG_INTERFACE
3226 //----------------------------------------------\\
3227 // Debug interface
3228 //----------------------------------------------\\
3229 
3230 bool embObjMotionControl::setParameterRaw(int j, unsigned int type, double value) { return NOT_YET_IMPLEMENTED("setParameterRaw"); }
3231 bool embObjMotionControl::getParameterRaw(int j, unsigned int type, double* value) { return NOT_YET_IMPLEMENTED("getParameterRaw"); }
3232 bool embObjMotionControl::getDebugParameterRaw(int j, unsigned int index, double* value) { return NOT_YET_IMPLEMENTED("getDebugParameterRaw"); }
3233 bool embObjMotionControl::setDebugParameterRaw(int j, unsigned int index, double value) { return NOT_YET_IMPLEMENTED("setDebugParameterRaw"); }
3234 bool embObjMotionControl::setDebugReferencePositionRaw(int j, double value) { return NOT_YET_IMPLEMENTED("setDebugReferencePositionRaw"); }
3235 bool embObjMotionControl::getDebugReferencePositionRaw(int j, double* value) { return NOT_YET_IMPLEMENTED("getDebugReferencePositionRaw");}
3236 
3237 #endif //IMPLEMENT_DEBUG_INTERFACE
3238 
3239 // Limit interface
3240 bool embObjMotionControl::setLimitsRaw(int j, double min, double max)
3241 {
3242  bool ret = true;
3243  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_userlimits);
3244 
3245  eOmeas_position_limits_t limits;
3246  limits.max = (eOmeas_position_t) S_32(max);
3247  limits.min = (eOmeas_position_t) S_32(min);
3248 
3249  ret = res->setRemoteValue(protid, &limits);
3250 
3251 
3252  if(!ret)
3253  {
3254  yError() << "while setting position limits for joint" << j << " \n";
3255  }
3256  return ret;
3257 }
3258 
3259 bool embObjMotionControl::getLimitsRaw(int j, double *min, double *max)
3260 {
3261  eOmeas_position_limits_t limits;
3262  eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_userlimits);
3263  uint16_t size;
3264 
3265  if(! askRemoteValue(protoid, &limits, size))
3266  return false;
3267 
3268  *min = (double)limits.min + SAFETY_THRESHOLD;
3269  *max = (double)limits.max - SAFETY_THRESHOLD;
3270  return true;
3271 }
3272 
3273 bool embObjMotionControl::getGearboxRatioRaw(int j, double *gearbox)
3274 {
3275  eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config);
3276  uint16_t size;
3277  eOmc_motor_config_t motor_cfg;
3278  if(! askRemoteValue(protoid, &motor_cfg, size))
3279  return false;
3280 
3281  // refresh cached value when reading data from the EMS
3282  *gearbox = (double)motor_cfg.gearbox_M2J;
3283 
3284  return true;
3285 }
3286 
3287 bool embObjMotionControl::getRotorLimitsRaw(int j, double *rotorMin, double *rotorMax)
3288 {
3289  eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config);
3290  uint16_t size;
3291  eOmc_motor_config_t motor_cfg;
3292  if(! askRemoteValue(protoid, &motor_cfg, size))
3293  return false;
3294  *rotorMax = (double)( motor_cfg.limitsofrotor.max);
3295  *rotorMin = (double)( motor_cfg.limitsofrotor.min);
3296  return true;
3297 }
3298 
3300 {
3301  eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config);
3302  uint16_t size;
3303  eOmc_joint_config_t joint_cfg;
3304  if(! askRemoteValue(protoid, &joint_cfg, size))
3305  return false;
3306 
3307  // refresh cached value when reading data from the EMS
3308  type = (int)joint_cfg.tcfiltertype;
3309  return true;
3310 }
3311 
3313 {
3314  eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config);
3315  uint16_t size;
3316  eOmc_motor_config_t motor_cfg;
3317  if(! askRemoteValue(protoid, &motor_cfg, size))
3318  return false;
3319 
3320  // refresh cached value when reading data from the EMS
3321  rotres = (double)motor_cfg.rotorEncoderResolution;
3322 
3323  return true;
3324 }
3325 
3327 {
3328  eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config);
3329  uint16_t size;
3330  eOmc_joint_config_t joint_cfg;
3331  if(! askRemoteValue(protoid, &joint_cfg, size))
3332  return false;
3333 
3334  // refresh cached value when reading data from the EMS
3335  jntres = (double)joint_cfg.jntEncoderResolution;
3336 
3337  return true;
3338 }
3339 
3341 {
3342  eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config);
3343  uint16_t size;
3344  eOmc_joint_config_t joint_cfg;
3345  if(! askRemoteValue(protoid, &joint_cfg, size))
3346  return false;
3347 
3348  // refresh cached value when reading data from the EMS
3349  type = (int)joint_cfg.jntEncoderType;
3350 
3351  return true;
3352 }
3353 
3355 {
3356  eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config);
3357  uint16_t size;
3358  eOmc_motor_config_t motor_cfg;
3359  if(! askRemoteValue(protoid, &motor_cfg, size))
3360  return false;
3361 
3362  // refresh cached value when reading data from the EMS
3363  type = (int)motor_cfg.rotorEncoderType;
3364 
3365  return true;
3366 }
3367 
3368 bool embObjMotionControl::getKinematicMJRaw(int j, double &rotres)
3369 {
3370  yError("getKinematicMJRaw not yet implemented");
3371  return false;
3372 }
3373 
3375 {
3376  // refresh cached value when reading data from the EMS
3377  ret = "NONE";
3378  if (_temperatureSensorsVector.at(j)->getType() == motor_temperature_sensor_pt100)
3379  {
3380  ret = "PT100";
3381  }
3382  else if (_temperatureSensorsVector.at(j)->getType() == motor_temperature_sensor_pt1000)
3383  {
3384  ret = "PT1000";
3385  }
3386  else
3387  {
3388  ret = "NONE";
3389  }
3390 
3391  return true;
3392 }
3393 
3395 {
3396  eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config);
3397  uint16_t size;
3398  eOmc_motor_config_t motor_cfg;
3399  if(! askRemoteValue(protoid, &motor_cfg, size))
3400  return false;
3401 
3402  // refresh cached value when reading data from the EMS
3403  ret = (int)motor_cfg.hasTempSensor;
3404 
3405  return true;
3406 }
3407 
3409 {
3410  eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config);
3411  uint16_t size;
3412  eOmc_motor_config_t motor_cfg;
3413  if(! askRemoteValue(protoid, &motor_cfg, size))
3414  return false;
3415 
3416  // refresh cached value when reading data from the EMS
3417  ret = (int)motor_cfg.hasHallSensor;
3418 
3419  return true;
3420 }
3421 
3423 {
3424  eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config);
3425  uint16_t size;
3426  eOmc_motor_config_t motor_cfg;
3427  if(! askRemoteValue(protoid, &motor_cfg, size))
3428  return false;
3429 
3430  // refresh cached value when reading data from the EMS
3431  ret = (int)motor_cfg.hasRotorEncoder;
3432 
3433  return true;
3434 }
3435 
3437 {
3438  eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config);
3439  uint16_t size;
3440  eOmc_motor_config_t motor_cfg;
3441  if(! askRemoteValue(protoid, &motor_cfg, size))
3442  return false;
3443 
3444  // refresh cached value when reading data from the EMS
3445  ret = (int)motor_cfg.hasRotorEncoderIndex;
3446 
3447  return true;
3448 }
3449 
3451 {
3452  eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config);
3453 
3454  uint16_t size;
3455  eOmc_motor_config_t motor_cfg;
3456  if(! askRemoteValue(protoid, &motor_cfg, size))
3457  return false;
3458 
3459  // refresh cached value when reading data from the EMS
3460  poles = (int)motor_cfg.motorPoles;
3461 
3462  return true;
3463 }
3464 
3465 bool embObjMotionControl::getRotorIndexOffsetRaw(int j, double& rotorOffset)
3466 {
3467  eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config);
3468  uint16_t size;
3469  eOmc_motor_config_t motor_cfg;
3470  if(! askRemoteValue(protoid, &motor_cfg, size))
3471  return false;
3472 
3473  // refresh cached value when reading data from the EMS
3474  rotorOffset = (double)motor_cfg.rotorIndexOffset;
3475 
3476  return true;
3477 }
3478 
3479 bool embObjMotionControl::getAxisNameRaw(int axis, std::string& name)
3480 {
3481  if (axis >= 0 && axis < _njoints)
3482  {
3483  name = _axesInfo[axis].name;
3484  return true;
3485  }
3486  else
3487  {
3488  name = "ERROR";
3489  return false;
3490  }
3491 }
3492 
3493 bool embObjMotionControl::getJointTypeRaw(int axis, yarp::dev::JointTypeEnum& type)
3494 {
3495  if (axis >= 0 && axis < _njoints)
3496  {
3497  type = _axesInfo[axis].type;
3498  return true;
3499  }
3500  else
3501  {
3502  return false;
3503  }
3504 }
3505 
3506 bool embObjMotionControl::getJointDeadZoneRaw(int j, double &jntDeadZone)
3507 {
3508  eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config);
3509  uint16_t size;
3510  eOmc_joint_config_t joint_cfg;
3511  if(! askRemoteValue(protoid, &joint_cfg, size))
3512  return false;
3513 
3514  // refresh cached value when reading data from the EMS
3515  jntDeadZone = _measureConverter->posE2A((double)joint_cfg.deadzone, _axisMap[j]);
3516 
3517  return true;
3518 }
3519 
3520 // IRemoteVariables
3521 bool embObjMotionControl::getRemoteVariableRaw(std::string key, yarp::os::Bottle& val)
3522 {
3523  val.clear();
3524  if (key == "kinematic_mj")
3525  {
3526  // Return the reduced kinematic_mj matrix considering only the joints actually exposed to the user
3527  Bottle& ret = val.addList();
3528 
3529  eOmn_serv_type_t mc_serv_type = (eOmn_serv_type_t)serviceConfig.ethservice.configuration.type;
3530  if(iNeedCouplingsInfo())
3531  {
3532  for (int r=0; r<_njoints; r++)
3533  {
3534  for (int c = 0; c < _njoints; c++)
3535  {
3536  // matrixJ2M is stored as row major in the eomc_couplingInfo_t,
3537  // and kinematic_mj is returned as a row major serialization as well
3538  ret.addFloat64(_couplingInfo.matrixJ2M[4 * r + c]);
3539  }
3540  }
3541  }
3542  else
3543  {
3544  ret.addFloat64(0.0);
3545  }
3546  return true;
3547  }
3548  else if (key == "encoders")
3549  {
3550  Bottle& r = val.addList(); for (int i = 0; i < _njoints; i++) { r.addFloat64(_measureConverter->posA2E(1.0, i)); }
3551  return true;
3552  }
3553  else if (key == "rotorEncoderResolution")
3554  {
3555  Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { double tmp = 0; getRotorEncoderResolutionRaw(i, tmp); r.addFloat64(tmp); }
3556  return true;
3557  }
3558  else if (key == "jointEncoderResolution")
3559  {
3560  Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { double tmp = 0; getJointEncoderResolutionRaw(i, tmp); r.addFloat64(tmp); }
3561  return true;
3562  }
3563  else if (key == "gearbox_M2J")
3564  {
3565  Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { double tmp=0; getGearboxRatioRaw(i, &tmp); r.addFloat64(tmp); }
3566  return true;
3567  }
3568  else if (key == "gearbox_E2J")
3569  {
3570  Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { double tmp=0; getGerabox_E2J(i, &tmp); r.addFloat64(tmp); }
3571  return true;
3572  }
3573  else if (key == "hasHallSensor")
3574  {
3575  Bottle& r = val.addList(); for (int i = 0; i < _njoints; i++) { int tmp = 0; getHasHallSensorRaw(i, tmp); r.addInt32(tmp); }
3576  return true;
3577  }
3578  else if (key == "hasTempSensor")
3579  {
3580  Bottle& r = val.addList(); for (int i = 0; i < _njoints; i++) { int tmp = 0; getHasTempSensorsRaw(i, tmp); r.addInt32(tmp); }
3581  return true;
3582  }
3583  else if (key == "TemperatureSensorType")
3584  {
3585  Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { std::string tmp = ""; getTemperatureSensorTypeRaw(i, tmp); r.addString(tmp); }
3586  return true;
3587  }
3588  else if (key == "hasRotorEncoder")
3589  {
3590  Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { int tmp = 0; getHasRotorEncoderRaw(i, tmp); r.addInt32(tmp); }
3591  return true;
3592  }
3593  else if (key == "hasRotorEncoderIndex")
3594  {
3595  Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { int tmp = 0; getHasRotorEncoderIndexRaw(i, tmp); r.addInt32(tmp); }
3596  return true;
3597  }
3598  else if (key == "rotorIndexOffset")
3599  {
3600  Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { double tmp = 0; getRotorIndexOffsetRaw(i, tmp); r.addFloat64(tmp); }
3601  return true;
3602  }
3603  else if (key == "motorPoles")
3604  {
3605  Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { int tmp = 0; getMotorPolesRaw(i, tmp); r.addInt32(tmp); }
3606  return true;
3607  }
3608  else if (key == "pidCurrentKp")
3609  {
3610  Bottle& r = val.addList(); for (int i = 0; i < _njoints; i++) { Pid p; getPidRaw(PidControlTypeEnum::VOCAB_PIDTYPE_CURRENT, i, &p); r.addFloat64(p.kp); }
3611  return true;
3612  }
3613  else if (key == "pidCurrentKi")
3614  {
3615  Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { Pid p; getPidRaw(PidControlTypeEnum::VOCAB_PIDTYPE_CURRENT, i, &p); r.addFloat64(p.ki); }
3616  return true;
3617  }
3618  else if (key == "pidCurrentShift")
3619  {
3620  Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { Pid p; getPidRaw(PidControlTypeEnum::VOCAB_PIDTYPE_CURRENT, i, &p); r.addFloat64(p.scale); }
3621  return true;
3622  }
3623  else if (key == "pidCurrentOutput")
3624  {
3625  Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { Pid p; getPidRaw(PidControlTypeEnum::VOCAB_PIDTYPE_CURRENT, i, &p); r.addFloat64(p.max_output); }
3626  return true;
3627  }
3628  else if (key == "jointEncoderType")
3629  {
3630  Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++)
3631  {
3632  int t; string s;
3633  getJointEncoderTypeRaw(i, t); uint8_t tt = t; bool b = EncoderType_eo2iCub(&tt, &s);
3634  if (b == false)
3635  {
3636  yError("Invalid jointEncoderType");
3637  }
3638  r.addString(s);
3639  }
3640  return true;
3641  }
3642  else if (key == "rotorEncoderType")
3643  {
3644  Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++)
3645  {
3646  int t; string s;
3647  getRotorEncoderTypeRaw(i, t); uint8_t tt = t; bool b = EncoderType_eo2iCub(&tt, &s);
3648  if (b == false)
3649  {
3650  yError("Invalid motorEncoderType");
3651  }
3652  r.addString(s);
3653  }
3654  return true;
3655  }
3656  else if (key == "coulombThreshold")
3657  {
3658  val.addString("not implemented yet");
3659  return true;
3660  }
3661  else if (key == "torqueControlFilterType")
3662  {
3663  Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { int t; getTorqueControlFilterType(i, t); r.addFloat64(t); }
3664  return true;
3665  }
3666  else if (key == "torqueControlEnabled")
3667  {
3668 
3669  Bottle& r = val.addList();
3670  for(int i = 0; i<_njoints; i++)
3671  {
3672  r.addInt32((int)_trq_pids[i].enabled );
3673  }
3674  return true;
3675  }
3676  else if (key == "PWMLimit")
3677  {
3678  Bottle& r = val.addList(); for (int i = 0; i< _njoints; i++) { double tmp = 0; getPWMLimitRaw(i, &tmp); r.addFloat64(tmp); }
3679  return true;
3680  }
3681  else if (key == "motOverloadCurr")
3682  {
3683  Bottle& r = val.addList(); for (int i = 0; i< _njoints; i++) { double tmp = 0; getMaxCurrentRaw(i, &tmp); r.addFloat64(tmp); }
3684  return true;
3685  }
3686  else if (key == "motNominalCurr")
3687  {
3688  Bottle& r = val.addList(); for (int i = 0; i< _njoints; i++) { double tmp = 0; getNominalCurrentRaw(i, &tmp); r.addFloat64(tmp); }
3689  return true;
3690  }
3691  else if (key == "motPeakCurr")
3692  {
3693  Bottle& r = val.addList(); for (int i = 0; i< _njoints; i++) { double tmp = 0; getPeakCurrentRaw(i, &tmp); r.addFloat64(tmp); }
3694  return true;
3695  }
3696  else if (key == "PowerSuppVoltage")
3697  {
3698  Bottle& r = val.addList(); for (int i = 0; i< _njoints; i++) { double tmp = 0; getPowerSupplyVoltageRaw(i, &tmp); r.addFloat64(tmp); }
3699  return true;
3700  }
3701  else if (key == "rotorMax")
3702  {
3703  double tmp1, tmp2;
3704  Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { double tmp = 0; getRotorLimitsRaw(i, &tmp1, &tmp2); r.addFloat64(tmp2); }
3705  return true;
3706  }
3707  else if (key == "rotorMin")
3708  {
3709  double tmp1, tmp2;
3710  Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { double tmp = 0; getRotorLimitsRaw(i, &tmp1, &tmp2); r.addFloat64(tmp1); }
3711  return true;
3712  }
3713  else if (key == "jointMax")
3714  {
3715  double tmp1, tmp2;
3716  Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { double tmp = 0; getLimitsRaw(i, &tmp1, &tmp2); r.addFloat64(tmp2); }
3717  return true;
3718  }
3719  else if (key == "jointMin")
3720  {
3721  double tmp1, tmp2;
3722  Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { double tmp = 0; getLimitsRaw(i, &tmp1, &tmp2); r.addFloat64(tmp1); }
3723  return true;
3724  }
3725  else if (key == "jointEncTolerance")
3726  {
3727  double tmp1;
3728  Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { double tmp = 0; getJointEncTolerance(i, &tmp1); r.addFloat64(tmp1); }
3729  return true;
3730  }
3731  else if (key == "motorEncTolerance")
3732  {
3733  double tmp1;
3734  Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { double tmp = 0; getMotorEncTolerance(i, &tmp1); r.addFloat64(tmp1); }
3735  return true;
3736  }
3737  else if (key == "jointDeadZone")
3738  {
3739  double tmp1;
3740  Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { double tmp = 0; getJointDeadZoneRaw(i, tmp1); r.addFloat64(tmp1); }
3741  return true;
3742  }
3743  else if (key == "readonly_position_PIDraw")
3744  {
3745  Bottle& r = val.addList();
3746  for (int i = 0; i < _njoints; i++)
3747  { Pid p;
3748  getPidRaw(PidControlTypeEnum::VOCAB_PIDTYPE_POSITION, i, &p);
3749  char buff[1000];
3750  snprintf(buff, 1000, "J %d : kp %+3.3f ki %+3.3f kd %+3.3f maxint %+3.3f maxout %+3.3f off %+3.3f scale %+3.3f up %+3.3f dwn %+3.3f kff %+3.3f", i, p.kp, p.ki, p.kd, p.max_int, p.max_output, p.offset, p.scale, p.stiction_up_val, p.stiction_down_val, p.kff);
3751  r.addString(buff);
3752  }
3753  return true;
3754  }
3755  else if (key == "readonly_velocity_PIDraw")
3756  {
3757  Bottle& r = val.addList();
3758  for (int i = 0; i < _njoints; i++)
3759  { Pid p; getPidRaw(PidControlTypeEnum::VOCAB_PIDTYPE_VELOCITY, i, &p);
3760  char buff[1000];
3761  snprintf(buff, 1000, "J %d : kp %+3.3f ki %+3.3f kd %+3.3f maxint %+3.3f maxout %+3.3f off %+3.3f scale %+3.3f up %+3.3f dwn %+3.3f kff %+3.3f", i, p.kp, p.ki, p.kd, p.max_int, p.max_output, p.offset, p.scale, p.stiction_up_val, p.stiction_down_val, p.kff);
3762  r.addString(buff);
3763  }
3764  return true;
3765  }
3766  else if (key == "readonly_torque_PIDraw")
3767  {
3768  Bottle& r = val.addList();
3769  for (int i = 0; i < _njoints; i++)
3770  { Pid p; getPidRaw(PidControlTypeEnum::VOCAB_PIDTYPE_TORQUE, i, &p);
3771  char buff[1000];
3772  snprintf(buff, 1000, "J %d : kp %+3.3f ki %+3.3f kd %+3.3f maxint %+3.3f maxout %+3.3f off %+3.3f scale %+3.3f up %+3.3f dwn %+3.3f kff %+3.3f", i, p.kp, p.ki, p.kd, p.max_int, p.max_output, p.offset, p.scale, p.stiction_up_val, p.stiction_down_val, p.kff);
3773  r.addString(buff);
3774  }
3775  return true;
3776  }
3777  else if (key == "readonly_current_PIDraw")
3778  {
3779  Bottle& r = val.addList();
3780  for (int i = 0; i < _njoints; i++)
3781  { Pid p; getPidRaw(PidControlTypeEnum::VOCAB_PIDTYPE_CURRENT, i, &p);
3782  char buff[1000];
3783  snprintf(buff, 1000, "J %d : kp %+3.3f ki %+3.3f kd %+3.3f maxint %+3.3f maxout %+3.3f off %+3.3f scale %+3.3f up %+3.3f dwn %+3.3f kff %+3.3f", i, p.kp, p.ki, p.kd, p.max_int, p.max_output, p.offset, p.scale, p.stiction_up_val, p.stiction_down_val, p.kff);
3784  r.addString(buff);
3785  }
3786  return true;
3787  }
3788  else if (key == "readonly_llspeed_PIDraw")
3789  {
3790  Bottle& r = val.addList();
3791  for (int i = 0; i < _njoints; i++)
3792  {
3793  Pid p; getPidRaw(PidControlTypeEnum::VOCAB_PIDTYPE_VELOCITY, i, &p);
3794  char buff[1000];
3795  snprintf(buff, 1000, "J %d : kp %+3.3f ki %+3.3f kd %+3.3f maxint %+3.3f maxout %+3.3f off %+3.3f scale %+3.3f up %+3.3f dwn %+3.3f kff %+3.3f", i, p.kp, p.ki, p.kd, p.max_int, p.max_output, p.offset, p.scale, p.stiction_up_val, p.stiction_down_val, p.kff);
3796  r.addString(buff);
3797  }
3798  return true;
3799  }
3800  else if (key == "readonly_motor_torque_params_raw")
3801  {
3802  Bottle& r = val.addList();
3803  for (int i = 0; i < _njoints; i++)
3804  {
3805  MotorTorqueParameters params;
3806  getMotorTorqueParamsRaw(i, &params);
3807  char buff[1000];
3808  snprintf(buff, 1000, "J %d : bemf %+3.3f bemf_scale %+3.3f ktau %+3.3f ktau_scale %+3.3f viscousPos %+3.3f viscousNeg %+3.3f coulombPos %+3.3f coulombNeg %+3.3f velocityThres %+3.3f", i, params.bemf, params.bemf_scale, params.ktau, params.ktau_scale, params.viscousPos, params.viscousNeg, params.coulombPos, params.coulombNeg, params.velocityThres);
3809  r.addString(buff);
3810  }
3811  return true;
3812  }
3813  yWarning("getRemoteVariable(): Unknown variable %s", key.c_str());
3814  return false;
3815 }
3816 
3817 bool embObjMotionControl::setRemoteVariableRaw(std::string key, const yarp::os::Bottle& val)
3818 {
3819  string s1 = val.toString();
3820  if (val.size() != _njoints)
3821  {
3822  yWarning("setRemoteVariable(): Protocol error %s", s1.c_str());
3823  return false;
3824  }
3825 
3826  if (key == "kinematic_mj")
3827  {
3828  yWarning("setRemoteVariable(): Impossible to set kinematic_mj parameter at runtime.");
3829  return false;
3830  }
3831 // else if (key == "rotor")
3832 // {
3833 // for (int i = 0; i < _njoints; i++) _rotorEncoderRes[i] = val.get(i).asInt32();//this operation has none effect on motor controlelr, so i remove it
3834 // return true;
3835 // }
3836 // else if (key == "gearbox_M2J")
3837 // {
3838 // for (int i = 0; i < _njoints; i++) _gearbox_M2J[i] = val.get(i).asFloat64();//this operation has none effect on motor controlelr, so i remove it
3839 // return true;
3840 // }
3841  else if (key == "PWMLimit")
3842  {
3843  for (int i = 0; i < _njoints; i++) setPWMLimitRaw(i, val.get(i).asFloat64());
3844  return true;
3845  }
3846  //disabled for used safety
3847 #if 0
3848  else if (key == "jointMax")
3849  {
3850  double min, max;
3851  for (int i = 0; i < _njoints; i++)
3852  {
3853  getLimitsRaw(i, &min, &max);
3854  setLimitsRaw(i, min, val.get(i).asFloat64());
3855  }
3856  return true;
3857  }
3858  else if (key == "jointMin")
3859  {
3860  double min, max;
3861  for (int i = 0; i < _njoints; i++)
3862  {
3863  getLimitsRaw(i, &min, &max);
3864  setLimitsRaw(i, val.get(i).asFloat64(), max);
3865  }
3866  }
3867 #endif
3868  yWarning("setRemoteVariable(): Unknown variable %s", key.c_str());
3869  return false;
3870 }
3871 
3872 bool embObjMotionControl::getRemoteVariablesListRaw(yarp::os::Bottle* listOfKeys)
3873 {
3874  listOfKeys->clear();
3875  listOfKeys->addString("kinematic_mj");
3876  listOfKeys->addString("encoders");
3877  listOfKeys->addString("gearbox_M2J");
3878  listOfKeys->addString("gearbox_E2J");
3879  listOfKeys->addString("hasHallSensor");
3880  listOfKeys->addString("hasTempSensor");
3881  listOfKeys->addString("TemperatureSensorType");
3882  listOfKeys->addString("hasRotorEncoder");
3883  listOfKeys->addString("hasRotorEncoderIndex");
3884  listOfKeys->addString("rotorIndexOffset");
3885  listOfKeys->addString("rotorEncoderResolution");
3886  listOfKeys->addString("jointEncoderResolution");
3887  listOfKeys->addString("motorPoles");
3888  listOfKeys->addString("pidCurrentKp");
3889  listOfKeys->addString("pidCurrentKi");
3890  listOfKeys->addString("pidCurrentShift");
3891  listOfKeys->addString("pidCurrentOutput");
3892  listOfKeys->addString("coulombThreshold");
3893  listOfKeys->addString("torqueControlFilterType");
3894  listOfKeys->addString("jointEncoderType");
3895  listOfKeys->addString("rotorEncoderType");
3896  listOfKeys->addString("PWMLimit");
3897  listOfKeys->addString("motOverloadCurr");
3898  listOfKeys->addString("motNominalCurr");
3899  listOfKeys->addString("motPeakCurr");
3900  listOfKeys->addString("PowerSuppVoltage");
3901  listOfKeys->addString("rotorMax");
3902  listOfKeys->addString("rotorMin");
3903  listOfKeys->addString("jointMax");
3904  listOfKeys->addString("jointMin");
3905  listOfKeys->addString("jointEncTolerance");
3906  listOfKeys->addString("motorEncTolerance");
3907  listOfKeys->addString("jointDeadZone");
3908  listOfKeys->addString("readonly_position_PIDraw");
3909  listOfKeys->addString("readonly_velocity_PIDraw");
3910  listOfKeys->addString("readonly_current_PIDraw");
3911  listOfKeys->addString("readonly_torque_PIDraw");
3912  listOfKeys->addString("readonly_motor_torque_params_raw");
3913  return true;
3914 }
3915 
3916 // IControlLimits2
3917 bool embObjMotionControl::setVelLimitsRaw(int axis, double min, double max)
3918 {
3919  return NOT_YET_IMPLEMENTED("setVelLimitsRaw");
3920 }
3921 
3922 bool embObjMotionControl::getVelLimitsRaw(int axis, double *min, double *max)
3923 {
3924  eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, axis, eoprot_tag_mc_joint_config);
3925  uint16_t size;
3926  eOmc_joint_config_t joint_cfg;
3927  if(! askRemoteValue(protoid, &joint_cfg, size))
3928  return false;
3929 
3930  *max = joint_cfg.maxvelocityofjoint;
3931  *min = 0;
3932 
3933  return true;
3934 }
3935 
3936 
3937 /*
3938  * IVirtualAnalogSensor Interface
3939  *
3940  * DEPRECATED!! WILL BE REMOVED IN THE NEAR FUTURE!!
3941  *
3942  */
3943 
3945 {
3946  return VAS_status::VAS_OK;
3947 };
3948 
3950 {
3951  return _njoints;
3952 };
3953 
3955 {
3956  bool ret = true;
3957 
3958  for(int j=0; j< _njoints; j++)
3959  {
3960  ret = ret && updateVirtualAnalogSensorMeasure(j, fTorques[j]);
3961  }
3962  return ret;
3963 }
3964 
3965 bool embObjMotionControl::updateVirtualAnalogSensorMeasure(int userLevel_jointNumber, double &fTorque)
3966 {
3967  int j = _axisMap[userLevel_jointNumber];
3968 
3969  eOmeas_torque_t meas_torque = 0;
3970  static double curr_time = Time::now();
3971  static int count_saturation=0;
3972 
3973  meas_torque = (eOmeas_torque_t) S_32(_measureConverter->trqN2S(fTorque, j));
3974 
3975  eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_inputs_externallymeasuredtorque);
3976 // We don't need anymore to cache locally because ems board broadcast its torque value in joint status core
3977 // // i write also locally because i want to read it back later on inside getTorqueRaw()
3978 // res->setLocalValue(protoid, &meas_torque);
3979 
3980  // and i want also to send it to the board
3981  return res->setRemoteValue(protoid, &meas_torque);
3982 }
3983 
3984 // end IVirtualAnalogSensor //
3985 
3986 
3987 // Torque control
3989 {
3990  eOmc_joint_status_core_t jstatus;
3991  eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_core);
3992  bool ret = res->getLocalValue(protoid, &jstatus);
3993  *t = (double) _measureConverter->trqS2N(jstatus.measures.meas_torque, j);
3994  return ret;
3995 }
3996 
3998 {
3999  bool ret = true;
4000  for(int j=0; j<_njoints; j++)
4001  ret = ret && getTorqueRaw(j, &t[j]);
4002  return true;
4003 }
4004 
4005 bool embObjMotionControl::getTorqueRangeRaw(int j, double *min, double *max)
4006 {
4007  return NOT_YET_IMPLEMENTED("getTorqueRangeRaw");
4008 }
4009 
4011 {
4012  return NOT_YET_IMPLEMENTED("getTorqueRangesRaw");
4013 }
4014 
4016 {
4017  bool ret = true;
4018  for(int j=0; j<_njoints && ret; j++)
4019  ret &= setRefTorqueRaw(j, t[j]);
4020  return ret;
4021 }
4022 
4024 {
4025  eOmc_setpoint_t setpoint;
4026  setpoint.type = (eOenum08_t) eomc_setpoint_torque;
4027  setpoint.to.torque.value = (eOmeas_torque_t) S_32(t);
4028 
4029  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_setpoint);
4030  return res->setRemoteValue(protid, &setpoint);
4031 }
4032 
4033 bool embObjMotionControl::setRefTorquesRaw(const int n_joint, const int *joints, const double *t)
4034 {
4035  bool ret = true;
4036  for(int j=0; j< n_joint; j++)
4037  {
4038  ret &= setRefTorqueRaw(joints[j], t[j]);
4039  }
4040  return ret;
4041 }
4042 
4044 {
4045  bool ret = true;
4046  for(int j=0; j<_njoints && ret; j++)
4047  ret &= getRefTorqueRaw(j, &t[j]);
4048  return ret;
4049 }
4050 
4052 {
4053  eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_core);
4054  eOmc_joint_status_core_t jcore = {0};
4055  *t =0 ;
4056 
4057 
4058  if(!res->getLocalValue(id32, &jcore))
4059  {
4060  yError() << "embObjMotionControl::getRefTorqueRaw() could not read pid torque reference pos for " << getBoardInfo() << "joint " << j;
4061  return false;
4062  }
4063 
4064  if ((eOmc_interactionmode_compliant == jcore.modes.interactionmodestatus) &&
4065  (eomc_controlmode_position == jcore.modes.controlmodestatus))
4066  {
4067  *t = (double) jcore.ofpid.complpos.reftrq;
4068  }
4069 
4070  if(eomc_controlmode_torque == jcore.modes.controlmodestatus)
4071  {
4072  *t = (double) jcore.ofpid.torque.reftrq;
4073  }
4074 
4075  return true;
4076 }
4077 
4078 bool embObjMotionControl::helper_setTrqPidRaw(int j, const Pid &pid)
4079 {
4080  eOmc_PID_t outPid;
4081  Pid hwPid = pid;
4082 
4083  //printf("DEBUG setTorquePidRaw: %f %f %f %f %f\n",hwPid.kp , hwPid.ki, hwPid.kd , hwPid.stiction_up_val , hwPid.stiction_down_val );
4084 
4085  copyPid_iCub2eo(&hwPid, &outPid);
4086  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_pidtorque);
4087  return res->setRemoteValue(protid, &outPid);
4088 }
4089 
4090 bool embObjMotionControl::helper_getTrqPidRaw(int j, Pid *pid)
4091 {
4092  eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_pidtorque);
4093 
4094  uint16_t size;
4095  eOmc_PID_t eoPID;
4096  if(! askRemoteValue(protoid, &eoPID, size))
4097  return false;
4098 
4099  copyPid_eo2iCub(&eoPID, pid);
4100  //printf("DEBUG getTorquePidRaw: %f %f %f %f %f\n",pid->kp , pid->ki, pid->kd , pid->stiction_up_val , pid->stiction_down_val );
4101 
4102  return true;
4103 }
4104 
4105 bool embObjMotionControl::helper_getTrqPidsRaw(Pid *pid)
4106 {
4107  std::vector<eOmc_PID_t> eoPIDList (_njoints);
4108  bool ret = askRemoteValues(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, eoprot_tag_mc_joint_config_pidtorque, eoPIDList);
4109  if(! ret)
4110  return false;
4111  for(int j=0; j< _njoints; j++)
4112  {
4113  copyPid_eo2iCub(&eoPIDList[j], &pid[j]);
4114  //printf("DEBUG getTorquePidRaw: %f %f %f %f %f\n",pid->kp , pid->ki, pid->kd , pid->stiction_up_val , pid->stiction_down_val );
4115  }
4116  return true;
4117 }
4118 
4119 
4120 bool embObjMotionControl::getImpedanceRaw(int j, double *stiffness, double *damping)
4121 {
4122  // first set is done in the open function because the whole joint config is sent to the EMSs
4123  eOmc_impedance_t val;
4124 
4125  if(!getWholeImpedanceRaw(j, val))
4126  return false;
4127 
4128  *stiffness = (double) (val.stiffness);
4129  *damping = (double) (val.damping);
4130  return true;
4131 }
4132 
4133 bool embObjMotionControl::getWholeImpedanceRaw(int j, eOmc_impedance_t &imped)
4134 {
4135  // first set is done in the open function because the whole joint config is sent to the EMSs
4136 
4137  eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_impedance);
4138  uint16_t size;
4139  if(! askRemoteValue(protoid, &imped, size))
4140  return false;
4141 
4142  // refresh cached value when reading data from the EMS
4143  _cacheImpedance->damping = imped.damping;
4144  _cacheImpedance->stiffness = imped.stiffness;
4145  _cacheImpedance->offset = imped.offset;
4146  return true;
4147 }
4148 
4149 bool embObjMotionControl::setImpedanceRaw(int j, double stiffness, double damping)
4150 {
4151  bool ret = true;
4152  eOmc_impedance_t val;
4153 
4154  // Need to read the whole struct and modify just 2 of them -> now aching the old values and re-using them.
4155  // first set is done in the open function because the whole joint config is sent to the EMSs
4156  // cleaner solution, split the impedance structure into 2 separeted nework variables
4157 // if(!getWholeImpedanceRaw(j, val))
4158 // return false;
4159 
4160  _cacheImpedance[j].stiffness = (eOmeas_stiffness_t) stiffness;
4161  _cacheImpedance[j].damping = (eOmeas_damping_t) damping;
4162 
4163  val.stiffness = _cacheImpedance[j].stiffness;
4164  val.damping = _cacheImpedance[j].damping;
4165  val.offset = _cacheImpedance[j].offset;
4166 
4167  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_impedance);
4168 
4169 
4170  ret &= res->setRemoteValue(protid, &val);
4171  return ret;
4172 }
4173 
4175 {
4176  bool ret = true;
4177  eOmc_impedance_t val;
4178 
4179  // first set is done in the open function because the whole joint config is sent to the EMSs
4180 // if(!getWholeImpedanceRaw(j, val))
4181 // return false;
4182 
4183  _cacheImpedance[j].offset = (eOmeas_torque_t) S_32(offset);
4184  val.stiffness = _cacheImpedance[j].stiffness;
4185  val.damping = _cacheImpedance[j].damping;
4186  val.offset = _cacheImpedance[j].offset;
4187 
4188  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_impedance);
4189 
4190 
4191  ret &= res->setRemoteValue(protid, &val);
4192 
4193  return ret;
4194 }
4195 
4197 {
4198  eOmc_impedance_t val;
4199 
4200  if(!getWholeImpedanceRaw(j, val))
4201  return false;
4202 
4203  *offset = val.offset;
4204  return true;
4205 }
4206 
4207 bool embObjMotionControl::getCurrentImpedanceLimitRaw(int j, double *min_stiff, double *max_stiff, double *min_damp, double *max_damp)
4208 {
4209  *min_stiff = _impedance_limits[j].min_stiff;
4210  *max_stiff = _impedance_limits[j].max_stiff;
4211  *min_damp = _impedance_limits[j].min_damp;
4212  *max_damp = _impedance_limits[j].max_damp;
4213  return true;
4214 }
4215 
4216 bool embObjMotionControl::getMotorTorqueParamsRaw(int j, MotorTorqueParameters *params)
4217 {
4218  eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_motor_params);
4219 
4220  uint16_t size;
4221  eOmc_motor_params_t eo_params = {0};
4222  if(! askRemoteValue(protoid, &eo_params, size))
4223  return false;
4224 
4225  params->bemf = eo_params.bemf_value;
4226  params->bemf_scale = eo_params.bemf_scale;
4227  params->ktau = eo_params.ktau_value;
4228  params->ktau_scale = eo_params.ktau_scale;
4229  params->viscousPos = eo_params.friction.viscous_pos_val;
4230  params->viscousNeg = eo_params.friction.viscous_neg_val ;
4231  params->coulombPos = eo_params.friction.coulomb_pos_val;
4232  params->coulombNeg = eo_params.friction.coulomb_neg_val;
4233  params->velocityThres = eo_params.friction.velocityThres_val;
4234 
4235  //printf("debug getMotorTorqueParamsRaw %f %f %f %f %f %f %f %f\n", params->bemf, params->bemf_scale, params->ktau,params->ktau_scale, params->viscousPos, params->viscousNeg, params->coulombPos, params->coulombNeg, params->threshold);
4236 
4237  return true;
4238 }
4239 
4240 bool embObjMotionControl::setMotorTorqueParamsRaw(int j, const MotorTorqueParameters params)
4241 {
4242  eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_motor_params);
4243  eOmc_motor_params_t eo_params = {0};
4244 
4245  //printf("setMotorTorqueParamsRaw for j %d(INPUT): benf=%f ktau=%f viscousPos=%f viscousNeg=%f coulombPos=%f coulombNeg=%f\n",j, params.bemf, params.ktau, params.viscousPos, params.viscousNeg, params.coulombPos, params.coulombNeg, params.threshold);
4246 
4247  eo_params.bemf_value = (float) params.bemf;
4248  eo_params.bemf_scale = (uint8_t) params.bemf_scale;
4249  eo_params.ktau_value = (float) params.ktau;
4250  eo_params.ktau_scale = (uint8_t) params.ktau_scale;
4251  eo_params.friction.viscous_pos_val = static_cast<float32_t>(params.viscousPos);
4252  eo_params.friction.viscous_neg_val = static_cast<float32_t>(params.viscousNeg);
4253  eo_params.friction.coulomb_pos_val = static_cast<float32_t>(params.coulombPos);
4254  eo_params.friction.coulomb_neg_val = static_cast<float32_t>(params.coulombNeg);
4255  eo_params.friction.velocityThres_val = static_cast<float32_t>(params.velocityThres);
4256 
4257 
4258  if(false == res->setRemoteValue(id32, &eo_params))
4259  {
4260  yError() << "embObjMotionControl::setMotorTorqueParamsRaw() could not send set message for" << getBoardInfo() << "joint " << j;
4261  return false;
4262  }
4263 
4264  return true;
4265 }
4266 
4267 // IVelocityControl2
4268 bool embObjMotionControl::velocityMoveRaw(const int n_joint, const int *joints, const double *spds)
4269 {
4270  bool ret = true;
4271 
4272  for(int j=0; j< n_joint; j++)
4273  {
4274  ret &= velocityMoveRaw(joints[j], spds[j]);
4275  }
4276  return ret;
4277 }
4278 
4279 /*
4280 bool embObjMotionControl::helper_setVelPidRaw(int j, const Pid &pid)
4281 {
4282  eOprotID32_t protoId = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_piddirect);
4283  eOmc_PID_t outPid;
4284  Pid hwPid = pid;
4285 
4286  if(!_dir_pids[j].enabled)
4287  {
4288  yError() << "eoMc " << getBoardInfo() << ": it is not possible set direct pid for joint " << j <<", because velocity pid is enabled in xml files";
4289  return false;
4290  }
4291 
4292  copyPid_iCub2eo(&hwPid, &outPid);
4293 
4294  if (false == res->setRemoteValue(protoId, &outPid))
4295  {
4296  yError() << "while setting direct PIDs for" << getBoardInfo() << " joint " << j;
4297  return false;
4298  }
4299 
4300  return true;
4301 
4302  //return NOT_YET_IMPLEMENTED("Our boards do not have a Velocity Pid");
4303 }
4304 */
4305 
4306 bool embObjMotionControl::helper_getVelPidRaw(int j, Pid *pid)
4307 {
4308  eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_piddirect);
4309  uint16_t size;
4310  eOmc_PID_t eoPID;
4311  if(! askRemoteValue(protoid, &eoPID, size))
4312  return false;
4313 
4314  copyPid_eo2iCub(&eoPID, pid);
4315 
4316  return true;
4317 
4318  //return NOT_YET_IMPLEMENTED("Our boards do not have a Velocity Pid");
4319 }
4320 
4321 bool embObjMotionControl::helper_getVelPidsRaw(Pid *pid)
4322 {
4323  std::vector <eOmc_PID_t> eoPIDList (_njoints);
4324  bool ret = askRemoteValues(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, eoprot_tag_mc_joint_config_piddirect, eoPIDList);
4325  if(!ret)
4326  return false;
4327 
4328  for(int j=0; j<_njoints; j++)
4329  {
4330  copyPid_eo2iCub(&eoPIDList[j], &pid[j]);
4331  }
4332 
4333  return true;
4334 
4335  //return NOT_YET_IMPLEMENTED("Our boards do not have a Velocity Pid");
4336 }
4337 
4338 // PositionDirect Interface
4340 {
4341  int mode = 0;
4342  getControlModeRaw(j, &mode);
4343  if (mode != VOCAB_CM_POSITION_DIRECT &&
4344  mode != VOCAB_CM_IDLE)
4345  {
4346  if(event_downsampler->canprint())
4347  {
4348  yError() << "setReferenceRaw: skipping command because" << getBoardInfo() << " joint " << j << " is not in VOCAB_CM_POSITION_DIRECT mode";
4349  }
4350  return true;
4351  }
4352 
4353  eOprotID32_t protoId = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_setpoint);
4354  eOmc_setpoint_t setpoint = {0};
4355 
4356  _ref_positions[j] = ref; // save internally the new value of pos.
4357  setpoint.type = (eOenum08_t) eomc_setpoint_positionraw;
4358  setpoint.to.position.value = (eOmeas_position_t) S_32(ref);
4359  setpoint.to.position.withvelocity = 0;
4360 
4361  return res->setRemoteValue(protoId, &setpoint);
4362 }
4363 
4364 bool embObjMotionControl::setPositionsRaw(const int n_joint, const int *joints, const double *refs)
4365 {
4366  bool ret = true;
4367  for(int i=0; i<n_joint; i++)
4368  {
4369  ret &= setPositionRaw(joints[i], refs[i]);
4370  }
4371  return ret;
4372 }
4373 
4375 {
4376  bool ret = true;
4377  for (int i = 0; i<_njoints; i++)
4378  {
4379  ret &= setPositionRaw(i, refs[i]);
4380  }
4381  return ret;
4382 }
4383 
4384 
4386 {
4387  if (axis<0 || axis>_njoints) return false;
4388 #if ASK_REFERENCE_TO_FIRMWARE
4389  eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, axis, eoprot_tag_mc_joint_status_target);
4390  *ref = 0;
4391 
4392  // Get the value
4393  uint16_t size;
4394  eOmc_joint_status_target_t target = {0};
4395  if(!askRemoteValue(id32, &target, size))
4396  {
4397  yError() << "embObjMotionControl::getTargetPositionRaw() could not read reference pos for " << getBoardInfo() << "joint " << axis;
4398  return false;
4399  }
4400 
4401  *ref = (double) target.trgt_position;
4402  //yError() << "embObjMotionControl::getTargetPositionRaw() BOARD" << _fId.boardNumber << "joint " << axis << "pos=" << target.trgt_position;
4403  return true;
4404 #else
4405  *ref = _ref_command_positions[axis];
4406  return true;
4407 #endif
4408 }
4409 
4411 {
4412  bool ret = true;
4413  for (int i = 0; i<_njoints; i++)
4414  {
4415  ret &= getTargetPositionRaw(i, &refs[i]);
4416  }
4417  return ret;
4418 }
4419 
4420 bool embObjMotionControl::getTargetPositionsRaw(int nj, const int * jnts, double *refs)
4421 {
4422  bool ret = true;
4423  for (int i = 0; i<nj; i++)
4424  {
4425  ret &= getTargetPositionRaw(jnts[i], &refs[i]);
4426  }
4427  return ret;
4428 }
4429 
4430 bool embObjMotionControl::getRefVelocityRaw(int axis, double *ref)
4431 {
4432  if (axis<0 || axis>_njoints) return false;
4433 #if ASK_REFERENCE_TO_FIRMWARE
4434  eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, axis, eoprot_tag_mc_joint_status_target);
4435  *ref = 0;
4436 
4437  // Get the value
4438  uint16_t size;
4439  eOmc_joint_status_target_t target = {0};
4440  if(!askRemoteValue(id32, &target, size))
4441  {
4442  yError() << "embObjMotionControl::getRefVelocityRaw() could not read reference vel for " << getBoardInfo() << "joint " << axis;
4443  return false;
4444  }
4445  *ref = (double) target.trgt_velocity;
4446  return true;
4447 #else
4448  *ref = _ref_command_speeds[axis];
4449  return true;
4450 #endif
4451 }
4452 
4454 {
4455  #if ASK_REFERENCE_TO_FIRMWARE
4456  std::vector <eOmc_joint_status_target_t> targetList(_njoints);
4457  bool ret = askRemoteValues(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, eoprot_tag_mc_joint_status_target, targetList);
4458  if(!ret)
4459  {
4460  yError() << "embObjMotionControl::getRefVelocitiesRaw() could not read reference vel for " << getBoardInfo() ;
4461  return false;
4462  }
4463  // Get the value
4464  for(int j=0; j<_njoints; j++)
4465  {
4466  refs[j] = (double) targetList[j].trgt_velocity;
4467  }
4468  return true;
4469  #else
4470  for(int j=0; j<_njoints; j++)
4471  {
4472  refs[j] = _ref_command_speeds[j];
4473  }
4474  return true;
4475  #endif
4476 }
4477 
4478 bool embObjMotionControl::getRefVelocitiesRaw(int nj, const int * jnts, double *refs)
4479 {
4480  std::vector <double> refsList(_njoints);
4481  if(!getRefVelocitiesRaw(refsList.data()))
4482  return false;
4483 
4484  for (int i = 0; i<nj; i++)
4485  {
4486  if(jnts[i]>= _njoints)
4487  {
4488  yError() << getBoardInfo() << "getRefVelocitiesRaw: joint " << jnts[i] << "doesn't exist";
4489  return false;
4490  }
4491  refs[i] = refsList[jnts[i]];
4492  }
4493  return true;
4494 }
4495 
4496 bool embObjMotionControl::getRefPositionRaw(int axis, double *ref)
4497 {
4498  if (axis<0 || axis>_njoints) return false;
4499 #if ASK_REFERENCE_TO_FIRMWARE
4500  eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, axis, eoprot_tag_mc_joint_status_target);
4501  *ref = 0;
4502  // Get the value
4503  uint16_t size;
4504  eOmc_joint_status_target_t target = {0};
4505  if(!askRemoteValue(id32, &target, size))
4506  {
4507  yError() << "embObjMotionControl::getRefPositionRaw() could not read reference pos for " << getBoardInfo() << "joint " << axis;
4508  return false;
4509  }
4510 
4511  *ref = (double) target.trgt_positionraw;
4512  return true;
4513 #else
4514  *ref = _ref_positions[axis];
4515  return true;
4516 #endif
4517 }
4518 
4520 {
4521  #if ASK_REFERENCE_TO_FIRMWARE
4522  std::vector <eOmc_joint_status_target_t> targetList(_njoints);
4523  bool ret = askRemoteValues(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, eoprot_tag_mc_joint_status_target, targetList);
4524  if(!ret)
4525  {
4526  yError() << "embObjMotionControl::getRefPositionRaw() could not read reference pos for " << getBoardInfo();
4527  return false;
4528  }
4529  // Get the value
4530  for(int j=0; j< _njoints; j++)
4531  refs[j] = (double) targetList[j].trgt_positionraw;
4532  return true;
4533  #else
4534  for(int j=0; j< _njoints; j++)
4535  refs[j] = _ref_positions[j];
4536  return true;
4537  #endif
4538 }
4539 
4540 bool embObjMotionControl::getRefPositionsRaw(int nj, const int * jnts, double *refs)
4541 {
4542  bool ret = true;
4543  for (int i = 0; i<nj; i++)
4544  {
4545  ret &= getRefPositionRaw(jnts[i], &refs[i]);
4546  }
4547  return ret;
4548 }
4549 
4550 // InteractionMode
4551 
4552 
4553 
4554 bool embObjMotionControl::getInteractionModeRaw(int j, yarp::dev::InteractionModeEnum* _mode)
4555 {
4556  eOenum08_t interactionmodestatus;
4557 // std::cout << "eoMC getInteractionModeRaw SINGLE joint " << j << std::endl;
4558 
4559  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_core_modes_interactionmodestatus);
4560  if(! res->getLocalValue(protid, &interactionmodestatus)) // it is broadcasted toghether with the jointStatus full
4561  return false;
4562 
4563  int tmp = (int) *_mode;
4564  if(!interactionModeStatusConvert_embObj2yarp(interactionmodestatus, tmp) )
4565  return false;
4566 
4567  *_mode = (yarp::dev::InteractionModeEnum) tmp;
4568  return true;
4569 }
4570 
4571 bool embObjMotionControl::getInteractionModesRaw(int n_joints, int *joints, yarp::dev::InteractionModeEnum* modes)
4572 {
4573 // std::cout << "eoMC getInteractionModeRaw GROUP joints" << std::endl;
4574  bool ret = true;
4575  for(int idx=0; idx<n_joints; idx++)
4576  {
4577  ret = getInteractionModeRaw(joints[idx], &modes[idx]);
4578  }
4579  return ret;
4580 }
4581 
4582 bool embObjMotionControl::getInteractionModesRaw(yarp::dev::InteractionModeEnum* modes)
4583 {
4584 // std::cout << "eoMC getInteractionModeRaw ALL joints" << std::endl;
4585  bool ret = true;
4586  for(int j=0; j<_njoints; j++)
4587  ret = ret && getInteractionModeRaw(j, &modes[j]);
4588  return ret;
4589 }
4590 
4591 // marco.accame: con alberto cardellino abbiamo parlato della correttezza di effettuare la verifica di quanto imposto (in setInteractionModeRaw() ed affini)
4592 // andando a rileggere il valore nella scheda eth fino a che esso non sia quello atteso. si deve fare oppure no?
4593 // con il interaction mode il can ora non lo fa. mentre lo fa per il control mode. perche' diverso?
4594 bool embObjMotionControl::setInteractionModeRaw(int j, yarp::dev::InteractionModeEnum _mode)
4595 {
4596  eOenum08_t interactionmodecommand = 0;
4597 
4598 
4599  // yDebug() << "received setInteractionModeRaw command (SINGLE) for" << getBoardInfo() << " joint " << j << " mode " << Vocab32::decode(_mode);
4600 
4601  if (_mode == VOCAB_IM_COMPLIANT && _trq_pids[j].enabled == false) {yError()<<"Torque control is disabled. Check your configuration parameters"; return false;}
4602 
4603  if(!interactionModeCommandConvert_yarp2embObj(_mode, interactionmodecommand) )
4604  {
4605  yError() << "setInteractionModeRaw: received unknown mode for" << getBoardInfo() << " joint " << j << " mode " << Vocab32::decode(_mode);
4606  }
4607 
4608  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_interactionmode);
4609 
4610  if(false == res->setRemoteValue(protid, &interactionmodecommand) )
4611  {
4612  yError() << "setInteractionModeRaw failed for" << getBoardInfo() << " joint " << j << " mode " << Vocab32::decode(_mode);
4613  return false;
4614  }
4615 
4616  // marco.accame: use the following if you want to check the value of interactionmode on the remote board
4617 #if 0
4618  eOenum08_t interactionmodestatus = 0;
4619  uint16_t size = 0;
4620  eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_interactionmodestatus);
4621  bool ret = askRemoteValue(id32, &interactionmodestatus, size);
4622 
4623  if((false == ret) || (interactionmodecommand != interactionmodestatus))
4624  {
4625  yError() << "check of embObjMotionControl::setInteractionModeRaw() failed for" << getBoardInfo() << " joint " << j << " mode " << Vocab32::decode(_mode);
4626  return false;
4627  }
4628 #endif
4629 
4630  return true;
4631 }
4632 
4633 
4634 bool embObjMotionControl::setInteractionModesRaw(int n_joints, int *joints, yarp::dev::InteractionModeEnum* modes)
4635 {
4636 // std::cout << "setInteractionModeRaw GROUP " << std::endl;
4637 
4638  eOenum08_t interactionmodecommand = 0;
4639 
4640  for(int j=0; j<n_joints; j++)
4641  {
4642  if (modes[j] == VOCAB_IM_COMPLIANT && _trq_pids[j].enabled == false) {yError()<<"Torque control is disabled. Check your configuration parameters"; continue;}
4643 
4644  if(!interactionModeCommandConvert_yarp2embObj(modes[j], interactionmodecommand) )
4645  {
4646  yError() << "embObjMotionControl::setInteractionModesRaw(): received unknown interactionMode for" << getBoardInfo() << " joint " << j << " mode " << Vocab32::decode(modes[j]) << " " << modes[j];
4647  return false;
4648  }
4649 
4650  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_interactionmode);
4651  if(false == res->setRemoteValue(protid, &interactionmodecommand) )
4652  {
4653  yError() << "embObjMotionControl::setInteractionModesRaw() failed for" << getBoardInfo() << " joint " << j << " mode " << Vocab32::decode(modes[j]);
4654  return false;
4655  }
4656 
4657  // marco.accame: use the following if you want to check the value of interactionmode on the remote board
4658 #if 0
4659  eOenum08_t interactionmodestatus = 0;
4660  uint16_t size = 0;
4661  eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_interactionmodestatus);
4662  bool ret = askRemoteValue(id32, &interactionmodestatus, size);
4663 
4664  if((false == ret) || (interactionmodecommand != interactionmodestatus))
4665  {
4666  if(false == ret)
4667  {
4668  yError() << "check of embObjMotionControl::setInteractionModesRaw() failed for" << getBoardInfo() << " joint " << j << " mode " << Vocab32::decode(modes[j]);
4669  return false;
4670  }
4671 
4672  int tmp;
4673  if(interactionModeStatusConvert_embObj2yarp(interactionmodestatus, tmp) )
4674  yError() << "setInteractionModeRaw failed for" << getBoardInfo() << " joint " << j << " because of interactionMode mismatching \n\tSet " \
4675  << Vocab32::decode(modes[j]) << " Got " << Vocab32::decode(tmp);
4676  else
4677  yError() << "setInteractionModeRaw failed for" << getBoardInfo() << " joint " << j << " because of interactionMode mismatching \n\tSet " \
4678  << Vocab32::decode(modes[j]) << " Got an unknown value!";
4679  return false;
4680  }
4681 #endif
4682 
4683  }
4684 
4685  return true;
4686 }
4687 
4688 bool embObjMotionControl::setInteractionModesRaw(yarp::dev::InteractionModeEnum* modes)
4689 {
4690 
4691  eOenum08_t interactionmodecommand = 0;
4692 
4693  for(int j=0; j<_njoints; j++)
4694  {
4695  if ((modes[j] == VOCAB_IM_COMPLIANT) && (_trq_pids[j].enabled == false))
4696  {
4697  yError()<<"Torque control is disabled. Check your configuration parameters";
4698  continue;
4699  }
4700 
4701  if(!interactionModeCommandConvert_yarp2embObj(modes[j], interactionmodecommand) )
4702  {
4703  yError() << "setInteractionModeRaw: received unknown interactionMode for" << getBoardInfo() << " joint " << j << " mode " << Vocab32::decode(modes[j]);
4704  return false;
4705  }
4706 
4707  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_interactionmode);
4708  if(false == res->setRemoteValue(protid, &interactionmodecommand) )
4709  {
4710  yError() << "setInteractionModeRaw failed for" << getBoardInfo() << " joint " << j << " mode " << Vocab32::decode(modes[j]);
4711  return false;
4712  }
4713 
4714  // marco.accame: use the following if you want to check the value of interactionmode on the remote board
4715 #if 0
4716  eOenum08_t interactionmodestatus = 0;
4717  uint16_t size = 0;
4718  eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_interactionmodestatus);
4719  bool ret = askRemoteValue(id32, &interactionmodestatus, size);
4720 
4721  if((false == ret) || (interactionmodecommand != interactionmodestatus))
4722  {
4723  if(false == ret)
4724  {
4725  yError() << "check of embObjMotionControl::setInteractionModesRaw() failed for" << getBoardInfo() << " joint " << j << " mode " << Vocab32::decode(modes[j]);
4726  return false;
4727  }
4728 
4729  int tmp;
4730  if(interactionModeStatusConvert_embObj2yarp(interactionmodestatus, tmp) )
4731  yError() << "setInteractionModeRaw failed for" << getBoardInfo() << " joint " << j << " because of interactionMode mismatching \n\tSet " \
4732  << Vocab32::decode(modes[j]) << " Got " << Vocab32::decode(tmp);
4733  else
4734  yError() << "setInteractionModeRaw failed for" << getBoardInfo() << " joint " << j << " because of interactionMode mismatching \n\tSet " \
4735  << Vocab32::decode(modes[j]) << " Got an unknown value!";
4736  return false;
4737  }
4738 #endif
4739 
4740  }
4741 
4742  return true;
4743 }
4744 
4745 
4746 bool embObjMotionControl::getPidOutputRaw(const PidControlTypeEnum& pidtype, int j, double *out)
4747 {
4748  eOprotID32_t protoId = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_core);
4749  eOmc_joint_status_core_t jcore = {0};
4750  *out = 0;
4751  if(!res->getLocalValue(protoId, &jcore) )
4752  return false;
4753 
4754  switch (pidtype)
4755  {
4756  case VOCAB_PIDTYPE_POSITION:
4757  if((eomc_controlmode_torque == jcore.modes.controlmodestatus) || (eomc_controlmode_current == jcore.modes.controlmodestatus))
4758  *out=0;
4759  else
4760  *out = (double) jcore.ofpid.generic.output;
4761  break;
4762  //case VOCAB_PIDTYPE_DIRECT:
4763  // *out=0;
4764  //break;
4765  case VOCAB_PIDTYPE_TORQUE:
4766  if ((eomc_controlmode_torque == jcore.modes.controlmodestatus) ||
4767  ((eomc_controlmode_position == jcore.modes.controlmodestatus) && (eOmc_interactionmode_compliant == jcore.modes.interactionmodestatus)))
4768  *out = jcore.ofpid.generic.output;
4769  else
4770  *out = 0;
4771  break;
4772  case VOCAB_PIDTYPE_CURRENT:
4773  *out=0;
4774  break;
4775  case VOCAB_PIDTYPE_VELOCITY:
4776  *out = 0;
4777  break;
4778  default:
4779  yError()<<"Invalid pidtype:"<<pidtype;
4780  break;
4781  }
4782  return true;
4783 }
4784 
4785 bool embObjMotionControl::getPidOutputsRaw(const PidControlTypeEnum& pidtype, double *outs)
4786 {
4787  bool ret = true;
4788  for(int j=0; j< _njoints; j++)
4789  {
4790  ret &= getPidOutputRaw(pidtype, j, &outs[j]);
4791  }
4792  return ret;
4793 }
4794 
4795 bool embObjMotionControl::isPidEnabledRaw(const PidControlTypeEnum& pidtype, int j, bool* enabled)
4796 {
4797  return NOT_YET_IMPLEMENTED("isPidEnabled");
4798 }
4799 
4801 {
4802  *num=_njoints;
4803  return true;
4804 }
4805 
4807 {
4808  eOmc_motor_status_basic_t status;
4809  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, m, eoprot_tag_mc_motor_status_basic);
4810 
4811  // if (_temperatureSensorsVector.at(m) == nullptr || (_temperatureSensorsVector.at(motor)->getType() == motor_temperature_sensor_none))
4812  *val = NAN;
4813  if (_temperatureSensorsVector.at(m)->getType() == motor_temperature_sensor_none)
4814  return true;
4815 
4816 
4817  bool ret = res->getLocalValue(protid, &status);
4818  if(!ret)
4819  {
4820  yError() << getBoardInfo() << "At timestamp" << yarp::os::Time::now() << "In motor" << m << "embObjMotionControl::getTemperatureRaw failed to complete getLocalValue()";
4821  return ret;
4822  }
4823 
4824  if (((double)status.mot_temperature) == temperatureErrorValue_s) //using -5000 as the default value on 2FOC for initializing the temperature. If cannot read from I2C the value cannot be updated
4825  {
4826  return false;
4827  }
4828 
4829  *val = _temperatureSensorsVector.at(m)->convertRawToTempCelsius((double)status.mot_temperature);
4830 
4831 
4832  return ret;
4833 }
4834 
4836 {
4837  bool ret = true;
4838  for(int j=0; j< _njoints; j++)
4839  {
4840  ret &= getTemperatureRaw(j, &vals[j]);
4841  }
4842  return ret;
4843 }
4844 
4846 {
4847  // eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, m, eoprot_tag_mc_motor_config_temperaturelimit);
4848  // uint16_t size;
4849  // eOmeas_temperature_t temperaturelimit = {0};
4850  // *temp = 0;
4851  // if(!askRemoteValue(protid, &temperaturelimit, size))
4852  // {
4853  // yError() << "embObjMotionControl::getTemperatureLimitRaw() can't read temperature limits for" << getBoardInfo() << " motor " << m;
4854  // return false;
4855  // }
4856 
4857  // *temp = (double) temperaturelimit;
4858 
4859  *temp= _temperatureLimits[m].warningTemperatureLimit;
4860 
4861  return true;
4862 }
4863 
4864 bool embObjMotionControl::setTemperatureLimitRaw(int m, const double temp)
4865 {
4866  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, m, eoprot_tag_mc_motor_config_temperaturelimit);
4867  eOmeas_temperature_t temperatureLimit = (eOmeas_pwm_t) S_16(temp);
4868  return res->setRemoteValue(protid, &temperatureLimit);
4869 
4870 }
4871 
4873 {
4874  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, m, eoprot_tag_mc_motor_config_currentlimits);
4875  uint16_t size;
4876  eOmc_current_limits_params_t currentlimits = {0};
4877  *val = 0;
4878  if(!askRemoteValue(protid, &currentlimits, size))
4879  {
4880  yError() << "embObjMotionControl::getPeakCurrentRaw() can't read current limits for" << getBoardInfo() << " motor " << m;
4881  return false;
4882  }
4883 
4884  *val = (double) currentlimits.peakCurrent ;
4885  return true;
4886 }
4887 
4888 bool embObjMotionControl::setPeakCurrentRaw(int m, const double val)
4889 {
4890  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, m, eoprot_tag_mc_motor_config_currentlimits);
4891  //get current limit params
4892  uint16_t size;
4893  eOmc_current_limits_params_t currentlimits = {0};
4894  if(!askRemoteValue(protid, &currentlimits, size))
4895  {
4896  yError() << "embObjMotionControl::setPeakCurrentRaw can't read current limits for" << getBoardInfo() << " motor " << m ;
4897  return false;
4898  }
4899 
4900  //set current overload
4901  currentlimits.peakCurrent = (eOmeas_current_t) S_16(val);
4902 
4903  //send new values
4904  bool ret = res->setRemoteValue(protid, &currentlimits);
4905  if(!ret)
4906  {
4907  yError() << "embObjMotionControl::setPeakCurrentRaw failed sending new value for" << getBoardInfo() << " motor " << m ;
4908  }
4909  return ret;
4910 }
4911 
4913 {
4914  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, m, eoprot_tag_mc_motor_config_currentlimits);
4915  uint16_t size;
4916  eOmc_current_limits_params_t currentlimits = {0};
4917  *val = 0;
4918  if(!askRemoteValue(protid, &currentlimits, size))
4919  {
4920  yError() << "embObjMotionControl::getNominalCurrentRaw() can't read current limits for" << getBoardInfo() << " motor " << m;
4921  return false;
4922  }
4923 
4924  *val = (double) currentlimits.nominalCurrent ;
4925  return true;
4926 }
4927 
4928 bool embObjMotionControl::setNominalCurrentRaw(int m, const double val)
4929 {
4930  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, m, eoprot_tag_mc_motor_config_currentlimits);
4931 
4932  //get current limit params
4933  uint16_t size;
4934  eOmc_current_limits_params_t currentlimits = {0};
4935  if(!askRemoteValue(protid, &currentlimits, size))
4936  {
4937  yError() << "embObjMotionControl::setNominalCurrentRaw can't read current limits for" << getBoardInfo() << " motor " << m ;
4938  return false;
4939  }
4940 
4941  //set current overload
4942  currentlimits.nominalCurrent = (eOmeas_current_t) S_16(val);
4943 
4944  //send new values
4945  bool ret = res->setRemoteValue(protid, &currentlimits);
4946  if(!ret)
4947  {
4948  yError() << "embObjMotionControl::setNominalCurrentRaw failed sending new value for" << getBoardInfo() << " motor " << m ;
4949  }
4950 
4951  return ret;
4952 }
4953 
4954 bool embObjMotionControl::getPWMRaw(int j, double* val)
4955 {
4956  eOmc_motor_status_basic_t status;
4957  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_status_basic);
4958 
4959  bool ret = res->getLocalValue(protid, &status);
4960  if(ret)
4961  {
4962  *val = (double) status.mot_pwm;
4963  }
4964  else
4965  {
4966  yError() << "embObjMotionControl::getPWMRaw failed for" << getBoardInfo() << " motor " << j ;
4967  *val = 0;
4968  }
4969 
4970  return ret;
4971 }
4972 
4973 bool embObjMotionControl::getPWMLimitRaw(int j, double* val)
4974 {
4975  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config_pwmlimit);
4976  uint16_t size;
4977  eOmeas_pwm_t motorPwmLimit;
4978 
4979  bool ret = askRemoteValue(protid, &motorPwmLimit, size);
4980  if(ret)
4981  {
4982  *val = (double) motorPwmLimit;
4983  }
4984  else
4985  {
4986  yError() << "embObjMotionControl::getPWMLimitRaw failed for" << getBoardInfo() << " motor " << j ;
4987  *val = 0;
4988  }
4989 
4990  return ret;
4991 }
4992 
4993 bool embObjMotionControl::setPWMLimitRaw(int j, const double val)
4994 {
4995  if (val < 0)
4996  {
4997  yError() << "embObjMotionControl::setPWMLimitRaw failed because pwmLimit is negative for" << getBoardInfo() << " motor " << j ;
4998  return true; //return true because the error ios not due to communication error
4999  }
5000  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config_pwmlimit);
5001  eOmeas_pwm_t motorPwmLimit = (eOmeas_pwm_t) S_16(val);
5002  return res->setRemoteValue(protid, &motorPwmLimit);
5003 }
5004 
5006 {
5007  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_controller, 0, eoprot_tag_mc_controller_status);
5008  uint16_t size;
5009  eOmc_controller_status_t controllerStatus;
5010 
5011  bool ret = askRemoteValue(protid, &controllerStatus, size);
5012  if(ret)
5013  {
5014  *val = (double) controllerStatus.supplyVoltage;
5015  }
5016  else
5017  {
5018  yError() << "embObjMotionControl::getPowerSupplyVoltageRaw failed for" << getBoardInfo() << " motor " << j ;
5019  *val = 0;
5020  }
5021 
5022  return ret;
5023 }
5024 
5025 bool embObjMotionControl::askRemoteValue(eOprotID32_t id32, void* value, uint16_t& size)
5026 {
5027  return res->getRemoteValue(id32, value, 0.200, 0);
5028 }
5029 
5030 
5031 template <class T>
5032 bool embObjMotionControl::askRemoteValues(eOprotEndpoint_t ep, eOprotEntity_t entity, eOprotTag_t tag, std::vector<T>& values)
5033 {
5034  std::vector<eOprotID32_t> idList;
5035  std::vector<void*> valueList;
5036  idList.clear();
5037  valueList.clear();
5038  for(int j=0; j<_njoints; j++)
5039  {
5040  eOprotID32_t protoId = eoprot_ID_get(ep, entity, j, tag);
5041  idList.push_back(protoId);
5042  valueList.push_back((void*)&values[j]);
5043  }
5044 
5045  bool ret = res->getRemoteValues(idList, valueList);
5046  if(!ret)
5047  {
5048  yError() << "embObjMotionControl::askRemoteValues failed for all joints of" << getBoardInfo();
5049  }
5050 
5051  return ret;
5052 }
5053 
5054 
5055 
5056 
5057 bool embObjMotionControl::checkRemoteControlModeStatus(int joint, int target_mode)
5058 {
5059  bool ret = false;
5060  eOenum08_t temp = 0;
5061  uint16_t size = 0;
5062 
5063  eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, joint, eoprot_tag_mc_joint_status_core_modes_controlmodestatus);
5064  const double timeout = 0.250; // 250 msec
5065  const int maxretries = 25;
5066  const double delaybetweenqueries = 0.010; // 10 msec
5067 
5068  // now i repeat the query until i am satisfied. how many times? for maximum time timeout seconds and with a gap of delaybetweenqueries
5069 
5070  double timeofstart = yarp::os::Time::now();
5071  int attempt = 0;
5072 
5073  for( attempt = 0; attempt < maxretries; attempt++)
5074  {
5075  ret = askRemoteValue(id32, &temp, size);
5076  if(ret == false)
5077  {
5078  yError ("An error occurred inside embObjMotionControl::checkRemoteControlModeStatus(j=%d, targetmode=%s) for BOARD %s IP %s", joint, yarp::os::Vocab32::decode(target_mode).c_str(), res->getProperties().boardnameString.c_str(), res->getProperties().ipv4addrString.c_str());
5079  break;
5080  }
5081  int current_mode = controlModeStatusConvert_embObj2yarp(temp);
5082  if(current_mode == target_mode)
5083  {
5084  ret = true;
5085  break;
5086  }
5087  if((current_mode == VOCAB_CM_IDLE) && (target_mode == VOCAB_CM_FORCE_IDLE))
5088  {
5089  ret = true;
5090  break;
5091  }
5092  if(current_mode == VOCAB_CM_HW_FAULT)
5093  {
5094  if(target_mode != VOCAB_CM_FORCE_IDLE) { yError ("embObjMotionControl::checkRemoteControlModeStatus(%d, %d) is unable to check the control mode of BOARD %s IP %s because it is now in HW_FAULT", joint, target_mode, res->getProperties().boardnameString.c_str(), res->getProperties().ipv4addrString.c_str()); }
5095  ret = true;
5096  break;
5097  }
5098 
5099  if((yarp::os::Time::now()-timeofstart) > timeout)
5100  {
5101  ret = false;
5102  yError ("A %f sec timeout occured in embObjMotionControl::checkRemoteControlModeStatus(), BOARD %s IP %s, joint %d, current mode: %s, requested: %s", timeout, res->getProperties().boardnameString.c_str(), res->getProperties().ipv4addrString.c_str(), joint, yarp::os::Vocab32::decode(current_mode).c_str(), yarp::os::Vocab32::decode(target_mode).c_str());
5103  break;
5104  }
5105  if(attempt > 0)
5106  { // i print the warning only after at least one retry.
5107  yWarning ("embObjMotionControl::checkRemoteControlModeStatus() has done %d attempts and will retry again after a %f sec delay. (BOARD %s IP %s, joint %d) -> current mode = %s, requested = %s", attempt+1, delaybetweenqueries, res->getProperties().boardnameString.c_str() , res->getProperties().ipv4addrString.c_str(), joint, yarp::os::Vocab32::decode(current_mode).c_str(), yarp::os::Vocab32::decode(target_mode).c_str());
5108  }
5109  SystemClock::delaySystem(delaybetweenqueries);
5110  }
5111 
5112  if(false == ret)
5113  {
5114  yError("failure of embObjMotionControl::checkRemoteControlModeStatus(j=%d, targetmode=%s) for BOARD %s IP %s after %d attempts and %f seconds", joint, yarp::os::Vocab32::decode(target_mode).c_str(), res->getProperties().boardnameString.c_str(), res->getProperties().ipv4addrString.c_str(), attempt, yarp::os::Time::now()-timeofstart);
5115  }
5116 
5117 
5118  return ret;
5119 }
5120 
5121 //the device needs coupling info if it manages joints controlled by 2foc and mc4plus.
5122 bool embObjMotionControl::iNeedCouplingsInfo(void)
5123 {
5124  eOmn_serv_type_t mc_serv_type = (eOmn_serv_type_t)serviceConfig.ethservice.configuration.type;
5125  if( (mc_serv_type == eomn_serv_MC_foc) ||
5126  (mc_serv_type == eomn_serv_MC_mc4plus) ||
5127  (mc_serv_type == eomn_serv_MC_mc4plusmais) ||
5128  (mc_serv_type == eomn_serv_MC_mc2pluspsc) ||
5129  (mc_serv_type == eomn_serv_MC_mc4plusfaps) ||
5130  (mc_serv_type == eomn_serv_MC_advfoc)
5131  )
5132  return true;
5133  else
5134  return false;
5135 }
5136 
5137 //PWM interface
5139 {
5140  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_setpoint);
5141 
5142  eOmc_setpoint_t setpoint;
5143 
5144  setpoint.type = (eOenum08_t)eomc_setpoint_openloop;
5145  setpoint.to.openloop.value = (eOmeas_pwm_t)S_16(v);
5146 
5147  return res->setRemoteValue(protid, &setpoint);
5148 }
5149 
5151 {
5152  bool ret = true;
5153  for (int j = 0; j<_njoints; j++)
5154  {
5155  ret = ret && setRefDutyCycleRaw(j, v[j]);
5156  }
5157  return ret;
5158 }
5159 
5161 {
5162  eOprotID32_t protoId = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_target);
5163  uint16_t size = 0;
5164  *v = 0;
5165  eOmc_joint_status_target_t target = { 0 };
5166 
5167 
5168  if (!askRemoteValue(protoId, &target, size))
5169  {
5170  yError() << "embObjMotionControl::getRefDutyCycleRaw() could not read openloop reference for " << getBoardInfo() << "joint " << j;
5171  return false;
5172  }
5173 
5174  *v = (double)target.trgt_pwm;
5175 
5176  return true;
5177 }
5178 
5180 {
5181  std::vector <eOmc_joint_status_target_t> targetList(_njoints);
5182  bool ret = askRemoteValues(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, eoprot_tag_mc_joint_status_target, targetList);
5183  if(!ret)
5184  {
5185  yError() << "embObjMotionControl::getDutyCyclesRaw failed for all joints of" << getBoardInfo();
5186  }
5187 
5188  for (int j = 0; j<_njoints; j++)
5189  {
5190  v[j]= targetList[j].trgt_pwm;
5191  }
5192  return ret;
5193 }
5194 
5196 {
5197  eOmc_motor_status_basic_t status;
5198  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_status_basic);
5199 
5200  bool ret = res->getLocalValue(protid, &status);
5201  if (ret)
5202  {
5203  *v = (double)status.mot_pwm;
5204  }
5205  else
5206  {
5207  yError() << "embObjMotionControl::getDutyCycleRaw failed for" << getBoardInfo() << " motor " << j;
5208  *v = 0;
5209  }
5210 
5211  return ret;
5212 }
5213 
5215 {
5216  bool ret = true;
5217  for (int j = 0; j< _njoints; j++)
5218  {
5219  ret &= getDutyCycleRaw(j, &v[j]);
5220  }
5221  return ret;
5222 }
5223 
5224 // Current interface
5225 
5226 bool embObjMotionControl::getCurrentRangeRaw(int j, double *min, double *max)
5227 {
5228  //this should be completed with numbers obtained from configuration files.
5229  //some caveats: currently current limits are expressed in robot configuration files in milliAmperes. Amperes should be used instead.
5230  //yarp does not perform any conversion on these numbers. Should it?
5231  *min = -10000.0;
5232  *max = 10000.0;
5233  return true;
5234 }
5235 
5237 {
5238  bool ret = true;
5239  for (int j = 0; j< _njoints; j++)
5240  {
5241  ret &= getCurrentRangeRaw(j, &min[j], &max[j]);
5242  }
5243  return ret;
5244 }
5245 
5247 {
5248  bool ret = true;
5249  for (int j = 0; j<_njoints; j++)
5250  {
5251  ret = ret && setRefCurrentRaw(j, t[j]);
5252  }
5253  return ret;
5254 }
5255 
5257 {
5258  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_setpoint);
5259 
5260  eOmc_setpoint_t setpoint;
5261 
5262  setpoint.type = (eOenum08_t)eomc_setpoint_current;
5263  setpoint.to.current.value = (eOmeas_pwm_t)S_16(t);
5264 
5265  return res->setRemoteValue(protid, &setpoint);
5266 }
5267 
5268 bool embObjMotionControl::setRefCurrentsRaw(const int n_joint, const int *joints, const double *t)
5269 {
5270  bool ret = true;
5271  for (int j = 0; j<n_joint; j++)
5272  {
5273  ret = ret && setRefCurrentRaw(joints[j], t[j]);
5274  }
5275  return ret;
5276 }
5277 
5279 {
5280  std::vector <eOmc_joint_status_target_t> targetList(_njoints);
5281  bool ret = askRemoteValues(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, eoprot_tag_mc_joint_status_target, targetList);
5282  if (!ret)
5283  {
5284  yError() << "embObjMotionControl::getDutyCyclesRaw failed for all joints of" << getBoardInfo();
5285  }
5286 
5287  for (int j = 0; j<_njoints; j++)
5288  {
5289  t[j] = targetList[j].trgt_current;
5290  }
5291  return ret;
5292 }
5293 
5295 {
5296  eOprotID32_t protoId = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_target);
5297  uint16_t size = 0;
5298  *t = 0;
5299  eOmc_joint_status_target_t target = { 0 };
5300 
5301 
5302  if (!askRemoteValue(protoId, &target, size))
5303  {
5304  yError() << "embObjMotionControl::getRefDutyCycleRaw() could not read openloop reference for " << getBoardInfo() << "joint " << j;
5305  return false;
5306  }
5307 
5308  *t = (double)target.trgt_current;
5309 
5310  return true;
5311 }
5312 
5313 bool embObjMotionControl::helper_setCurPidRaw(int j, const Pid &pid)
5314 {
5315  eOprotID32_t protoId = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config_pidcurrent);
5316  eOmc_PID_t outPid;
5317  Pid hwPid = pid;
5318 
5319  if (!_cur_pids[j].enabled)
5320  {
5321  yError() << "eoMc " << getBoardInfo() << ": it is not possible set current pid for motor " << j << ", because current pid is not enabled in xml files";
5322  return false;
5323  }
5324 
5325  copyPid_iCub2eo(&hwPid, &outPid);
5326 
5327  if (false == res->setRemoteValue(protoId, &outPid))
5328  {
5329  yError() << "while setting velocity PIDs for" << getBoardInfo() << " joint " << j;
5330  return false;
5331  }
5332 
5333  return true;
5334 
5335  //return NOT_YET_IMPLEMENTED("Our boards do not have a Velocity Pid");
5336 }
5337 
5338 bool embObjMotionControl::helper_setSpdPidRaw(int j, const Pid &pid)
5339 {
5340  eOprotID32_t protoId = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config_pidspeed);
5341  eOmc_PID_t outPid;
5342  Pid hwPid = pid;
5343 
5344  if (!_cur_pids[j].enabled)
5345  {
5346  yError() << "eoMc " << getBoardInfo() << ": it is not possible set speed pid for motor " << j << ", because speed pid is not enabled in xml files";
5347  return false;
5348  }
5349 
5350  copyPid_iCub2eo(&hwPid, &outPid);
5351 
5352  if (false == res->setRemoteValue(protoId, &outPid))
5353  {
5354  yError() << "while setting velocity PIDs for" << getBoardInfo() << " joint " << j;
5355  return false;
5356  }
5357 
5358  return true;
5359 
5360  //return NOT_YET_IMPLEMENTED("Our boards do not have a Velocity Pid");
5361 }
5362 
5363 bool embObjMotionControl::helper_getCurPidRaw(int j, Pid *pid)
5364 {
5365  eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config);
5366  uint16_t size;
5367  eOmc_motor_config_t motor_cfg;
5368  if(! askRemoteValue(protoid, &motor_cfg, size))
5369  return false;
5370 
5371  // refresh cached value when reading data from the EMS
5372  eOmc_PID_t tmp = (eOmc_PID_t)motor_cfg.pidcurrent;
5373  copyPid_eo2iCub(&tmp, pid);
5374 
5375  return true;
5376 }
5377 
5378 bool embObjMotionControl::helper_getSpdPidRaw(int j, Pid *pid)
5379 {
5380  eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config);
5381  uint16_t size;
5382  eOmc_motor_config_t motor_cfg;
5383  if (!askRemoteValue(protoid, &motor_cfg, size))
5384  return false;
5385 
5386  // refresh cached value when reading data from the EMS
5387  eOmc_PID_t tmp = (eOmc_PID_t)motor_cfg.pidspeed;
5388  copyPid_eo2iCub(&tmp, pid);
5389 
5390  return true;
5391 }
5392 
5393 bool embObjMotionControl::helper_getCurPidsRaw(Pid *pid)
5394 {
5395  std::vector <eOmc_motor_config_t> motor_cfg_list(_njoints);
5396  bool ret = askRemoteValues<eOmc_motor_config_t>(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, eoprot_tag_mc_motor_config, motor_cfg_list);
5397  if(! ret)
5398  return false;
5399 
5400  for(int j=0; j<_njoints; j++)
5401  {
5402  eOmc_PID_t tmp = (eOmc_PID_t)motor_cfg_list[j].pidcurrent;
5403  copyPid_eo2iCub(&tmp, &pid[j]);
5404  }
5405  return true;
5406 }
5407 
5408 bool embObjMotionControl::helper_getSpdPidsRaw(Pid *pid)
5409 {
5410  std::vector <eOmc_motor_config_t> motor_cfg_list(_njoints);
5411  bool ret = askRemoteValues<eOmc_motor_config_t>(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, eoprot_tag_mc_motor_config, motor_cfg_list);
5412  if (!ret)
5413  return false;
5414 
5415  for (int j = 0; j<_njoints; j++)
5416  {
5417  eOmc_PID_t tmp = (eOmc_PID_t)motor_cfg_list[j].pidspeed;
5418  copyPid_eo2iCub(&tmp, &pid[j]);
5419  }
5420  return true;
5421 }
5422 
5423 bool embObjMotionControl::getJointConfiguration(int joint, eOmc_joint_config_t *jntCfg_ptr)
5424 {
5425  uint32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, joint, eoprot_tag_mc_joint_config);
5426  uint16_t size;
5427  if(!askRemoteValue(protoid, jntCfg_ptr, size))
5428  {
5429  yError ("Failure of askRemoteValue() inside embObjMotionControl::getJointConfiguration(axis=%d) for BOARD %s IP %s", joint, res->getProperties().boardnameString.c_str(), res->getProperties().ipv4addrString.c_str());
5430  return false;
5431  }
5432  return true;
5433 }
5434 
5435 bool embObjMotionControl::getMotorConfiguration(int axis, eOmc_motor_config_t *motCfg_ptr)
5436 {
5437  uint32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, axis, eoprot_tag_mc_motor_config);
5438  uint16_t size;
5439  if(!askRemoteValue(protoid, motCfg_ptr, size))
5440  {
5441  yError ("Failure of askRemoteValue() inside embObjMotionControl::getMotorConfiguration(axis=%d) for BOARD %s IP %s", axis, res->getProperties().boardnameString.c_str(), res->getProperties().ipv4addrString.c_str());
5442  return false;
5443  }
5444  return true;
5445 }
5446 
5447 
5448 bool embObjMotionControl::getGerabox_E2J(int joint, double *gearbox_E2J_ptr)
5449 {
5450  eOmc_joint_config_t jntCfg;
5451 
5452  if(!getJointConfiguration(joint, &jntCfg))
5453  {
5454  yError ("Failure embObjMotionControl::getGerabox_E2J(axis=%d) for BOARD %s IP %s", joint, res->getProperties().boardnameString.c_str(), res->getProperties().ipv4addrString.c_str());
5455  return false;
5456  }
5457  *gearbox_E2J_ptr = jntCfg.gearbox_E2J;
5458  return true;
5459 }
5460 
5461 bool embObjMotionControl::getJointEncTolerance(int joint, double *jEncTolerance_ptr)
5462 {
5463  eOmc_joint_config_t jntCfg;
5464 
5465  if(!getJointConfiguration(joint, &jntCfg))
5466  {
5467  yError ("Failure embObjMotionControl::getJointEncTolerance(axis=%d) for BOARD %s IP %s", joint, res->getProperties().boardnameString.c_str(), res->getProperties().ipv4addrString.c_str());
5468  return false;
5469  }
5470  *jEncTolerance_ptr = jntCfg.jntEncTolerance;
5471  return true;
5472 }
5473 
5474 bool embObjMotionControl::getMotorEncTolerance(int axis, double *mEncTolerance_ptr)
5475 {
5476  eOmc_motor_config_t motorCfg;
5477  if(!getMotorConfiguration(axis, &motorCfg))
5478  {
5479  yError ("Failure embObjMotionControl::getMotorEncTolerance(axis=%d) for BOARD %s IP %s", axis, res->getProperties().boardnameString.c_str(), res->getProperties().ipv4addrString.c_str());
5480  return false;
5481  }
5482  *mEncTolerance_ptr = motorCfg.rotEncTolerance;
5483  return true;
5484 }
5485 
5486 bool embObjMotionControl::getLastJointFaultRaw(int j, int& fault, std::string& message)
5487 {
5488  eOmc_motor_status_t status;
5489 
5490  eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol,
5491  eoprot_entity_mc_motor, j,
5492  eoprot_tag_mc_motor_status);
5493 
5494  bool ret = res->getLocalValue(protid, &status);
5495 
5496  message.clear();
5497 
5498  if (!ret)
5499  {
5500  fault = -1;
5501  message = "Could not retrieve the fault state.";
5502  return false;
5503  }
5504 
5505  if (status.mc_fault_state == EOERROR_CODE_DUMMY)
5506  {
5507  fault = EOERROR_CODE_DUMMY;
5508  message = "No fault detected.";
5509 
5510  return true;
5511  }
5512 
5513  fault = eoerror_code2value(status.mc_fault_state);
5514  message = eoerror_code2string(status.mc_fault_state);
5515 
5516  return true;
5517 }
5518 
5519 // eof
#define MAX_POSITION_MOVE_INTERVAL
bool parseService(yarp::os::Searchable &config, servConfigMais_t &maisconfig)
servMC_encoder_t * getEncoderAtMotor(int index)
servMC_encoder_t * getEncoderAtJoint(int index)
virtual const Properties & getProperties()=0
virtual bool setcheckRemoteValue(const eOprotID32_t id32, void *value, const unsigned int retries=10, const double waitbeforecheck=0.001, const double timeout=0.050)=0
virtual bool serviceVerifyActivate(eOmn_serv_category_t category, const eOmn_serv_parameter_t *param, double timeout=0.500)=0
virtual bool setRemoteValue(const eOprotID32_t id32, void *value)=0
virtual bool verifyEPprotocol(eOprot_endpoint_t ep)=0
virtual bool getLocalValue(const eOprotID32_t id32, void *value)=0
virtual bool serviceSetRegulars(eOmn_serv_category_t category, vector< eOprotID32_t > &id32vector, double timeout=0.500)=0
virtual bool serviceStart(eOmn_serv_category_t category, double timeout=0.500)=0
virtual bool getRemoteValue(const eOprotID32_t id32, void *value, const double timeout=0.100, const unsigned int retries=0)=0
virtual bool getRemoteValues(const std::vector< eOprotID32_t > &id32s, const std::vector< void * > &values, const double timeout=0.500)=0
int releaseResource2(eth::AbstractEthResource *ethresource, IethResource *interface)
Definition: ethManager.cpp:409
bool verifyEthBoardInfo(yarp::os::Searchable &cfgtotal, eOipv4addr_t &boardipv4, string boardipv4string, string boardname)
Definition: ethManager.cpp:283
static bool killYourself()
Definition: ethManager.cpp:178
static TheEthManager * instance()
Definition: ethManager.cpp:159
eth::AbstractEthResource * requestResource2(IethResource *interface, yarp::os::Searchable &cfgtotal)
Definition: ethManager.cpp:336
bool start()
Instantiates the yarp::os::Timer object and starts it.
bool canprint()
Called by the object that implements the downsampler.
virtual bool getPidReferenceRaw(const PidControlTypeEnum &pidtype, int j, double *ref) override
virtual bool setVelLimitsRaw(int axis, double min, double max) override
virtual bool setMaxCurrentRaw(int j, double val) override
virtual bool getMotorEncoderRaw(int m, double *v) override
virtual bool enablePidRaw(const PidControlTypeEnum &pidtype, int j) override
virtual bool setPidErrorLimitsRaw(const PidControlTypeEnum &pidtype, const double *limits) override
virtual bool setRefSpeedsRaw(const double *spds) override
virtual bool getTorqueRangesRaw(double *min, double *max) override
virtual bool getControlModesRaw(int *v) override
virtual bool getRefCurrentRaw(int j, double *t) override
virtual bool setInteractionModeRaw(int j, yarp::dev::InteractionModeEnum _mode) override
virtual bool getPidOutputRaw(const PidControlTypeEnum &pidtype, int j, double *out) override
virtual bool getInteractionModesRaw(int n_joints, int *joints, yarp::dev::InteractionModeEnum *modes) override
virtual bool setInteractionModesRaw(int n_joints, int *joints, yarp::dev::InteractionModeEnum *modes) override
bool getRotorEncoderTypeRaw(int j, int &type)
virtual bool setRefAccelerationsRaw(const double *accs) override
virtual bool disablePidRaw(const PidControlTypeEnum &pidtype, int j) override
virtual bool getImpedanceRaw(int j, double *stiffness, double *damping) override
virtual bool update(eOprotID32_t id32, double timestamp, void *rxdata)
virtual bool setPidOffsetRaw(const PidControlTypeEnum &pidtype, int j, double v) override
virtual bool getPowerSupplyVoltageRaw(int j, double *val) override
virtual bool setPidsRaw(const PidControlTypeEnum &pidtype, const Pid *pids) override
virtual bool getPidErrorLimitRaw(const PidControlTypeEnum &pidtype, int j, double *limit) override
virtual bool setPeakCurrentRaw(int m, const double val) override
virtual bool enableAmpRaw(int j) override
bool getHasRotorEncoderRaw(int j, int &ret)
virtual bool setRefTorqueRaw(int j, double t) override
virtual bool relativeMoveRaw(int j, double delta) override
virtual bool disableAmpRaw(int j) override
virtual bool getRefVelocityRaw(const int joint, double *ref) override
virtual bool getEncodersRaw(double *encs) override
virtual bool getLastJointFaultRaw(int j, int &fault, std::string &message) override
virtual bool getDutyCyclesRaw(double *v) override
virtual bool getPidReferencesRaw(const PidControlTypeEnum &pidtype, double *refs) override
virtual bool getMotorEncoderAccelerationsRaw(double *accs) override
virtual bool resetMotorEncoderRaw(int m) override
virtual bool checkMotionDoneRaw(bool *flag) override
virtual bool getPWMLimitRaw(int j, double *val) override
virtual bool getControlModeRaw(int j, int *v) override
virtual bool getPWMRaw(int j, double *val) override
bool getRotorLimitsRaw(int j, double *rotorMin, double *rotorMax)
virtual bool getTorqueRaw(int j, double *t) override
virtual bool getMotorEncodersRaw(double *encs) override
virtual bool open(yarp::os::Searchable &par)
virtual bool getEncodersTimedRaw(double *encs, double *stamps) override
bool getHasHallSensorRaw(int j, int &ret)
bool getJointEncoderResolutionRaw(int m, double &jntres)
virtual bool getRefSpeedsRaw(double *spds) override
virtual bool getInteractionModeRaw(int j, yarp::dev::InteractionModeEnum *_mode) override
virtual bool getEntityName(uint32_t entityId, std::string &entityName)
virtual eth::iethresType_t type()
bool getTemperatureSensorTypeRaw(int j, std::string &ret)
virtual bool getCurrentRangesRaw(double *min, double *max) override
virtual bool getLimitsRaw(int axis, double *min, double *max) override
virtual bool setPidReferenceRaw(const PidControlTypeEnum &pidtype, int j, double ref) override
virtual bool updateVirtualAnalogSensorMeasure(yarp::sig::Vector &fTorques) override
virtual bool setImpedanceRaw(int j, double stiffness, double damping) override
virtual bool setRemoteVariableRaw(std::string key, const yarp::os::Bottle &val) override
virtual bool getCurrentsRaw(double *vals) override
virtual bool getTorqueRangeRaw(int j, double *min, double *max) override
virtual bool getTorquesRaw(double *t) override
virtual bool getAmpStatusRaw(int *st) override
virtual yarp::dev::VAS_status getVirtualAnalogSensorStatus(int ch) override
bool getHasTempSensorsRaw(int j, int &ret)
virtual bool setRefCurrentsRaw(const double *t) override
virtual bool getTargetPositionRaw(const int joint, double *ref) override
virtual bool setMotorEncoderCountsPerRevolutionRaw(int m, const double cpr) override
virtual bool getGearboxRatioRaw(int m, double *gearbox) override
virtual bool resetEncodersRaw() override
virtual bool getTemperatureLimitRaw(int m, double *temp) override
virtual bool setCalibrationParametersRaw(int axis, const CalibrationParameters &params) override
virtual bool setNominalCurrentRaw(int m, const double val) override
virtual bool setMotorTorqueParamsRaw(int j, const MotorTorqueParameters params) override
virtual bool setRefCurrentRaw(int j, double t) override
virtual bool setTemperatureLimitRaw(int m, const double temp) override
virtual bool getRemoteVariableRaw(std::string key, yarp::os::Bottle &val) override
virtual bool calibrationDoneRaw(int j) override
virtual bool getEncoderTimedRaw(int j, double *encs, double *stamp) override
virtual bool getAxisNameRaw(int axis, std::string &name) override
virtual bool setPWMLimitRaw(int j, const double val) override
virtual bool getRefAccelerationRaw(int j, double *acc) override
virtual bool resetPidRaw(const PidControlTypeEnum &pidtype, int j) override
virtual bool getPidRaw(const PidControlTypeEnum &pidtype, int j, Pid *pid) override
virtual bool setPositionRaw(int j, double ref) override
virtual bool getRefSpeedRaw(int j, double *ref) override
virtual bool setPidErrorLimitRaw(const PidControlTypeEnum &pidtype, int j, double limit) override
virtual bool setControlModesRaw(const int n_joint, const int *joints, int *modes) override
bool getRotorEncoderResolutionRaw(int m, double &rotres)
virtual bool setRefDutyCycleRaw(int j, double v) override
virtual bool getImpedanceOffsetRaw(int j, double *offset) override
bool getWholeImpedanceRaw(int j, eOmc_impedance_t &imped)
virtual bool getEncoderSpeedsRaw(double *spds) override
virtual bool setPositionsRaw(const int n_joint, const int *joints, const double *refs) override
virtual bool resetMotorEncodersRaw() override
bool getJointEncoderTypeRaw(int j, int &type)
virtual bool getNumberOfMotorEncodersRaw(int *num) override
virtual bool getPidErrorLimitsRaw(const PidControlTypeEnum &pidtype, double *limits) override
virtual bool setMotorEncoderRaw(int m, const double val) override
virtual bool getMotorEncoderTimedRaw(int m, double *encs, double *stamp) override
virtual bool setEncoderRaw(int j, double val) override
virtual bool resetEncoderRaw(int j) override
virtual bool setPidRaw(const PidControlTypeEnum &pidtype, int j, const Pid &pid) override
virtual bool getRefAccelerationsRaw(double *accs) override
virtual bool getPidOutputsRaw(const PidControlTypeEnum &pidtype, double *outs) override
virtual bool getRefPositionsRaw(double *refs) override
virtual bool getJointTypeRaw(int axis, yarp::dev::JointTypeEnum &type) override
virtual bool calibrateAxisWithParamsRaw(int axis, unsigned int type, double p1, double p2, double p3) override
virtual bool getNominalCurrentRaw(int m, double *val) override
virtual bool setRefTorquesRaw(const double *t) override
virtual bool getRefDutyCyclesRaw(double *v) override
virtual bool getCurrentRaw(int j, double *val) override
bool getMotorPolesRaw(int j, int &poles)
virtual bool getCurrentRangeRaw(int j, double *min, double *max) override
virtual bool getRefTorquesRaw(double *t) override
virtual bool setEncodersRaw(const double *vals) override
virtual bool getEncoderRaw(int j, double *v) override
virtual bool setControlModeRaw(const int j, const int mode) override
virtual bool positionMoveRaw(int j, double ref) override
bool getKinematicMJRaw(int j, double &rotres)
virtual bool setLimitsRaw(int axis, double min, double max) override
virtual bool getEncoderAccelerationRaw(int j, double *spds) override
virtual bool getMotorTorqueParamsRaw(int j, MotorTorqueParameters *params) override
virtual bool getTemperatureRaw(int m, double *val) override
virtual bool setPidReferencesRaw(const PidControlTypeEnum &pidtype, const double *refs) override
virtual bool getCurrentImpedanceLimitRaw(int j, double *min_stiff, double *max_stiff, double *min_damp, double *max_damp) override
virtual bool getVelLimitsRaw(int axis, double *min, double *max) override
virtual bool getRefTorqueRaw(int j, double *t) override
virtual bool getNumberOfMotorsRaw(int *num) override
virtual bool setRefSpeedRaw(int j, double sp) override
virtual bool getMotorEncoderSpeedsRaw(double *spds) override
virtual bool getMaxCurrentRaw(int j, double *val) override
virtual bool getTemperaturesRaw(double *vals) override
virtual bool getMotorEncoderCountsPerRevolutionRaw(int m, double *v) override
virtual bool getEncoderAccelerationsRaw(double *accs) override
virtual bool getPidsRaw(const PidControlTypeEnum &pidtype, Pid *pids) override
virtual bool getRemoteVariablesListRaw(yarp::os::Bottle *listOfKeys) override
bool getTorqueControlFilterType(int j, int &type)
virtual bool getRefCurrentsRaw(double *t) override
virtual bool getPidErrorRaw(const PidControlTypeEnum &pidtype, int j, double *err) override
virtual bool setImpedanceOffsetRaw(int j, double offset) override
virtual bool getRefDutyCycleRaw(int j, double *v) override
virtual bool getMotorEncodersTimedRaw(double *encs, double *stamps) override
virtual int getVirtualAnalogSensorChannels() override
bool getRotorIndexOffsetRaw(int j, double &rotorOffset)
virtual bool setMotorEncodersRaw(const double *vals) override
virtual bool isPidEnabledRaw(const PidControlTypeEnum &pidtype, int j, bool *enabled) override
virtual bool setRefAccelerationRaw(int j, double acc) override
virtual bool getEncoderSpeedRaw(int j, double *sp) override
virtual bool getMotorEncoderSpeedRaw(int m, double *sp) override
virtual bool getMotorEncoderAccelerationRaw(int m, double *spds) override
virtual bool getAxes(int *ax) override
virtual bool getRefPositionRaw(const int joint, double *ref) override
virtual bool setRefDutyCyclesRaw(const double *v) override
virtual bool velocityMoveRaw(int j, double sp) override
virtual bool getPeakCurrentRaw(int m, double *val) override
virtual bool getPidErrorsRaw(const PidControlTypeEnum &pidtype, double *errs) override
virtual bool getRefVelocitiesRaw(double *refs) override
virtual bool getTargetPositionsRaw(double *refs) override
bool getHasRotorEncoderIndexRaw(int j, int &ret)
virtual bool getDutyCycleRaw(int j, double *v) override
bool parseJointsetCfgGroup(yarp::os::Searchable &config, std::vector< JointsSet > &jsets, std::vector< int > &jointtoset)
bool parseJointsLimits(yarp::os::Searchable &config, std::vector< jointLimits_t > &jointsLimits)
bool parseAmpsToSensor(yarp::os::Searchable &config, double ampsToSensor[])
bool parseMechanicalsFlags(yarp::os::Searchable &config, int useMotorSpeedFbk[])
bool parseMotioncontrolVersion(yarp::os::Searchable &config, int &version)
bool parseAxisInfo(yarp::os::Searchable &config, int axisMap[], std::vector< axisInfo_t > &axisInfo)
bool parseFocGroup(yarp::os::Searchable &config, focBasedSpecificInfo_t *foc_based_info, std::string groupName, std::vector< std::unique_ptr< eomc::ITemperatureSensor >> &temperatureSensorsVector)
bool parseCouplingInfo(yarp::os::Searchable &config, couplingInfo_t &couplingInfo)
bool parsePids(yarp::os::Searchable &config, PidInfo *ppids, TrqPidInfo *tpids, PidInfo *cpids, PidInfo *spids, bool lowLevPidisMandatory)
Definition: eomcParser.cpp:79
bool parseTemperatureLimits(yarp::os::Searchable &config, std::vector< temperatureLimits_t > &temperatureLimits)
bool parseDeadzoneValue(yarp::os::Searchable &config, double deadzone[], bool *found)
bool isVerboseEnabled(yarp::os::Searchable &config)
bool parseTimeoutsGroup(yarp::os::Searchable &config, std::vector< timeouts_t > &timeouts, int defaultVelocityTimeout)
bool parseCurrentLimits(yarp::os::Searchable &config, std::vector< motorCurrentLimits_t > &currLimits)
bool parseEncoderFactor(yarp::os::Searchable &config, double encoderFactor[])
bool parsefullscalePWM(yarp::os::Searchable &config, double dutycycleToPWM[])
bool parseRotorsLimits(yarp::os::Searchable &config, std::vector< rotorLimits_t > &rotorsLimits)
bool parseImpedanceGroup(yarp::os::Searchable &config, std::vector< impedanceParameters_t > &impedance)
bool parseKalmanFilterParams(yarp::os::Searchable &config, std::vector< kalmanFilterParams_t > &kalmanFilterParams)
bool parseGearboxValues(yarp::os::Searchable &config, double gearbox_M2J[], double gearbox_E2J[])
bool parseBehaviourFalgs(yarp::os::Searchable &config, bool &useRawEncoderData, bool &pwmIsLimited)
std::string usernamePidSelected
Definition: eomcParser.h:374
yarp::dev::PidFeedbackUnitsEnum fbk_PidUnits
Definition: eomcParser.h:368
eOmc_ctrl_out_type_t out_type
Definition: eomcParser.h:370
yarp::dev::PidOutputUnitsEnum out_PidUnits
Definition: eomcParser.h:369
_3f_vect_t acc
Definition: dataTypes.h:1
int n
static uint32_t idx[BOARD_NUM]
static constexpr double const temperatureErrorValue_s
static bool nv_not_found(void)
static bool NOT_YET_IMPLEMENTED(const char *txt)
#define PARSER_MOTION_CONTROL_VERSION
static bool DEPRECATED(const char *txt)
int jnts
Definition: main.cpp:60
iethresType_t
Definition: IethResource.h:62
@ iethres_motioncontrol
Definition: IethResource.h:67
const FSC max
Definition: strain.h:48
const FSC min
Definition: strain.h:49
int S_32(double x)
Definition: eomcUtils.h:70
bool EncoderType_eo2iCub(const uint8_t *in, string *out)
Definition: eomcUtils.h:125
int controlModeStatusConvert_embObj2yarp(eOenum08_t embObjMode)
Definition: eomcUtils.h:258
bool interactionModeStatusConvert_embObj2yarp(eOenum08_t embObjMode, int &vocabOut)
Definition: eomcUtils.h:384
bool controlModeCommandConvert_yarp2embObj(int vocabMode, eOenum08_t &embOut)
Definition: eomcUtils.h:201
void copyPid_eo2iCub(eOmc_PID_t *in, Pid *out)
Definition: eomcUtils.h:186
short S_16(double x)
Definition: eomcUtils.h:43
@ motor_temperature_sensor_pt100
Definition: eomcParser.h:62
@ motor_temperature_sensor_pt1000
Definition: eomcParser.h:63
@ motor_temperature_sensor_none
Definition: eomcParser.h:64
void copyPid_iCub2eo(const Pid *in, eOmc_PID_t *out)
Definition: eomcUtils.h:171
bool interactionModeCommandConvert_yarp2embObj(int vocabMode, eOenum08_t &embOut)
Definition: eomcUtils.h:362
int U_16(double x)
Definition: eomcUtils.h:31
int U_32(double x)
Definition: eomcUtils.h:58
out
Definition: sine.m:8
degrees offset
Definition: sine.m:4
std::vector< BufferedPort< Bottle > * > ports
eOmn_serv_diagn_cfg_t config
eOmn_serv_parameter_t ethservice
Definition: serviceParser.h:90
eOmc_encoder_descriptor_t desc
bool useRawEncoderData
its value depends on environment variable "ETH_VERBOSEWHENOK"
bool pwmIsLimited
if true than do not use calibration data
std::vector< double > matrixM2J
Definition: eomcParser.h:483
std::vector< double > matrixE2J
Definition: eomcParser.h:484
std::vector< double > matrixJ2M
Definition: eomcParser.h:482