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