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